PHP - यदि सीएलआई या वेब सर्वर से वर्तमान आह्वान सबसे अच्छा है तो यह कैसे निर्धारित किया जाए?


192

मुझे यह निर्धारित करने की आवश्यकता है कि PHP का वर्तमान आह्वान कमांड लाइन (CLI) से है या वेब सर्वर से (मेरे मामले में, Ap_ mod_php के साथ)।

किसी भी अनुशंसित तरीके?


संपादित और प्रश्न को स्पष्ट किया।
शमीम

जवाबों:


308

php_sapi_nameवह फ़ंक्शन है जिसका आप उपयोग करना चाहते हैं क्योंकि यह इंटरफ़ेस प्रकार का एक लोअरकेस स्ट्रिंग लौटाता है। इसके अलावा, PHP स्थिरांक है PHP_SAPI

प्रलेखन यहाँ पाया जा सकता है: http://php.net/php_sapi_name

उदाहरण के लिए, यह निर्धारित करने के लिए कि क्या PHP को CLI से चलाया जा रहा है, आप इस फ़ंक्शन का उपयोग कर सकते हैं:

function isCommandLineInterface()
{
    return (php_sapi_name() === 'cli');
}

11
अधिक सीधा:return php_sapi_name() == 'cli';
Savageman

11
मैंने एक शोध किया: यदि आप इस स्क्रिप्ट को लागू करते हैं तो php-cgiयह काम नहीं करेगा। बदले में, यह cgi-fcgiस्ट्रिंग लौटाएगा । यदि आप स्क्रिप्ट को ब्राउज़र से वेब पेज के रूप में लोड करते हैं, तो आपको मिलेगा apache2handler। उम्मीद है की यह मदद करेगा। मुझे चर php-cgiपेश करने के लिए उपयोग करने की आवश्यकता है :। नहीं के बराबर होना चाहिए के लिए परीक्षण ठीक है । $_GETphp-cgi myscript.php arg1=one arg2=twoapache2handlerapache
सेबेस्टियन

3
इस पद्धति के बारे में एक छोटा चेतावनी: यह क्रॉन जॉब से चलने पर वापस नहीं आएगा "cli"$_SERVERअनुरोध को HTTP के माध्यम से आया है या नहीं, इसके बारे में अधिक भरोसेमंद रूप से निर्धारित करने के लिए अंदर से चुनने के लिए एक नंबर ओड डिफरेंट कीज़ है ।
सर्वव्यापी

2
@omnonsons I ने PHP 7.2.7 के साथ परीक्षण किया और यह cli देता है।
जोस

38

मैं कुछ वर्षों से इस फ़ंक्शन का उपयोग कर रहा हूं

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;
}

10
array_key_exists('REQUEST_METHOD', $_SERVER) return true;WAT?
biziclop

@biziclop, अनुरोधarray_key_exists('REQUEST_METHOD', $_SERVER) के स्रोत का पता लगाने में सहायता के लिए चेक सही है । जब CLI में , $_SERVERसुपर ग्लोबल ऐरे की कुंजी नहीं होगी REQUEST_METHOD, यह केवल तब मौजूद होता है जब अनुरोध वेब के माध्यम से किया जाता है, इसलिए, लेखक पूरी तरह से इसके लिए जाँच करते समय निशाने पर होता है।
जूलियो मरची

1
@ JulioMarchi: लेकिन यह return false;या नहीं करना चाहिए if ( ! array_key_exists(…)) return true;?
biziclop

2
@biziclop, आप पूरी तरह से सही हैं !!!! मैं इतना बड़ा छोटा विवरण कैसे याद कर सकता हूं ??? मुझ पर शर्म की बात है... :)। निश्चित रूप से, अगर कुंजी 'REQUEST_METHOD'है नहीं पाया, तो समारोह लौटना चाहिए FALSE"CLI" से संकेत मिलता है। फ़ंक्शन के दायरे पर ध्यान न देने के लिए मेरी माफी ... लेखक को इसे ठीक करना चाहिए क्योंकि फ़ंक्शन वास्तव में काम करता है!
जूलियो मरची

इस फ़ंक्शन ने मेरे मामले में काम किया, php_sapi_name () नहीं, क्योंकि मुझे वेब अनुरोधों और क्रोनजोब निष्पादन के बीच अंतर करने की आवश्यकता थी, और php_sapi_name () परिणाम दोनों मामलों में "php-cgi" था।
luis.ap.uyen

36

