我会使用下面的代码:
$SERVER_PATH = dirname(__FILE__); shell_exec($PHP_LOCATION.' '.$SERVER_PATH."/script.php?k1=v1&k2=v2 > /dev/null 2>/dev/null &");
哪里:
$PHP_LOCATION
应该包含PHP的path,
$SERVER_PATH
– 是当前工作目录(幸运的是脚本运行在同一目录中),
> /dev/null 2>/dev/null &
添加使这个调用asynchronous(取自PHPasynchronousshell exec )
这个代码有两个问题:
据我所知, ?k1=v1&k2=v2
只能用于networking通话,所以在这种情况下参数不会传递给脚本。
我真的不知道如何初始化$PHP_LOCATION
variables,使其变得灵活,并且能够在大多数主机上工作。
我对这两个问题进行了一些研究:
解决方法1 build议使用-- 'parameters_string'
但也build议修改脚本来parsing参数string,看起来有点笨拙。 有更好的解决scheme吗?
要解决2我find了一个解决scheme ,使用PHP_BINARY
但这是一个PHP 5.4 +的情况下(我使用5.3)。 但原来的问题是要运行与原始脚本版本相同版本的PHP。 所以对我来说(因为我只使用PHP 5.3)可能有解决scheme吗?
编辑0
让我做一些解释为什么我坚持这个奇怪的(对于PHP)方法:
这些PHP脚本应该彼此分开:
其中一个将分析数据和
第二个将生成PNG图作为最终结果。
这些脚本并不是同时运行的,这意味着第二个脚本可以按照自己的时间表运行,只需要运行它的数据就可以了(由第一个脚本完成)。 所以没有数据应该从第二个脚本(子)传回到第一个(父)。
编辑1
从大多数评论看,主要的讨论都是为了方向。 不过,我想在原来的问题上强调第一点和第二点。 我有理由以我指出的方式来解决这个任务,我试图指出所有的理由。 如果我的一些观点看起来很奇怪,请发表评论 – 我会更加清楚,否则我会改变主要问题。
先谢谢你!
假设你正在使用Linux,你可以使用:
function getBinaryRunner($binary) { return trim(shell_exec('which '.$binary)); }
例如,同样可以用来检查是否需要安装东西:
function checkIfCommandExists($command) { $result = shell_exec('which '.$command); return !empty($result); }
一些观点:
escapeshellarg()
和company 通过文件系统路径执行shell_exec()
,你正在访问文件,显然,所有的“GET”参数都只是文件名的一部分,不再是“URI”,因为没有Web服务器来处理它。 所以你有两个选择:
通过访问您的Web服务器来调用调用。 所以会是这样的:
//Yes, you will use wget or, better, curl to make web-request from CLI shell_exec('wget http://your.web-server.domain/script.php?foo=bar');
缺点:如果您通过公共DNS访问您的网络服务器,将导致网络差距和所有处理开销。 好处 – 显然,您不需要在脚本中指望其他任何东西,也不需要区分CLI和非CLI调用
在你的脚本中使用$_SERVER
数组,并像使用CLI一样传递参数:
shell_exec('/usr/bin/php /path/to/script.php foo bar'); //inside your script.php you will see: //$_SERVER['argv'][0] is "script.php" //$_SERVER['argv'][1] is "foo" //$_SERVER['argv'][2] is "bar"
是的,这将需要在脚本中进行修改,并且可能需要一些关于如何映射“常规”web请求和CLI的逻辑。 我会建议甚至想到将与CLI相关的东西分离到不同的脚本包中,以免混淆该逻辑。
当你做php script.php &
你只是在后台模式下运行它。 然而,这仍然保持你的过程的亲子关系。 这意味着 – 如果父母过程死亡,孩子也将被删除。 确切地说, SIGHUP
将被触发,为了避免这种情况,你应该使用nohup
命令。 这将允许模仿一个流程的“分离”,从而使其运行可靠,独立于父流程的情况。