繁体   English   中英

PHP-在循环中运行脚本

[英]PHP - running script within a loop

我试图从一个脚本中运行一个脚本,并有以下似乎无法正常工作。 我基本上是从数据库中获取大量数据,遍历每一行并运行一个脚本,该脚本将基于该数据生成XML。

set_time_limit(0);

//connect to database
$msSqlDB = new mySqlConnect('store');

$select = "SELECT * FROM FStores"; 

$run = mysql_query($select);
while($row = mysql_fetch_array($run)){
    exec('/var/www/web/shop_xml/index.php?shopKeeper=$row[SKID]&shop=1');
}

最好的方法是什么? 第二行会等到第一行成功执行后还是可以同时运行多个? 非常感谢您的任何建议。

您需要执行以下操作:

exec('php /var/www/web/shop_xml/index.php "'.escapeshellarg($row['SKID']).'" "1" > /dev/null 2>&1 &');

然后,在您的index.php脚本中:

<?php

  $shopKeeper = $argv[1];
  $shop = $argv[2];

  // ... do stuff

您试图做的是在文件系统调用中使用HTTP查询字符串,该字符串不起作用。 您需要像在终端中一样将数据作为命令行参数传递。 然后,您可以从$argv获取数据。

您需要使用php启动命令,否则内核(很可能,除非您添加hashbang并设置权限)不知道如何执行脚本或具有执行该脚本的权限。

如果添加> /dev/null 2>&1 &这些命令将异步运行,即,您不必等待最后一个命令完成就可以调用另一个命令。 但是请小心,如果查询返回许多行,可能会导致许多过程。

为了避免这种情况,您可以执行以下操作:

<?php

  // Number of records to process at a time
  $perBatch = 5;

  set_time_limit(0);

  //connect to database
  $msSqlDB = new mySqlConnect('Freewebstore');

  // Get the number of records in the table
  $query = "SELECT count(*) FROM FacebookStores";
  $result = mysql_fetch_row(mysql_query($select));
  $count = $result[0];

  for ($i = 0; $i < $count; $i += $perBatch) {

    // Get $perBatch records from the DB
    $query = "SELECT * FROM FacebookStores LIMIT $i,$perBatch";
    $result = mysql_query($select);

    for ($j = 1; $row = mysql_fetch_array($result); $j++) {

      // Base command
      $command = 'php /var/www/web/shop_xml/index.php "'.escapeshellarg($row['SKID']).'" "1"';

      // Run all except the last asynchronously
      if ($j < $perBatch) {
        $command .= ' > /dev/null 2>&1 &';
      }

      exec($command);

    }

  }

这将$perBatch从数据库获取$perBatch记录,并异步处理除最后一个记录外的所有记录。 这将导致它们一次大约处理$perBatch记录,并有助于避免大量进程$perBatch服务器资源。

附带说明一下,您似乎混合使用了OO DB代码和过程DB代码的奇怪组合-您应该坚持一个或另一个以避免混淆。

George P的回答从字面上回答了您的问题; 如何从命令行按原样运行脚本。 接下来让我提供一些替代方案。

首先,您的shop_xml / index.php脚本可以检查是否从命令行调用它,并相应地读取参数。 从而:

if( php_sapi_name() == 'cli' ) {
   // you would, of course, want to escape these for malicious code!
   $shopKeeper = $argv[1];
   $shop = $argv[2];
}
else {
   $shopKeeper = $_GET['shopKeeper'];
   $shop = $_GET['shop'];
}

然后,您将按以下方式调用命令:

$arg = escapeshellarg($row['SKID']);
exec( "/var/www/web/shop_xml/index.php \"$arg\" 1" );

但是,更好的解决方案是将要从CLI调用的index.php中的代码拿走,然后将其移到include(如functions.php)中,然后将其放入如下函数中:

function processShopRow($showKeeper, $shop) {
   // stuff that used to be in index.php goes here
}

现在,在index.php和从CLI运行的代码中,您将包括并运行代码,如下所示:

include('functions.php');
set_time_limit(0);

//connect to database
$msSqlDB = new mySqlConnect('Freewebstore');

$select = "SELECT * FROM FacebookStores"; 

$run = mysql_query($select);
while($row = mysql_fetch_array($run)){
    processShopRow($row['SKID'], 1);
}

您的脚本不起作用,因为

exec('/var/www/web/shop_xml/index.php?shopKeeper=$row[SKID]&shop=1');

做了

exec("/var/www/web/shop_xml/index.php?shopKeeper=$row[SKID]&shop=1");

单引号内不能包含变量。

您是否尝试过使用此功能:

exec("/var/www/web/shop_xml/index.php?shopKeeper=$row[SKID]&shop=1");

而不是原来的? 单引号'不允许您评估其中的嵌入式变量或php对象。 您必须使用双引号" -您能尝试一下吗?

在exec命令中,您需要使用lynx(命令行浏览器)或PHP CLI运行脚本。 您还应该引用域,而不是完整路径:

exec("php http://domain.com/index.php?shopKeeper=$row[SKID]&shop=1");

exec()尝试调用服务器文件系统上的程序,就像在shell提示符下键入exec()参数一样。 外壳程序不知道如何处理URL,因此您将收到“没有匹配的文件”错误,如? 网址中的内容将被视为外壳通配符。

如果您想请求网址,则至少需要

$output = file_get_contents("/var/www/etc....");

并且PHP将为您执行完整的HTTP请求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM