У меня есть сценарий, который выполняет файл в нескольких каталогах, которые выглядят следующим образом:
exec("php-cli $file_path > /dev/null 2>/dev/null &"); //php command-line
Это работает на большинстве хостов, но некоторым хостам это не нравится, и он не запускается без каких-либо ошибок.
Для хостов, с которыми это не удается, я использую
exec("php $file_path > /dev/null 2>/dev/null &"); //notice the -cli is gone
Что хорошо работает.
$ file_path – полный путь к исполняемому файлу /home/blah/path/blah.php
Как я могу сделать эту форму так, чтобы она работала на всех серверах (по крайней мере, unix)
** РЕДАКТИРОВАТЬ * *
Ну, я делаю это так, это (скорее всего) не правильный путь, но он работает.
Вместо того, чтобы просто использовать php-cli или php, я использую оба метода, поэтому если один из них терпит неудачу, другой проходит. Либо php работает как cgi, либо cli, и один из них будет ловить, и поскольку нет выхода, также не было бы ошибки.
exec("php-cli $file_path > /dev/null 2>/dev/null &"); exec("php $file_path > /dev/null 2>/dev/null &");
Если вы не знаете лучшего решения, пожалуйста, дайте мне знать. Спасибо за вашу помощь.
function php_exec($file_path) { if (!($binary = which(array('php', 'php5', 'php-cli', 'php-cgi')))) return false; return exec("$binary $file_path > /dev/null 2>/dev/null &"); } function which($binaries) { if (!($path = getenv('PATH')) && !($path = getenv('Path'))) return false; $arr = preg_split('/[:;]/', $path); foreach ($arr as $p) { foreach ($binaries as $b) { if (file_exists("$p/$b")) return "$p/$b"; } } return false; } var_dump(php_exec('test.php'));
Объяснение: В большинстве систем двоичный файл PHP называется php, php5, php-cli или php-cgi. функция () проверяет стандартный путь (оба * nix и окна имеют переменную окружения, называемую PATH / Path) для каждого из этих имен, и если он найдет файл с таким именем, он вернет его.
Формат переменной PATH: /bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
для * nix (bash) и C:\Windows\System32\;C:\Windows\;
для окон, поэтому я использую preg_split ('/ [:;] /')
Это решение лучше вашего, потому что php_exec () вернет false
если он не может найти действительный двоичный файл php. В вашем решении нет способа узнать, не выполнено ли выполнение сценария.
Это зависит от того, как скомпилирован двоичный файл PHP-CLI. В большинстве систем исполняемый файл называется просто «php», и я предполагаю, что хосты, которые имеют «php-cli», скомпилированы вручную, а большинство других – через диспетчер пакетов ОС.
У вас есть два варианта, чтобы обойти это и сделать его «универсальным»:
Возможно, простой вопрос, но существует ли php-cli
на всех хостах? Я предполагаю, что причина его неудачного молчания в том, что вы говорите, что это перенаправляет все.
exec("php $file_path > /some/writable/path/output.log 2>/some/writable/path/error.log &");