পিএইচপি - বর্তমান আহবানটি সিএলআই বা ওয়েব সার্ভারের থেকে থাকলে কীভাবে সেরা নির্ধারণ করা যায়?


192

পিএইচপি-র বর্তমান অনুরোধটি কমান্ড লাইন (সিএলআই) থেকে বা ওয়েব সার্ভার (আমার ক্ষেত্রে, অ্যাডেচি Mod_php সহ) থেকে কিনা তা নির্ধারণ করতে হবে।

কোন প্রস্তাবিত পদ্ধতি?


সম্পাদিত এবং প্রশ্নটি স্পষ্ট করে।
শামীম

উত্তর:


308

php_sapi_nameএটি যে ফাংশনটি আপনি ব্যবহার করতে চাইবেন এটি ইন্টারফেসের ধরণের একটি ছোট স্ট্রিং দেয়। উপরন্তু, পিএইচপি ধ্রুবক আছে PHP_SAPI

ডকুমেন্টেশন এখানে পাওয়া যাবে: http://php.net/php_sapi_name

উদাহরণস্বরূপ, পিএইচপি সিএলআই থেকে চালিত হচ্ছে কিনা তা নির্ধারণ করতে আপনি এই ফাংশনটি ব্যবহার করতে পারেন:

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

11
আরও সোজা:return php_sapi_name() == 'cli';
সেভেজম্যান

11
আমি একটি গবেষণা করেছি: আপনি যদি স্ক্রিপ্টটির সাথে অনুরোধ করেন তবে php-cgiএটি কাজ করবে না। পরিবর্তে, এটি cgi-fcgiস্ট্রিং ফিরে আসবে । আপনি যদি কোনও ব্রাউজার থেকে স্ক্রিপ্টটি ওয়েব পৃষ্ঠা হিসাবে লোড করেন তবে আপনি পাবেন apache2handler। আশাকরি এটা সাহায্য করবে. আমি ব্যবহার করা প্রয়োজন php-cgiক্রম চালু করার জন্য $_GETভেরিয়েবল: php-cgi myscript.php arg1=one arg2=two। সমান না হওয়ার জন্য পরীক্ষা apache2handlerকরা ঠিক হবে apache
সেবাস্তিয়ান

3
এই পদ্ধতি সম্পর্কে একটি ছোট সতর্কতা: একটি ক্রোন কাজ থেকে চালানো হলে এটি ফিরে আসবে না"cli"$_SERVERঅনুরোধটি এইচটিটিপি-র মাধ্যমে এসেছে কিনা তা আরও নির্ভরযোগ্যভাবে নির্ধারণ করার জন্য ভিতরে থেকে বেছে নেওয়ার জন্য অনেকগুলি ভিন্ন ভিন্ন কী রয়েছে ।
omninonsense

2
@omninonsense আমি পিএইচপি 7.2.7 দিয়ে পরীক্ষা করেছি এবং এটি ক্লায়েন্ট ফিরে আসে returns
জোসে নোবাইল

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?
বিজিক্লপ

@ বিজিক্লপ, অনুরোধের উত্সarray_key_exists('REQUEST_METHOD', $_SERVER) সনাক্তকরণে সহায়তা করার জন্য চেক করা সঠিক । ইন CLI , সুপার গ্লোবাল অ্যারের হবে না কী আছে , এটি শুধুমাত্র বিদ্যমান যখন অনুরোধ ওয়েবের মাধ্যমে তৈরি হয়, অত: পর, লেখক একেবারে লক্ষ্যে যখন এটি পরীক্ষা করার নেই। $_SERVERREQUEST_METHOD
জুলিও মার্চি

1
@ জুলিওমারচি: তবে এটা করা return false;বা করা উচিত নয় if ( ! array_key_exists(…)) return true;?
বিজিকলপ

2
@ বিজিক্লপ, আপনি পুরোপুরি ঠিক আছেন !!!! আমি কীভাবে এত বড় ছোট ঘটনা মিস করতে পারি ??? নিজের প্রতি লজ্জা... :). নিশ্চয়, যদি চাবিকাঠি 'REQUEST_METHOD'হয় না পাওয়া যায়, তারপর ফাংশন ফেরত পাঠাবেন FALSE"CLI" ইঙ্গিত। ফাংশনটির সুযোগের দিকে মনোযোগ না দেওয়ার জন্য আমার ক্ষমা ... লেখক এটি ঠিক করা উচিত কারণ ফাংশনটি আসলে কাজ করে!
জুলিও মার্চি

এই ফাংশনটি আমার ক্ষেত্রে কাজ করেছিল, পিএইচপি_সাপি_নাম () নয়, যেহেতু আমার ওয়েব অনুরোধ এবং ক্রোনজব মৃত্যুদন্ডের মধ্যে পার্থক্য করা দরকার, এবং পিএইচপি_সাপি_নাম () ফলাফল উভয় ক্ষেত্রেই "পিএইচপি-সিজি" ছিল।
luis.ap.uyen

36