php_sapi_name()वास्तव में इस जाँच को करने का सबसे अच्छा तरीका नहीं है क्योंकि यह कई संभावित मूल्यों के खिलाफ जाँच पर निर्भर करता है। Php-cgi बाइनरी को कमांड लाइन से, शेल स्क्रिप्ट से या क्रोन जॉब के रूप में कहा जा सकता है और (ज्यादातर मामलों में) इन्हें 'cli' भी माना जाना चाहिए, लेकिन php_sapi_name()इनके लिए अलग-अलग मान दिए जाएंगे (ध्यान दें कि यह isn ') PHP के सादे संस्करण के साथ मामला नहीं है, लेकिन आप चाहते हैं कि आपका कोड कहीं भी, सही काम करे?)। यह उल्लेख नहीं करने के लिए कि अगले वर्ष PHP का उपयोग करने के नए तरीके हो सकते हैं जिन्हें हम संभवतः अब नहीं जान सकते। मैं इसके बारे में नहीं सोचता जब मैं मौसम की परवाह करता हूं तो मुझे अपना आउटपुट HTML में लपेटना चाहिए या नहीं।

सौभाग्य से, PHP के पास इसके लिए विशेष रूप से जांच करने का एक तरीका है। बस http_response_code()किसी भी पैरामीटर के बिना उपयोग करें और यह TRUE लौटा देगा यदि एक वेब सर्वर प्रकार के वातावरण से और FALSE को एक CLI प्रकार के वातावरण से चलाया जाए। यहाँ कोड है:

$is_web=http_response_code()!==FALSE;

यह तब भी काम करेगा जब आप गलती से (?) इस कॉल से पहले CLI (या CLI जैसी कोई चीज़) से चलने वाली स्क्रिप्ट से एक प्रतिक्रिया कोड सेट करें।


4
यह प्रश्न पहले से ही पुराना था जब मैंने इसका उत्तर दिया। इस जवाब को वोट करने से शायद एक और उत्तर पोस्ट करने से ज्यादा उपयोगी होता है जो कि स्पष्टीकरण के बिना एक डुप्लिकेट है।
krowe2

इस बारे में "कि यह तब भी काम करेगा जब आप गलती से (?) कॉल करने से पहले CLI ([...]) से चलने वाली स्क्रिप्ट से एक प्रतिक्रिया कोड सेट करें।": (कम से कम) PHP 7.4.3 के रूप में, यह। सच नहीं। http_response_code()CLI से चलने पर कोड / रिटर्न सेट कोड सेट करता है। द्वारा सत्यापित <?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();। तो अगर http_response_code()===falseयह CLI मानने के लिए सुरक्षित शर्त है, लेकिन अगर आपको अन्य मेट्रिक्स की भी जांच करने की आवश्यकता नहीं है।
सेबेस्टियन बी

23

मुझे लगता है कि उसका मतलब है कि अगर PHP सीएलआई को लागू किया जा रहा है या अगर यह एक वेब अनुरोध से प्रतिक्रिया है। इसका सबसे अच्छा तरीका यह होगा php_sapi_name()कि अगर यह एक वेब अनुरोध चला रहा है तो यह अपाचे को गूंज देगा यदि यह चल रहा था।

Php डॉक्सphp_sapi_name() से लिए गए कुछ की सूची पर :

  • aolserver
  • अमरीका की एक मूल जनजाति
  • apache2filter
  • apache2handler
  • caudium
  • cgi (PHP 5.3 तक)
  • cgi-fcgi
  • CLI
  • cli-server ( अंतर्निहित PHP 5.4 के रूप में वेब सर्वर )
  • निरंतरता
  • एम्बेड
  • FPM-fcgi
  • ISAPI
  • LiteSpeed
  • मच्छ
  • NSAPI
  • phttpd
  • pi3web
  • Roxen
  • thttpd
  • टक्स
  • webjames

13

यह सभी मामलों को संभालना चाहिए (php-cgi सहित)

return (php_sapi_name() === 'cli' OR defined('STDIN'));

6
function is_cli() {
    return !http_response_code();
}

उदाहरण:

if (is_cli()) {
    echo 'command line';
} else {
    echo 'browser';
}

2
मैन्युअल से, "FALSE लौटाया जाएगा यदि response_code प्रदान नहीं किया गया है और यह एक वेब सर्वर वातावरण (जैसे एक CLI एप्लिकेशन से) में लागू नहीं किया गया है। TRUE वापस किया जाएगा यदि response_code प्रदान किया गया है और इसे वेब सर्वर में नहीं लगाया गया है। पर्यावरण (लेकिन केवल जब कोई पिछली प्रतिक्रिया की स्थिति निर्धारित नहीं की गई है) "। आप अपने तर्क को पीछे की ओर ले गए हैं।
क्रोव 2

1
+1। गजब का। इतने वर्षों के निरर्थक शोध के बाद ... मैं इसके द्वारा आपको PHPics के नोबेल मेमोरियल पुरस्कार से सम्मानित करता हूँ, जो वास्तव में इसे काम करने के उनके अमूल्य योगदान के लिए @ krowe2 के साथ साझा करता है। बधाई हो!
एस.जे.

यह संभव है कि कुछ ने प्रतिक्रिया कोड निर्धारित किया हो ... http_response_code(200);... अगर मैं अब फोन http_response_code()करता हूं तो यह 200 वापस आ जाएगा;
ब्रैड केंट

@BradKent यह केवल तभी है जब आप इसे एक वेब वातावरण से कॉल करते हैं और उस स्थिति में, यह चेक तब भी काम करेगा जब तक आपने स्थिति कोड को शून्य पर सेट नहीं किया था (जो कि एक अवैध HTTP स्थिति कोड वैसे भी है)। मेरा संस्करण उस मामले में भी काम करेगा क्योंकि यह विशेष रूप से FALSE के खिलाफ जांच करता है। यदि http_response_code();सीएलआई वातावरण से कहा जाता है तो यह वास्तविक स्थिति कोड की परवाह किए बिना हमेशा FALSE लौटाएगा। मैंने पहले ही अपने उत्तर में यह समझाया है, लेकिन आप "रिटर्न वैल्यूज़" के तहत मैनुअल पेज को पढ़कर या इसे आज़माकर भी यह पता लगा सकते हैं।
krowe2

@ krowe2 php -r 'http_response_code(200); echo http_response_code()."\n";' आउटपुट "200" जब तक आप गारंटी दे सकते हैं कि कुछ पुस्तकालय या अज्ञानी ढांचे ने प्रतिक्रिया कोड को http_response_code(यहां तक ​​कि एक cli env में) सेट नहीं किया है , तब यह काम करेगा। व्यक्तिगत रूप से, मैं का उपयोग करें$isCli = \defined('STDIN') || isset($_SERVER['argv']) || \array_key_exists('REQUEST_METHOD', $_SERVER)
ब्रैड केंट

4

मैंने इसका उपयोग किया:

php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)

