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.
Zrobiłem badanie: jeśli wywołasz skrypt z 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.
Sebastian
3
Małe zastrzeżenie dotyczące tej metody: nie wróci "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.
omninonsense
2
@ omninonsense Testowałem z PHP 7.2.7 i zwraca cli.
Jose Nobile
38
Korzystam z tej funkcji od kilku lat
function is_cli(){if(defined('STDIN')){returntrue;}if( php_sapi_name()==='cli'){returntrue;}if( array_key_exists('SHELL', $_ENV)){returntrue;}if( empty($_SERVER['REMOTE_ADDR'])and!isset($_SERVER['HTTP_USER_AGENT'])and count($_SERVER['argv'])>0){returntrue;}if(!array_key_exists('REQUEST_METHOD', $_SERVER)){returntrue;}returnfalse;}
@biziclop, pole wyboru 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.
Julio Marchi,
1
@JulioMarchi: ale czy nie powinno to return false;zrobić if ( ! array_key_exists(…)) return true;?
biziclop
2
@biziclop, masz całkowitą rację !!!! Jak mogłem przeoczyć tak ogromne szczegóły? Wstyd mi ... :). Z pewnością, jeśli NIE'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
Julio Marchi,
Ta funkcja działała w moim przypadku, a nie php_sapi_name (), ponieważ musiałem rozróżniać żądania sieciowe i wykonania cronjob, a wynikiem php_sapi_name () w obu przypadkach było „php-cgi”.
luis.ap.uyen
36
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.
To pytanie było już stare, kiedy na nie odpowiedziałem. Głosowanie w górę tej odpowiedzi prawdopodobnie byłoby bardziej przydatne niż opublikowanie innej odpowiedzi, która jest duplikatem, chyba że bez wyjaśnienia.
krowe2
Odnośnie „To zadziała nawet, jeśli przypadkowo (?) Ustawisz kod odpowiedzi ze skryptu uruchomionego z CLI ([...]) przed wywołaniem tego.”: (Przynajmniej) od PHP 7.4.3, to jest nie prawda. 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.
Sebastian B.
23
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.
Z instrukcji „FALSE zostanie zwrócone, jeśli kod odpowiedzi nie zostanie podany i nie zostanie wywołany w środowisku serwera WWW (np. Z aplikacji CLI). PRAWDA zostanie zwrócona, jeśli kod odpowiedzi zostanie podany i nie zostanie wywołany na serwerze WWW środowisko (ale tylko wtedy, gdy nie ustawiono wcześniejszego stanu odpowiedzi) ". Masz swoją logikę do tyłu.
krowe2
1
+1. Niesamowity. Po tylu latach bezowocnych badań ... Niniejszym przyznam Wam Nagrodę Nobla w dziedzinie PHPics, udostępnioną @ @ krowe2 za jego nieoceniony wkład w sprawienie, aby działał. Gratulacje!
Sz.
Możliwe, że coś ustawiło kod odpowiedzi ... http_response_code(200);... jeśli teraz zadzwonię http_response_code(), zwróci 200;
Brad Kent
@BradKent To TYLKO, jeśli wywołasz to ze środowiska internetowego, a w takim przypadku ta kontrola będzie nadal działać, dopóki nie ustawisz kodu stanu na zero (co i tak jest nieprawidłowym kodem statusu HTTP). Moja wersja będzie działać nawet w takim przypadku, ponieważ sprawdza się w szczególności na FAŁSZ. Jeśli 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.
krowe2
@ krowe2 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)
Chociaż nie jest to „poprawna” odpowiedź, może być bardziej wiarygodna
pretendent
2
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
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.
Prawidłowa odpowiedź na to pytanie zależy od prawdziwych intencji:
Czy SAPI jest czynnikiem decydującym (kontekst internetowy czy nie)?
Czy informacje są interpretowane jako „uruchomione w tty”?
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(){returndefined("\STDIN")&& posix_isatty(\STDIN);}
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 PHPPHP_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:
źródło
return php_sapi_name() == 'cli';
php-cgi
tym, to nie zadziała. Z kolei zwrócicgi-fcgi
String. Jeśli załadujesz skrypt jako stronę internetową z przeglądarki, otrzymaszapache2handler
. 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ądkuapache
."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
źródło
array_key_exists('REQUEST_METHOD', $_SERVER) return true;
WATarray_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 kluczaREQUEST_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”, alephp_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:Działa to nawet, jeśli przypadkowo (?) Ustawisz kod odpowiedzi ze skryptu uruchomionego z CLI (lub czegoś takiego jak CLI) przed wywołaniem tego.
źródło
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ślihttp_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ów
php_sapi_name()
php :źródło
To powinno obsłużyć wszystkie przypadki (w tym php-cgi)
źródło
przykład:
źródło
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 odpowiedzihttp_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:
Pochodzi z bazy kodu Drush, environment.inc, gdzie mają podobną kontrolę do wykonania.
źródło
register_argc_argv
jest ustawiony, to przekazanie dowolnej liczby wartości GET spowoduje, żeargc
nie będzie wynosić 0.Próbować
jeśli jest ustawiony, jesteś w przeglądarce.
Alternatywnie możesz sprawdzić, czy
ale może nie być to prawdą w Windows CLI, IDK.
źródło
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
źródło
sposób Joomla
źródło
Sugerowałbym sprawdzenie, czy niektóre wpisy w tablicy $ _SERVER są ustawione.
Na przykład:
źródło
php-cgi
wierszem poleceń, ustawi toGET
na:php-cgi -f file.php arg1=2
Moja preferowana metoda:
źródło
źródło
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:
źródło
Na podstawie powyższej odpowiedzi Silver Moon używam tej funkcji do zwracania poprawnych podziałów linii:
źródło
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:źródło
Jak wiele skomplikowanych rozwiązań. Co powiesz na ...
źródło
Spróbowałbym:
Zwykle serwery są uruchamiane pod inną nazwą użytkownika, więc to powinno powiedzieć.
źródło