我正在尝试从脚本中运行脚本并使下面看起来不起作用。我基本上是从数据库中获取大量数据,循环遍历每一行并运行一个脚本,该脚本将根据该数据生成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');
}
最好的方法是什么?第二行是否会等到第一行成功执行或者可以同时多次运行?非常感谢您对此提出的任何建议。
答案 0 :(得分:4)
你需要做这样的事情:
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
条记录,并有助于避免大量进程占用服务器资源。
作为旁注,您似乎使用了OO DB代码和程序DB代码的奇怪组合 - 您应该坚持使用其中一个以避免混淆。
答案 1 :(得分:2)
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" );
然而,一个更好的解决方案是获取index.php中的代码,该代码从CLI调用并将其移动到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);
}
答案 2 :(得分: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");
单引号无法在其中包含变量。
答案 3 :(得分:1)
您是否尝试过使用此功能:
exec("/var/www/web/shop_xml/index.php?shopKeeper=$row[SKID]&shop=1");
而不是原来的?单引号'
不允许您评估其中的嵌入变量或php对象。你必须使用双引号"
- 你能试试吗?
答案 4 :(得分:0)
在exec命令中,您需要使用lynx(命令行浏览器)或PHP CLI运行脚本。您还应该引用域,而不是完整路径:
exec("php http://domain.com/index.php?shopKeeper=$row[SKID]&shop=1");
答案 5 :(得分:0)
exec()尝试在服务器的文件系统上调用程序,就像在shell提示符下键入exec()参数一样。 shell不知道如何处理URL,因此您将收到“无匹配文件”错误,因为url中的?
将被视为shell通配符。
如果您想申请网址,则必须至少执行
$output = file_get_contents("/var/www/etc....");
并且PHP将为您执行完整的HTTP请求。