从PHP脚本运行PHP脚本的最佳做法是什么?

我会使用下面的代码:

$SERVER_PATH = dirname(__FILE__); shell_exec($PHP_LOCATION.' '.$SERVER_PATH."/script.php?k1=v1&k2=v2 > /dev/null 2>/dev/null &"); 

哪里:

这个代码有两个问题:

  1. 据我所知, ?k1=v1&k2=v2只能用于networking通话,所以在这种情况下参数不会传递给脚本。

  2. 我真的不知道如何初始化$PHP_LOCATIONvariables,使其变得灵活,并且能够在大多数主机上工作。

我对这两个问题进行了一些研究:

解决方法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); } 

一些观点:

  • 是的,它只适用于Linux
  • 如果允许将用户输入传递给shell命令,则应该小心: escapeshellarg()和company
  • 事实上,通常PHP不应该用于这样的东西,就好像它是关于异步请求的,更好的是实现派生或从外部工作人员运行命令。

如何传递参数

通过文件系统路径执行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命令。 这将允许模仿一个流程的“分离”,从而使其运行可靠,独立于父流程的情况。