[英]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.