Почему PHP не распознает программу в системе Windows PATH, когда я использую ее с Apache?
В моей локальной среде разработки у меня установлен Apache и PHP в Windows 7. Я звоню в 7-Zip из моей PHP-программы с помощью exec. Сначала я попытался
exec('7z a example.zip example.pdf');
но он не создал zip файл. После проверки журнала ошибок Apache я обнаружил
"7z" не распознается как внутренняя или внешняя команда, операционная программа или командный файл.
После изменения exec
чтобы включить полный путь к 7-Zip.exe, он сработал.
exec('"C:\\Program Files\\7-Zip\\7z" a example.zip example.pdf');
Но C:\Program Files\7-Zip
включен в мою систему Windows PATH. Тот же PHP-код работает из командной строки без использования полного пути.
php -r "exec('7z a example.zip example.pdf');"
Почему это требует полного пути, когда я использую его с Apache?
Важным моментом, который я забыл включить, когда я изначально поставил этот вопрос, является то, что я уже могу использовать exec()
для вызова других программ, включенных в систему Windows PATH, не ссылаясь на них по их полным путям.
Еще один момент, о котором я не упоминал изначально, потому что я не осознавал, что его значимость заключалась в том, что 7-Zip был добавлен в PATH только недавно, и я снова перезапустил службу Apache после добавления.
Ответы
Ответ 1
Я просто понял, что вызывает эту проблему. Это было фактически не связано с моим первоначальным предположением.
Я вспомнил, что видел информацию о PATH
в phpinfo()
, поэтому я посмотрел на это. В разделе "Apache Environment" он отображал всю PATH
кроме пути к 7-Zip, который я недавно добавил в систему PATH
. По-видимому, он, похоже, имеет доступ к этому пути, но не использовал текущую версию. Почему нет?
Обычно я думал, что только что забыл перезапустить Apache после обновления пути, но я повторно перезапустил его, пытаясь понять это. Но, по-видимому, перезапуск Apache не обновляет это значение. Я должен был остановить это, а затем начать его. Затем путь 7-Zip появился в PATH
в phpinfo, и я смог изменить свою программу на использование простой 7z
.
Ответ 2
У меня WAMP установлен на Windows 8, и после прочтения вашего вопроса я решил проверить пару вещей.
Запуск echo exec('whoami');
повторил:
nt authority\system
Это подтверждает то, что сказал @Barmar, Apache не работает под тем же пользователем, что и вы, поэтому PATH
отличается.
Я решил остановить Apache и запустить его вручную под учетной записью администратора. Затем я попробовал:
echo exec('whoami');
Что вышло:
computername\administrator
Я предположил, что теперь exec
будет работать с PATH
и попытался:
echo exec('adb');
// Инструмент adroid adb находится на моем PATH
Удивительно, но несмотря на то, что Apache работал с тем же пользователем, что и я, PATH
все еще не работал. Я не знаю, почему это происходит, и если у кого-то есть подсказка, прокомментируйте это ниже.
Мне удалось использовать PATH
(используя учетную запись администратора) со следующим кодом:
https://stackoverflow.com/users/171318/hek2mgl $ WshShell = новый COM ("WScript.Shell"); $ oExec = $WshShell-> Выполнить ("cmd/C 7z a example.zip example.pdf", 0); //0 невидимый /1 видимый
Я не тестировал код ниже, но вы можете попробовать установить PATH
в учетной записи Apache Service (nt authority\system
), а затем использовать команду, то есть:
echo exec('set PATH=%PATH%;C:/path/to/7z');
echo exec('7z a example.zip example.pdf');
Я считаю, что path
будет по-прежнему действителен между перезагрузками.
Обновить:
этот ответ может помочь вам установить PATH
для учетной записи nt authority\system
.
Личные переменные среды пользователя локальной системы указаны в " HKEY_USERS.DEFAULT\Environment ". Общесистемные переменные среды указаны в разделе " HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment ". Первый из них не очень легко доступен из любого места, кроме реестра, но последний доступен из диалогового окна " Переменные среды " на вкладке " Дополнительно " в " Свойствах системы ".
Для будущих пользователей правильным способом установки Apache PATH является:
Вы можете использовать setEnv
в .htaccess
или putenv
в PHP
коде для установки $PATH
Кредит идет на hek2mgl