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_name
jest 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-cgi
tym, to nie zadziała. Z kolei zwróci cgi-fcgi
String. Jeśli załadujesz skrypt jako stronę internetową z przeglądarki, otrzymasz apache2handler
. Mam nadzieję że to pomoże. Musiałem użyć php-cgi
w celu wprowadzenia $_GET
zmiennych: php-cgi myscript.php arg1=one arg2=two
. Testowanie na wartość nie równą apache2handler
powinno być w porządku apache
.
"cli"
po uruchomieniu z zadania cron. Istnieje wiele różnych kluczy do wyboru w $_SERVER
celu 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 $_SERVER
tablica 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()===false
wię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 $argv
zmiennej (co prawdopodobnie zrobisz dla parametrów wiersza poleceń). Nawet jeśli nie ma parametrów, $argv
zwraca 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 STDIN
jest 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ć.