php foreach: проблема со скриптом - PullRequest
2 голосов
/ 09 ноября 2010

У меня проблема со следующим сценарием, он записывает в базу данных только первый номер 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();

?>

$ элементы получены из множественного выбора, который я выполняю во flexigrid.

LE: Если я выполню эту команду через Putty:

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

Я получу номер PID этого процесса PLOWDOWN, я могу увидеть это в моем списке процессов с TOP.

поэтому мне нужно выполнить команду для каждого выбранного URL-адреса и ввести номер PID в базу данных на случай, если позже я захочу остановить процесс.

Надеюсь, это имеет смысл.

Ответы [ 3 ]

2 голосов
/ 09 ноября 2010

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 не будет содержать нулевое значение, и будет содержать нулевое значение всякий раз, когда больше не осталось результатов для обработки. Каждый раз, когда он содержит ненулевое значение, будет выполнено тело цикла. Теперь, что касается того, почему вы записываете только один PID в базу данных, это потому, что вы получаете только один URL из базы данных. Вам нужно перебрать все 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());
}
0 голосов
/ 09 ноября 2010

Должен быть цикл 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();
0 голосов
/ 09 ноября 2010

Поскольку ваш запрос использует элементы where in, он будет производить одинаковые записи независимо от того, сколько раз он выполняется.Если вы хотите другой pid, вы захотите использовать идентификатор из зацикленной записи.

Также я бы рекомендовал использовать time () вместо вашего случайного числа, что обеспечит уникальность.*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...