【问题标题】:PHP execute external script without waiting, while passing variablesPHP执行外部脚本无需等待,同时传递变量
【发布时间】:2011-07-16 22:03:51
【问题描述】:

我正在为我的用户制作一个功能,他们可以上传大型 XML 文件以与我的数据库同步。

当用户将文件上传到upload.php时,我想用process.php开始在后台处理数据,最好是从shell命令,并将用户重定向到status.php,这显示了同步。

我需要在执行 process.php 脚本时将一些变量传递给它,至少一个带有用户 ID 的变量并将其他变量放入一个文本文件中,(可能更喜欢这个,所以我不必放入exec() 命令中有很多数据。)或用户 ID 和一堆 $_POST 变量。

我想到的一个解决方案是这样执行 PHP 脚本:

exec("php -f ./process.php > /dev/null 2>/dev/null &"); 

这允许我锁定 process.php 与 http 访问,这很好,因为它是一个进程获取脚本。我在这里唯一需要做的就是以某种方式传递一个变量,但我不知道该怎么做。

所以我的主要问题是:

如何在上述解决方案中传递变量?

或者你们有更好的解决方案吗?可能是我不必通过exec() 的地方?请记住,我不希望用户等待脚本执行,我需要传递至少一个变量。

更新:为了将来参考,请记住在通过exec() 或类似函数传递参数时使用escapeshellarg()

【问题讨论】:

    标签: php shell


    【解决方案1】:

    你测试使用它

    exec("php -f ./process.php var1 var2 > /dev/null 2>/dev/null &"); 
    

    如果你喜欢获取这些变量值,可以访问全局变量 $argv。如果你打印这个 var 显示相同:

    print_r($argv);
    
    
    Array
    (
        [0] => process.php
        [1] => var1
        [2] => var2
    )
    

    【讨论】:

      【解决方案2】:

      您可以传递如下参数。

      // call process.php
      exec("php -f ./process.php foo=bar bar=foo > /dev/null 2>/dev/null &"); 
      
      // process.php
      if ($argc > 0) {
          for ($i=1;$i < $argc;$i++) {
              parse_str($argv[$i],$tmp);
              $_REQUEST = array_merge($_REQUEST, $tmp);
          }
      }
      
      var_dump($_REQUEST);
      

      【讨论】:

        【解决方案3】:

        我不太了解您的目标,但是将参数传递给 PHP 脚本的工作方式与任何其他 shell 脚本类似。请参阅:http://www.php.net/manual/en/features.commandline.usage.php(示例 #2)

        “当用户上传文件 [...] 时,我想开始在后台处理数据” - You can't access an upload before it is finished,在 PHP 中使用 CGI。

        【讨论】:

        • 文件会在 process.php 执行前保存,不用担心。并感谢您的链接。
        【解决方案4】:

        这是我的解决方案。

        优点是您可以将此脚本用于命令行以及常规 Web 使用。如果您从 cmd 调用它,则会设置 $argv 变量,因此 parse_str() 部分会提取变量并将它们放入 $_GET 数组中。如果您从网络调用它,$argv 未设置,因此值来自 url。

        // executingScript.php
        // You have to make percent escaping yourself
        exec("php -f ./executedScript.php foo=bar%20foo bar=foo%20bar > /dev/null 2>/dev/null &");
        
        // executedScript.php
        // The if-statement avoids crashing when calling the script from the web
        if (isset($argv)) {
            parse_str(implode('&', array_slice($argv, 1)), $_GET);
        }
        

        这将使您能够像往常一样访问变量:

        echo $_GET["foo"] // outputs "bar foo"
        echo $_GET["bar"] // outputs "foo bar"
        

        【讨论】:

          猜你喜欢
          • 2011-07-22
          • 1970-01-01
          • 2016-05-23
          • 1970-01-01
          • 2016-09-13
          • 1970-01-01
          • 1970-01-01
          • 2023-03-11
          • 1970-01-01
          相关资源
          最近更新 更多