php foreach:脚本问题

时间:2010-11-09 12:23:29

标签: php foreach

我遇到以下脚本的问题,它只在数据库中写入第一个PID号,但它执行两个命令:

<?php
error_reporting(0);

include_once "config/mysql.php";

// the path
$path = "PATH=$PATH:/share/MD0_DATA/.qpkg/Optware/bin:";

//random number for the log file name
$random = rand(1,500000);

//initial download location
$init_loc="/share/MD0_DATA/Qdownload/plowshare";

$items = rtrim($_POST['items'],",");
$sql = mysql_query("SELECT url FROM plow WHERE id IN ($items)") or die ('Error: ' . mysql_error());
$db_row = mysql_fetch_assoc($sql);
foreach ($db_row as $value) { 
  //random number for the log file name
  $random = rand(1,500000);
  //log file name
  $out_file = '/share/MD0_DATA/Qdownload/plowshare/Logs/log'.$random.'.txt';
  //command 1
  $command = exec("($path" . " nohup /opt/bin/plowdown -o '$init_loc' " . "'$value' 2> " . "'$out_file' > /dev/null &);" . "echo $$;", $out); 
  exec($command, $out);
  $query = mysql_query("UPDATE plow SET state = 'Active', pid = '$out[0]' WHERE id IN ($items)") or die ('Error: ' . mysql_error());
 }
mysql_close();

?>

$ items来自我在flexigrid中制作的多重选择。

LE:如果我通过Putty运行此命令:

nohup /opt/bin/plowdown -o /share/Qdownload/plowshare http://www.megadownloadlink.com 2> /share/Qdownload/plowshare/Logs/log342342.txt > /dev/null &

我得到PLOWDOWN进程的PID号,我可以在TOP的进程列表中看到这个。

所以我需要为所选的每个URL运行命令,并在数据库中输入PID号,以防我想稍后停止该过程。

希望这是有道理的。

3 个答案:

答案 0 :(得分:2)

mysql_fetch_assoc在列形成关联数组时返回单行。您的代码现在似乎在列上循环,但您只选择一列。因此,删除foreach循环并简单地说$value = $db_row['url'];等同于您。但那仍然不是你想要的行为。

运行查询时,应循环显示结果,直到没有结果为止。那将是这样的:

$sql = mysql_query("SELECT url FROM plow WHERE id IN ($items)")
       or die ('Error: ' . mysql_error());
while($db_row = mysql_fetch_assoc($sql)){
    // execute per result stuff, $db_row['url'] gives you the `url` column

}

这一行:while($db_row = mysql_fetch_assoc($sql))将一直运行,直到$db_row保持空值,并且只要没有剩余的结果要处理,它就会保留一个空值。每次它保持非null值时,循环体将执行。现在,至于你为什么只向数据库写一个PID,那是因为你只从数据库中获取一个URL。您需要遍历所有网址。

除此之外,您的exec来电与您的测试用例不符,这是一个与您的测试用例匹配的调用:

exec("{$path} nohup /opt/bin/plowdown -o {$init_loc} {$db_row['url']} 2> $out_file > /dev/null &", $out); 

把这一切放在一起我们产生这样的东西:

$sql = mysql_query("SELECT url FROM plow WHERE id IN ($items)")
       or die ('Error: ' . mysql_error());
while($db_row = mysql_fetch_assoc($sql)){
    // execute per result stuff, $db_row['url'] gives you the `url` column
    $random = rand(1,500000);
    //log file name
    $out_file = '/share/MD0_DATA/Qdownload/plowshare/Logs/log'.$random.'.txt';

    exec("{$path} nohup /opt/bin/plowdown -o {$init_loc} {$db_row['url']} 2> $out_file > /dev/null &", $out);

    mysql_query("UPDATE plow SET state = 'Active', pid = '{$out[0]}' WHERE id IN ($items)") 
        or die ('Error: ' . mysql_error());
}

答案 1 :(得分:0)

由于您的查询使用where in items,无论运行多少次,它都会影响相同的记录。如果您希望使用不同的pid,则需要使用正在循环的记录中的标识符。

另外,我建议使用time()而不是随机数来确保唯一性。

$sql = mysql_query("SELECT url FROM plow WHERE id IN ($items)")
       or die ('Error: ' . mysql_error());
while($db_row = mysql_fetch_assoc($sql)){
    // execute per result stuff, $db_row['url'] gives you the `url` column
    $random = time();
    //log file name
    $out_file = '/share/MD0_DATA/Qdownload/plowshare/Logs/log'.$random.'.txt';
    $command = exec("($path" . " nohup /opt/bin/plowdown -o '$init_loc' " . "'$value' 2> " . "'$out_file' > /dev/null &);" . "echo $$;", $out1); 
    exec($command, $out2);

    // first exec saved output to $out1
    mysql_query("UPDATE plow SET state = 'Active', pid = '$out1[0]' WHERE id IN ($items)") 
        or die ('Error: ' . mysql_error());
    // second exec saved output to $out2
    mysql_query("UPDATE plow SET state = 'Active', pid = '$out2[0]' WHERE id = $db_row['id']") 
        or die ('Error: ' . mysql_error());
}

答案 2 :(得分:0)

应该是一个while循环:

while($db_row = mysql_fetch_assoc($sql))
{
    //Your Code here
}

更新:我将如何编写以下内容:

error_reporting(0);

include_once "config/mysql.php";

// the path
$path = "PATH=$PATH:/share/MD0_DATA/.qpkg/Optware/bin:";

//initial download location
$init_loc="/share/MD0_DATA/Qdownload/plowshare";

$items = mysql_real_escape_string(rtrim($_POST['items'],","));

$query = mysql_query("SELECT url FROM plow WHERE id IN (" . $items .")");
if($query)
{
    while($row = mysql_fetch_assoc($query))
    {
        $out_file = '/share/MD0_DATA/Qdownload/plowshare/Logs/log'.rand().'.txt';
        while(file_exists($out_file))
        {
            $out_file = '/share/MD0_DATA/Qdownload/plowshare/Logs/log'.rand().'.txt';
        }

        $command = "(" . $path . "  nohup /opt/bin/plowdown -o ".$init_loc." " . $value . " 2> " . $out_file . " > /dev/null &);";

       exec($command,$out);

       $update = "UPDATE plow SET state = 'Active', pid = '" . $out[0] . "' WHERE id IN ( " . $items . " )";

       if(mysql_query($update))
       {
           echo 'Updated: ' . mysql_insert_id() . "\n";
       }
    }
}
mysql_close();