php_sapi_name()এই চেকটি সম্পাদন করার পক্ষে সত্যিই সর্বোত্তম উপায় নয় কারণ এটি অনেকগুলি সম্ভাব্য মানগুলির বিরুদ্ধে পরীক্ষা করার উপর নির্ভর করে। পিএইচপি-সিজি বাইনারি কমান্ড লাইন থেকে, শেল স্ক্রিপ্ট থেকে বা ক্রোন জব হিসাবে ডেকে আনা যেতে পারে এবং (বেশিরভাগ ক্ষেত্রে) এগুলিকে 'ক্লাইও' হিসাবে বিবেচনা করা উচিত তবে php_sapi_name()এগুলির জন্য বিভিন্ন মান ফিরে আসবে (দ্রষ্টব্য যে এই ইসন নয়) পিএইচপি এর সাধারণ সংস্করণে কেস না দিলেও আপনি চান যে আপনার কোডটি যে কোনও জায়গায় কাজ করতে পারে, তাই না?)। পরের বছর পিএইচপি ব্যবহারের নতুন উপায় থাকতে পারে যা আমরা সম্ভবত জানি না mention আমি বরং আমার চিন্তাভাবনা করব না যখন আমার যত্ন করা সমস্ত আবহাওয়া আমার HTML এ আমার আউটপুট গুটিয়ে রাখা উচিত।

ভাগ্যক্রমে, পিএইচপি বিশেষত এটি জন্য একটি উপায় আছে। কেবল http_response_code()কোনও প্যারামিটার ছাড়াই ব্যবহার করুন এবং এটি একটি ওয়েব সার্ভার ধরণের পরিবেশ থেকে চালিত হলে সত্য হবে এবং একটি সিএলআই টাইপ পরিবেশ থেকে চালিত হলে মিথ্যা হবে। কোডটি এখানে:

$is_web=http_response_code()!==FALSE;

এমনকি যদি আপনি দুর্ঘটনাক্রমে (?) সি এল এল থেকে চালিত কোনও স্ক্রিপ্ট থেকে প্রতিক্রিয়া কোড সেট করেন (বা সি এল এলির মতো কিছু) আপনি এটি কল করার আগেও এটি কাজ করবে।


4
আমি যখন উত্তর দিয়েছিলাম তখন এই প্রশ্নটি ইতিমধ্যে পুরানো ছিল। আপ-ভোটিংয়ের এই উত্তরটি সম্ভবত অন্য উত্তর পোস্ট করার চেয়ে বেশি কার্যকর হতে পারে যা ব্যাখ্যা ছাড়াই একটি সদৃশ is
kroe2

"এটি এমনকি যদি আপনি দুর্ঘটনাক্রমে (?) সিএলআই থেকে চালানো কোনও স্ক্রিপ্ট থেকে [[...]) প্রতিক্রিয়া কোড সেট করেন তবে এটি কাজ করবে ([...]) পিএইচপি 7.4.3 হিসাবে, এটি হ'ল সত্য না. http_response_code()সি এল এল থেকে চলার সময় কোড / রিটার্ন সেট কোড সেট করে। দ্বারা যাচাই করা হয়েছে <?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সিএলআই অনুমান করা নিরাপদ বাজি, তবে তা না হলে আপনাকে অন্যান্য মেট্রিকগুলিও পরীক্ষা করতে হবে।
সেবাস্তিয়ান বি।

23

আমি মনে করি তার অর্থ যদি পিএইচপি সিএলআই চালু করা হয় বা যদি এটি কোনও ওয়েব অনুরোধের প্রতিক্রিয়া হয়। সর্বোত্তম php_sapi_name()উপায়টি হ'ল এটি ব্যবহার করা যা এটি যদি কোনও ওয়েব রিকোয়েস্টটি চালাচ্ছিল তবে অ্যাপাচি প্রতিধ্বনিত হবে যদি এটি চলমান ছিল।

পিএইচপি ডক্সphp_sapi_name() থেকে নেওয়া কয়েকজনের তালিকাতে :

  • aolserver
  • Apache
  • apache2filter
  • apache2handler
  • caudium
  • সিজিআই (পিএইচপি 5.3 অবধি)
  • CGI-fcgi
  • CLI
  • ক্লিমে সার্ভার ( পিএইচপি 5.4 হিসাবে অন্তর্নির্মিত ওয়েব সার্ভার )
  • ধারাবাহিকতা
  • বসান
  • FPM-fcgi
  • isapi
  • litespeed
  • পুরুষ মাছ
  • nsapi
  • phttpd
  • pi3web
  • Roxen
  • thttpd
  • Tux
  • webjames

13

এটি সমস্ত ক্ষেত্রে পরিচালনা করতে হবে (পিএইচপি-সিজি সহ)

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 প্রতিক্রিয়া_কোড সরবরাহ করা থাকলে এবং এটি একটি ওয়েব সার্ভারে চালু না হলে সত্য ফিরে আসবে will পরিবেশ (তবে কেবল যখন কোনও পূর্ববর্তী প্রতিক্রিয়া স্থিতি সেট করা হয়নি) "। আপনি আপনার যুক্তি পিছনে পিছনে পেয়েছেন।
kroe2

