Muszę ustalić, czy bieżące wywołanie PHP pochodzi z wiersza poleceń (CLI), czy z serwera WWW (w moim przypadku Apache z mod_php).
Jakieś zalecane metody?
Muszę ustalić, czy bieżące wywołanie PHP pochodzi z wiersza poleceń (CLI), czy z serwera WWW (w moim przypadku Apache z mod_php).
Jakieś zalecane metody?
Odpowiedzi:
php_sapi_namejest funkcją, której będziesz chciał użyć, ponieważ zwraca ciąg znaków małymi literami typu interfejsu. Ponadto istnieje stała PHP PHP_SAPI.
Dokumentację można znaleźć tutaj: http://php.net/php_sapi_name
Na przykład, aby ustalić, czy PHP jest uruchamiane z interfejsu CLI, możesz użyć tej funkcji:
function isCommandLineInterface()
{
return (php_sapi_name() === 'cli');
}
return php_sapi_name() == 'cli';
php-cgitym, to nie zadziała. Z kolei zwróci cgi-fcgiString. Jeśli załadujesz skrypt jako stronę internetową z przeglądarki, otrzymasz apache2handler. Mam nadzieję że to pomoże. Musiałem użyć php-cgiw celu wprowadzenia $_GETzmiennych: php-cgi myscript.php arg1=one arg2=two. Testowanie na wartość nie równą apache2handlerpowinno być w porządku apache.
"cli"po uruchomieniu z zadania cron. Istnieje wiele różnych kluczy do wyboru w $_SERVERcelu bardziej niezawodnego określenia, czy żądanie zostało wysłane przez HTTP, czy nie.
Korzystam z tej funkcji od kilku lat
function is_cli()
{
if ( defined('STDIN') )
{
return true;
}
if ( php_sapi_name() === 'cli' )
{
return true;
}
if ( array_key_exists('SHELL', $_ENV) ) {
return true;
}
if ( empty($_SERVER['REMOTE_ADDR']) and !isset($_SERVER['HTTP_USER_AGENT']) and count($_SERVER['argv']) > 0)
{
return true;
}
if ( !array_key_exists('REQUEST_METHOD', $_SERVER) )
{
return true;
}
return false;
}
array_key_exists('REQUEST_METHOD', $_SERVER) return true;WAT
array_key_exists('REQUEST_METHOD', $_SERVER)jest poprawne, aby ułatwić wykrycie źródła żądania . Kiedy w CLI The $_SERVERtablica Super globalna nie ma klucza REQUEST_METHOD, to istnieje tylko wtedy, gdy wniosek został złożony za pośrednictwem sieci, a więc autor jest absolutnie na celu sprawdzenie, kiedy do niego.
return false;zrobić if ( ! array_key_exists(…)) return true;?
'REQUEST_METHOD' zostanie znaleziony KLUCZ , funkcja powinna wrócić, aby wskazać „CLI”. Przepraszam, że nie zwróciłem uwagi na zakres samej funkcji ... Autor powinien to naprawić, ponieważ funkcja faktycznie działa! FALSE
php_sapi_name()naprawdę nie jest najlepszym sposobem na wykonanie tej kontroli, ponieważ zależy od sprawdzenia wielu możliwych wartości. Plik binarny php-cgi można wywołać z wiersza poleceń, ze skryptu powłoki lub jako zadanie cron i (w większości przypadków) powinny one być również traktowane jako „cli”, ale php_sapi_name()zwracają dla nich różne wartości (zwróć uwagę, że to nie jest ” t przypadku zwykłej wersji PHP, ale chcesz, aby Twój kod działał w dowolnym miejscu, prawda?). Nie wspominając już o tym, że w przyszłym roku mogą istnieć nowe sposoby korzystania z PHP, których nie znamy teraz. Wolałbym o tym nie myśleć, gdy jedyne, na czym mi zależy, to pogoda. Powinienem zawinąć swoje wyniki w HTML, czy nie.
Na szczęście PHP ma sposób, aby to sprawdzić. Po prostu użyj http_response_code()bez żadnych parametrów, a zwróci PRAWDA, jeśli jest uruchamiany ze środowiska typu serwera WWW, lub FALSE, jeśli jest uruchamiany ze środowiska typu CLI. Oto kod:
$is_web=http_response_code()!==FALSE;
Działa to nawet, jeśli przypadkowo (?) Ustawisz kod odpowiedzi ze skryptu uruchomionego z CLI (lub czegoś takiego jak CLI) przed wywołaniem tego.
http_response_code()ustawia kod / zwraca ustawiony kod podczas uruchamiania z CLI. Zweryfikowany przez <?php function t() { echo var_export(http_response_code(), true) . ' -> ' . (http_response_code() !== false ? 'web' : 'cli') . "\n"; } t(); http_response_code(200); t(); http_response_code(false); t();. Jeśli http_response_code()===falsewięc to bezpiecznie założyć CLI, ale jeśli nie, musisz sprawdzić również inne wskaźniki.
Myślę, że ma na myśli to, czy PHP CLI jest wywoływane, czy jest to odpowiedź z żądania sieciowego. Najlepszym sposobem byłoby użycie tego, php_sapi_name()który gdyby uruchomił żądanie WWW, powtórzyłby Apache, jeśli tak właśnie działało.
Aby wyświetlić listę kilku dokumentówphp_sapi_name() php :
function is_cli() {
return !http_response_code();
}
przykład:
if (is_cli()) {
echo 'command line';
} else {
echo 'browser';
}
http_response_code(200);... jeśli teraz zadzwonię http_response_code(), zwróci 200;
http_response_code();jest wywoływana z CLI środowisko zawsze będzie return false niezależnie od rzeczywistego kodu statusu. Wyjaśniłem to już w mojej odpowiedzi, ale możesz to również znaleźć, czytając stronę podręcznika pod „Zwracane wartości” lub wypróbowując.
php -r 'http_response_code(200); echo http_response_code()."\n";' wypisuje „200” O ile nie możesz zagwarantować, że niektóre biblioteki lub środowisko ignorujące nie ustawiło kodu odpowiedzi http_response_code(nawet w środowisku cli), to zadziała. Osobiście używam$isCli = \defined('STDIN') || isset($_SERVER['argv']) || \array_key_exists('REQUEST_METHOD', $_SERVER)
Użyłem tego:
php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)
Pochodzi z bazy kodu Drush, environment.inc, gdzie mają podobną kontrolę do wykonania.
Próbować
isset($_SERVER['REQUEST_METHOD'])
jeśli jest ustawiony, jesteś w przeglądarce.
Alternatywnie możesz sprawdzić, czy
isset($_SERVER['argv'])
ale może nie być to prawdą w Windows CLI, IDK.
Zgodnie z http://jp2.php.net/manual/en/features.commandline.php Istnieje wiele stałych ustawianych tylko podczas uruchamiania z CLI. Stałe te to STDIN, STDOUT i STDERR. Testowanie jednego z nich powie ci, czy jest w trybie cli
sposób Joomla
if (array_key_exists('REQUEST_METHOD', $_SERVER)) die();
Moja preferowana metoda:
if (array_key_exists('SHELL', $_ENV)) {
echo "Console invocation";
}
else {
echo "HTTP invocation";
}
// Detect CLI calls
define("IS_CLI_CALL",( strcmp(php_sapi_name(),'cli') == 0 ));
if(IS_CLI_CALL){
//do you stuff here
}
Prostym sposobem jest przesłuchanie $argvzmiennej (co prawdopodobnie zrobisz dla parametrów wiersza poleceń). Nawet jeśli nie ma parametrów, $argvzwraca pustą tablicę.
Jeśli jest ustawiony, użyto cli. Następnie możesz założyć, że wszystkie inne wywołania są wysyłane przez jakiś serwer WWW lub inny.
na przykład:
if (isset($argv)) {
// Do the cli thing.
}
Na podstawie powyższej odpowiedzi Silver Moon używam tej funkcji do zwracania poprawnych podziałów linii:
/**
* Linebreak function
* @return "/n" if cli, else return <br>
*/
protected static function lb(){
return (defined('STDIN') || php_sapi_name() === 'cli' || isset($_ENV['SHELL']) ||
(empty($_SERVER['REMOTE_ADDR']) && !isset($_SERVER['HTTP_USER_AGENT']) && count($_SERVER['argv']) > 0) ||
!isset($_SERVER['REQUEST_METHOD'])) ? "\n" : "<br>";
}
Prawidłowa odpowiedź na to pytanie zależy od prawdziwych intencji:
Jeśli to pierwsze, podane odpowiedzi i komentarze wystarczą, aby znaleźć rozwiązanie, które działa.
Jeśli to drugie, podane tutaj przepisy nie powiodą się, jeśli narzędzie zostanie uruchomione jako kronika lub zadanie w tle z innego demona - w takim przypadku sugeruję dalsze sprawdzenie, czy STDINjest to TTY:
function at_tty() {
return defined("\STDIN") && posix_isatty(\STDIN);
}
Spróbowałbym:
echo exec('whoami');
Zwykle serwery są uruchamiane pod inną nazwą użytkownika, więc to powinno powiedzieć.