यह Drush codebase, environment.inc से है जहां इन्हें बनाने के लिए समान जांच होती है।


4
यदि register_argc_argvसेट किया गया है, तो GET मान की किसी भी राशि में उत्तीर्ण होने का कारण argc0. नहीं होगा

3

प्रयत्न

isset($_SERVER['REQUEST_METHOD'])

यदि यह सेट है, तो आप एक ब्राउज़र में हैं।

वैकल्पिक रूप से, आप देख सकते हैं कि क्या

isset($_SERVER['argv'])

लेकिन यह विंडोज़ CLI, IDK पर सही नहीं हो सकता है।


1
हालांकि यह "सही" उत्तर नहीं है लेकिन यह अधिक विश्वसनीय हो सकता है
challet

2

Http://jp2.php.net/manual/en/features.commandline.php के अनुसार , सीएलआई से चलने पर केवल कई स्थिरांक निर्धारित होते हैं। ये स्थिरांक STDIN, STDOUT और STDERR हैं। उनमें से एक के लिए परीक्षण आपको बताएगा कि क्या यह क्ली मोड में है



0

मैं यह जांचने का सुझाव दूंगा कि क्या $ _SERVER सरणी में से कुछ प्रविष्टियां सेट की गई हैं।

उदाहरण के लिए:

if (isset($_SERVER['REQUEST_METHOD'])) {
        print "HTTP request\n";
} else {
        print "CLI invocation\n";
}

यह php-cgiकमांड लाइन के साथ काम नहीं करेगा , इसे इसके लिए सेट किया जाएगा GET:php-cgi -f file.php arg1=2
सेबस्टियन



0

एक आसान तरीका $argvचर को पूछताछ करना है, (जो आप वैसे भी कमांड लाइन मापदंडों के लिए करेंगे)। यहां तक ​​कि अगर कोई पैरामीटर नहीं है तो $argvएक खाली सरणी देता है।

यदि यह सेट है, तो क्ली का उपयोग किया गया था। फिर आप मान सकते हैं कि अन्य सभी चालान किसी वेब सर्वर या अन्य के माध्यम से हैं।

उदाहरण के लिए:

if (isset($argv)) {
  // Do the cli thing.
}

0

ऊपर सिल्वर मून के उत्तर के आधार पर , मैं सही लाइनब्रेक लौटाने के लिए इस फ़ंक्शन का उपयोग कर रहा हूं:

/**
* 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>";

}

0

इस प्रश्न का सही उत्तर इसके पीछे की वास्तविक मंशा पर निर्भर करता है:

  • SAPI निर्णायक कारक है (वेब-संदर्भ या नहीं)?
  • या क्या सूचना को 'ट्टी में चल रहा है' कहा जाता है?

यदि पूर्व में दिए गए उत्तर और लिखी गई टिप्पणियां काम करने वाले समाधान खोजने के लिए पर्याप्त हैं।

यदि उत्तरार्द्ध, यहां दिए गए व्यंजनों को विफल कर दिया जाएगा यदि उपकरण को क्रोनजोब के रूप में चलाया जाता है, या किसी अन्य डेमॉन से पृष्ठभूमि-नौकरी के रूप में - उस मामले में मैं आगे परीक्षण करने का सुझाव देता हूं यदि STDINएक टीटीवाई है:

function at_tty() {
    return defined("\STDIN") && posix_isatty(\STDIN);
}

-1

कैसे, इतने सारे जटिल समाधान। कैसा रहेगा ...

if($_SERVER['REQUEST_SCHEME']=="http" or $_SERVER['REQUEST_SCHEME']=="https"){
    // must be browser :)
}

-17

मैं कोशिश करूँगा:

echo exec('whoami');

आमतौर पर webservers एक अलग उपयोगकर्ता नाम के तहत चलाए जाते हैं, इसलिए यह बताना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.