1
+1 টি। অ্যামেজিং। বহু বছর ধরে নিরর্থক গবেষণার পরে ... আমি আপনাকে এর দ্বারা পিএইচপিফিক্সের নোবেল স্মৃতি পুরস্কার প্রদান করছি, এটি সত্যই কার্যকরভাবে তৈরির অবদানের জন্য @ ক্রোয়ে 2 এর সাথে ভাগ করে নিলাম। অভিনন্দন!
জেড

এটা সম্ভব যে কোনও কিছু প্রতিক্রিয়া কোড সেট করেছে ... http_response_code(200);... আমি যদি এখন ফোন http_response_code()করি তবে এটি 200 ফেরত আসবে;
ব্র্যাড কেন্ট

@ ব্র্যাডক্যান্ট এটি কেবলমাত্র যদি আপনি ওয়েব পরিবেশ থেকে কল করেন এবং সেই ক্ষেত্রে, আপনি যদি স্থিতি কোডটি শূন্যে সেট না করেন ততক্ষণ এই চেকটি এখনও কাজ করে চলেছে (এটি যাইহোক একটি অবৈধ HTTP স্থিতি কোড)। আমার সংস্করণ এমনকি সেই ক্ষেত্রেও কাজ করবে কারণ এটি বিশেষত মিথ্যা বিরুদ্ধে পরীক্ষা করে। যদি http_response_code();কোনও সিএলআই পরিবেশ থেকে ডাকা হয় তবে এটি প্রকৃত স্থিতি কোড নির্বিশেষে সর্বদা মিথ্যা ফিরিয়ে দেয়। আমি ইতিমধ্যে আমার উত্তরে এটি ব্যাখ্যা করেছি তবে আপনি "রিটার্ন মানগুলি" এর অধীনে ম্যানুয়াল পৃষ্ঠাটি পড়ে বা চেষ্টা করে এটি সন্ধান করতে পারতেন।
kroe2

@ ক্রোই 2 আউটপুটস php -r 'http_response_code(200); echo http_response_code()."\n";' "200" আপনি যদি গ্যারান্টি দিতে না পারেন তবে কিছু লাইব্রেরি বা অজ্ঞ কাঠামো প্রতিক্রিয়া কোডটি সেট করে নি http_response_code(এমনকি কোনও ক্লিভ এনভির মধ্যেও), তাহলে এটি কাজ করবে। ব্যক্তিগতভাবে, আমি ব্যবহার করি$isCli = \defined('STDIN') || isset($_SERVER['argv']) || \array_key_exists('REQUEST_METHOD', $_SERVER)
ব্র্যাড কেন্ট

4

আমি এটি ব্যবহার করেছি:

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

এটি ড্রাশ কোডবেস, এনভায়রনমেন্ট.ইনক থেকে যেখানে তাদের অনুরূপ চেক করতে হবে।


4
যদি register_argc_argvসেট করা থাকে, তবে কোনও পরিমাণ জিইটি মান উত্তীর্ণ হওয়ার কারণ argc0 হবে না

3

চেষ্টা

isset($_SERVER['REQUEST_METHOD'])

যদি এটি সেট করা থাকে তবে আপনি একটি ব্রাউজারে রয়েছেন।

পর্যায়ক্রমে, আপনি যদি পরীক্ষা করতে পারেন

isset($_SERVER['argv'])

তবে এটি উইন্ডোজ সিএলআই, আইডিকে-তে সত্য হতে পারে না।


1
যদিও এটি "সঠিক" উত্তর না হলেও এটি আরও নির্ভরযোগ্য হতে পারে
চ্যালেট

2

Http://jp2.php.net/manual/en/features.commandline.php অনুসারে কেবল সিএলআই থেকে চালানোর সময় অনেকগুলি স্থির থাকে। এই ধ্রুবকগুলি হল STDIN, STDOUT এবং STDERR। এর মধ্যে একটির জন্য পরীক্ষা করা আপনাকে বলবে যে এটি ক্লাইম মোডে রয়েছে কিনা



0

আমি check _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

এই প্রশ্নের সঠিক উত্তর এর পিছনে আসল অভিপ্রায় নির্ভর করে:

  • এসএপিআই কি সিদ্ধান্ত নেওয়ার ফ্যাক্টর (ওয়েব-প্রসঙ্গ বা না)?
  • বা তথ্যটি 'টিটিটিতে চলছে' বলে ব্যাখ্যা করা হয়?

যদি পূর্বের দেওয়া উত্তর এবং লিখিত মন্তব্যগুলি কার্যকর হয় তবে একটি সমাধান খুঁজে পেতে যথেষ্ট।

যদি দ্বিতীয়টি হয়, তবে এখানে দেওয়া রেসিপিগুলি যদি সরঞ্জামটি ক্রোনজব হিসাবে চালানো হয়, বা অন্য ডিমন থেকে ব্যাকগ্রাউন্ড-কাজ হিসাবে চালিত হয় - তবে আমি টিটিওয়াই হলে আরও পরীক্ষা করার পরামর্শ দিচ্ছি 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');

সাধারণত ওয়েবসার্ভারগুলি একটি পৃথক ব্যবহারকারীর নামে চালিত হয়, যাতে তা বলা উচিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.