Как передать файл в качестве аргумента в php exec? - PullRequest
1 голос
/ 23 октября 2011

Я хотел бы знать, как я могу передать содержимое файла (в моем случае csv) в качестве аргумента для исполняемого файла командной строки (в C или Objective C), который будет вызываться exec в php.

Вот что я сделал: пользователь загружает содержимое своего файла с URL-адреса следующим образом:

http://www.myserver.com/model.php?fileName=test.csv

Тогда следующий код позволяет php анализировать и загружать файл csv:

<?php

$f = $_GET['fileName'];
$handle = fopen("$f", "r"); 

$data = array(); 
while (($line = fgetcsv($handle)) !== FALSE) { 
$data[] = $line;
}

?>

где я застрял - как передать содержимое этого csv-файла в качестве аргумента exec. Даже если я могу предположить, что csv, как известно, имеет только два столбца, количество строк зависит от пользователя, поэтому я не могу передать все значения одно за другим в качестве параметров, например

exec("/path_to_executable/model -a $data[0][0] -b $data[0][1] .....");

Единственное альтернативное решение, я думаю, было бы написать что-то вроде этого:

exec("/path_to_executable/model -fileName test.csv");

и чтобы исполняемый файл командной строки выполнял синтаксический анализ csv, но в этом случае, я думаю, мне нужно, чтобы файл csv был физически записан на стороне сервера. Мне интересно, что произойдет, если несколько человек одновременно получат доступ к веб-странице со своим собственным файлом csv, они перезаписывают друг друга?

Полагаю, для этого должен быть правильный способ, и я этого не понял. Любая идея? Спасибо!

Ответы [ 2 ]

0 голосов
/ 23 октября 2011

Я бы порекомендовал хранить эти данные на диске и загружать их в утилиту командной строки - с этим гораздо меньше проблем.Но если вы не можете этого сделать, просто передавайте по одной (непарсированной) строке за раз:

$command = "/path_to_executable/model";
foreach ($fileData as $line) {
  $command .= ' "'.escapeshellarg($line).'"';
}
exec($command);

Тогда вы можете просто извлечь данные в свою утилиту, выполнив цикл argv, где argv[0] - первая строка, argv[1] - вторая строка и т. д.

0 голосов
/ 23 октября 2011

вы можете использовать popen () , чтобы получить дескриптор процесса для записи.Если вам нужно пойти в обоих направлениях (чтение / запись) и вам может потребоваться больше энергии, посмотрите: proc_open () .

Вы также можете просто записать свои данные в какой-нибудь случайный файл(чтобы не допустить, чтобы несколько пользователей пинали друг друга по заднице).Что-то вроде

<?php
$csv = file_get_contents('http://www.myserver.com/model.php?fileName=test.csv
');
$filename = '/tmp/' . uniqid(sha1($csv)) . '.csv';
file_put_contents($filename, $csv);
exec('/your/thing < '. escapeshellarg($filename));
unlink($filename);

И так как вы также отвечаете за исполняемый файл, вы можете выяснить, как получить количество переданных аргументов (подсказка: argc) и прочитать их в (подсказка:ARGV).Проходя их по линии, например, так:

<?php

$csvRow = fgetcsv($fh);
if ($csvRow) {
  $escaped = array_map('escapeshellarg', $csvRow);
  exec('/your/thing '. join(' ', $escaped));
}
...