PHP命令行脚本是否可以自我更新并使用新代码重新启动?

PHP命令行脚本是否可以自我更新并使用新代码重新启动?,php,include,Php,Include,很多月前,当我开始编程的时候,我在互联网还没有图片之前,为所有年轻人编写了一个基于MUD多用户地下城文本的“MMO”!。它是用C写的,我学到了很多,我在编写代码时学到的最酷的事情之一是,mud将代码的各个区域编译为链接库,我相信这就是所谓的链接库?自从我用C语言编写代码以来已经有很长时间了,我能够动态地更新/更改游戏的代码,而不必关闭/重新启动它。取消旧库的链接,将新库移动到位,重新链接,然后重新启用该功能 现在:我运行了一个PHP命令行脚本,它可以处理一些服务器任务。在演讲之前,是的,我知道这

很多月前,当我开始编程的时候,我在互联网还没有图片之前,为所有年轻人编写了一个基于MUD多用户地下城文本的“MMO”!。它是用C写的,我学到了很多,我在编写代码时学到的最酷的事情之一是,mud将代码的各个区域编译为链接库,我相信这就是所谓的链接库?自从我用C语言编写代码以来已经有很长时间了,我能够动态地更新/更改游戏的代码,而不必关闭/重新启动它。取消旧库的链接,将新库移动到位,重新链接,然后重新启用该功能

现在:我运行了一个PHP命令行脚本,它可以处理一些服务器任务。在演讲之前,是的,我知道这不是最好/最有效的语言。但由于某些因素,这是它现在使用的语言

我正在运行的脚本实际上运行在4个不同的服务器上,当它启动时,有一个调用脚本运行wget从主服务器获取更新的“核心”代码,包括它,然后运行它。代码如下:

#!/usr/bin/php -q
<?php
  echo "Grabbing latest code...\n";
  `wget -N http://blahblahblah.php`;
  `wget -N http://blahblahothercode.php`;

  include('blahblahblah.php');
?>
所以我的问题是,在它运行时,是否有可能让它更新自己的代码并重新加载自己?我目前的解决方案是在使用shell“at”命令重新启动自身后退出。笨重,但它可以实现目标

问题是,当脚本启动时,它从stdin获取一个加密密钥,该密钥必须在脚本启动时键入。我不希望将该密钥保存到磁盘上的任何位置,我不希望将该密钥保存到临时文件中,或在“at”的任何命令历史记录中重新读取。理想情况下,我希望将密钥保留在内存中,只需“替换”正在运行的代码。如果这在PHP中是可能的话

<>当我们最终在C++中重做这一点时,我们可以选择库,但现在,有没有办法在PHP?< /P>中实现这一点?
在我点击提交之前我有一个想法。。。当PHP点击include命令时,它是在运行时执行一次include,还是在每次看到它时都运行include?如果我循环一个include…,这可能是一个选项?

有一种方法,但可能不会很好。主要问题是PHP中的函数、类等大多数东西都是命名的,一旦定义,就无法重新定义

你可以通过只使用匿名函数和对象来解决这个问题;这样,您可以简单地再次包含一个模块,它将简单地用新的匿名函数覆盖旧的匿名函数。你会得到一些看起来很像LUA或JavaScript代码的东西

但您的代码可能不是为此而构建的,因此您将几乎失去您必须完成的工作

对于现有项目来说,更好的解决方案可能是将程序分为两部分,首先运行一个更新程序,该程序将获取最新代码,然后启动实际程序,并在启动时传递密钥?除非您想在程序已经运行时更新程序,否则无论如何。

您始终可以使用

eval('?>' . file_get_contents('updated.php') . '<?php ');
不过,我会避免这种丑陋的做法


干杯。

根据评论复制/粘贴:


只有一种方法,叫做过程监控。您可以使用fork,让父进程包含有关encr的信息。输入一个变量。现在有趣的部分是——孩子就是运行的代码。现在您要做的是——您需要检测文件事件循环中的更改,使用轮询进行统计——无论您使用什么。一旦您检测到子进程中发生的更改,它就会自动终止退出、死亡等等。现在我们回到父级-父级收到其子级退出的信号。你再把它踢回去是的,再叉子。永远重复。但是,您的密钥在内存中,因此可以进行查找


更新:我已经使用这种方法有一段时间了,但是我也使用LibEV和PHP扩展来处理它,以便对stat-events文件更改做出反应。您可以在此处查看扩展名:

自变异代码…这就是机器将如何接管世界。首次遇到include时,include执行一次,因此循环include语句实际上只执行include文件一次,此后,它将执行每次迭代中包含的代码。只有一种方法,称为过程监控。您可以使用fork,让父进程包含有关encr的信息。输入一个变量。现在有趣的部分是——孩子就是运行的代码。现在您要做的是——您需要检测文件事件循环中的更改,使用轮询进行统计——无论您使用什么。一旦您检测到子进程中发生的更改,它就会自动终止退出、死亡等等。现在我们回到父级-父级收到其子级退出的信号。你再把它踢回去是的,再叉子。永远重复。然而,你的钥匙在内存中,可以查到。这是一个有趣的想法。如果可以重新定义,我正在考虑使用名称空间或将所有内容包装在一个类中
我喜欢那些。用叉子叉孩子可能更容易。我想这样做的原因是,如果我做了一个小的更改,我需要远程进入4台不同的机器,终止进程,重新启动它,然后键入密钥。皮塔。至于记忆中的钥匙,这是不可避免的。我担心的是服务器的物理盗窃或驱动器内容的数据盗窃。不拔掉插头就不能偷,如果钥匙不在磁盘上就拿不到。注:这是一个完美的解决方案。只是做了个小测试。设置一个变量,然后围绕一个fork循环。子代码是包含,然后是退出。在fork代码之后,我有一个“按enter键继续”行。运行了它,它运行了include。在它等待输入时,我更改了包含的文件。按回车键。它运行新的/更改的代码。完美的你能在这里标记一条评论作为答案吗?我在stackoverflow是个笨蛋!谢谢是 啊我想评估一下,但即使是我也认为那是个坏主意;我今天开车时考虑的是让主程序加载include,获取密钥,然后循环include,直到需要“重新启动”,然后重新加载include,这样它们的密钥和任何其他相关变量都会保留在内存中,但无法重新定义可能存在问题的函数。不过,看看名称空间,所有“全局”变量都需要在名称空间之外。传递给多个函数的全局变量