ฉันต้องการตรวจสอบว่าการร้องขอปัจจุบันของ PHP มาจาก command line (CLI) หรือจากเว็บเซิร์ฟเวอร์ (ในกรณีของฉัน Apache กับ mod_php)
มีวิธีแนะนำไหม?
ฉันต้องการตรวจสอบว่าการร้องขอปัจจุบันของ PHP มาจาก command line (CLI) หรือจากเว็บเซิร์ฟเวอร์ (ในกรณีของฉัน Apache กับ mod_php)
มีวิธีแนะนำไหม?
คำตอบ:
php_sapi_name
เป็นฟังก์ชั่นที่คุณจะต้องการใช้เพราะมันจะคืนค่าสตริงตัวพิมพ์เล็กของประเภทอินเตอร์เฟส PHP_SAPI
นอกจากนี้ยังมีเป็นค่าคงที่ของ PHP
เอกสารสามารถพบได้ที่นี่: http://php.net/php_sapi_name
ตัวอย่างเช่นเพื่อตรวจสอบว่า PHP กำลังถูกเรียกใช้จาก CLI หรือไม่คุณสามารถใช้ฟังก์ชันนี้:
function isCommandLineInterface()
{
return (php_sapi_name() === 'cli');
}
return php_sapi_name() == 'cli';
php-cgi
สิ่งนี้จะไม่ทำงาน ในทางกลับกันมันจะส่งกลับcgi-fcgi
สตริง apache2handler
ถ้าคุณโหลดสคริปต์ที่เป็นหน้าเว็บเบราว์เซอร์ที่คุณจะได้รับ หวังว่านี่จะช่วยได้ ฉันต้องใช้php-cgi
เพื่อแนะนำ$_GET
ตัวแปร: php-cgi myscript.php arg1=one arg2=two
. การทดสอบที่ไม่เท่ากับapache2handler
ควรจะเป็นapache
เช่นนั้น
"cli"
เมื่อทำงานจากงาน cron มีปุ่มตัวเลขที่แตกต่างกันให้เลือกจากด้านในของ$_SERVER
เพื่อกำหนดความน่าเชื่อถือมากขึ้นว่าคำขอมาทาง HTTP หรือไม่
ฉันใช้ฟังก์ชั่นนี้มาหลายปีแล้ว
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;
วัด?
array_key_exists('REQUEST_METHOD', $_SERVER)
ที่ถูกต้องที่จะช่วยให้การตรวจสอบของแหล่งที่มาของการร้องขอ เมื่ออยู่ในCLIที่$_SERVER
อาร์เรย์ซูเปอร์ทั่วโลกจะไม่ได้มีกุญแจสำคัญREQUEST_METHOD
ก็เกิดขึ้นเมื่อมีการยื่นคำขอผ่านทางเว็บดังนั้นผู้เขียนเป็นอย่างในเป้าหมายเมื่อตรวจสอบมัน
return false;
ทำif ( ! array_key_exists(…)) return true;
หรือไม่?
'REQUEST_METHOD'
จะไม่พบแล้วฟังก์ชั่นควรกลับFALSE
เพื่อบ่งชี้ถึง "CLI" ฉันขอโทษที่ไม่สนใจขอบเขตของฟังก์ชั่นเอง ... ผู้เขียนควรแก้ไขเพราะฟังก์ชั่นใช้งานได้จริง!
php_sapi_name()
ไม่ใช่วิธีที่ดีที่สุดในการตรวจสอบนี้เนื่องจากขึ้นอยู่กับการตรวจสอบกับค่าที่เป็นไปได้มากมาย php-cgi binary สามารถเรียกได้จากบรรทัดคำสั่งจากเชลล์สคริปต์หรือเป็นงาน cron และ (ในกรณีส่วนใหญ่) สิ่งเหล่านี้ควรได้รับการปฏิบัติเช่น 'cli' แต่php_sapi_name()
จะส่งกลับค่าที่แตกต่างกันสำหรับสิ่งเหล่านี้ กรณีนี้เป็นรุ่นธรรมดาของ PHP แต่คุณต้องการให้โค้ดของคุณทำงานได้ทุกที่ใช่ไหม?) ไม่ต้องพูดถึงว่าปีหน้าอาจมีวิธีใหม่ในการใช้ PHP ที่เราอาจไม่รู้ตอนนี้ ฉันไม่คิดว่าเมื่อฉันสนใจคือสภาพอากาศที่ฉันควรห่อออกของฉันใน HTML หรือไม่
โชคดีที่ PHP มีวิธีตรวจสอบสิ่งนี้โดยเฉพาะ เพียงใช้http_response_code()
โดยไม่มีพารามิเตอร์ใด ๆ และมันจะคืนค่า TRUE หากทำงานจากสภาพแวดล้อมประเภทเว็บเซิร์ฟเวอร์และเป็น FALSE หากเรียกใช้จากสภาพแวดล้อมประเภท CLI นี่คือรหัส:
$is_web=http_response_code()!==FALSE;
สิ่งนี้จะใช้งานได้หากคุณตั้งใจ (?) ตั้งรหัสตอบกลับจากสคริปต์ที่เรียกใช้จาก CLI (หรือบางอย่างเช่น CLI) ก่อนที่คุณจะเรียกสิ่งนี้
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 แต่ถ้าไม่คุณต้องตรวจสอบตัวชี้วัดอื่น ๆ ด้วย
ฉันคิดว่าเขาหมายถึงว่ามีการเรียกใช้ PHP CLI หรือไม่หรือเป็นการตอบสนองจากคำขอทางเว็บ วิธีที่ดีที่สุดคือการใช้php_sapi_name()
ซึ่งหากมีการเรียกใช้คำขอเว็บจะสะท้อน Apache ถ้านั่นคือสิ่งที่มันกำลังทำงาน
ในการแสดงรายการบางส่วนที่มาจาก php docs เมื่อphp_sapi_name()
:
สิ่งนี้ควรจัดการกับทุกกรณี (รวมถึง php-cgi)
return (php_sapi_name() === 'cli' OR defined('STDIN'));
function is_cli() {
return !http_response_code();
}
ตัวอย่าง:
if (is_cli()) {
echo 'command line';
} else {
echo 'browser';
}
http_response_code(200);
... ถ้าฉันเรียกhttp_response_code()
มันว่าจะคืนค่า 200;
http_response_code();
ถูกเรียกจากสภาพแวดล้อม CLI จะส่งคืน FALSE เสมอไม่ว่ารหัสสถานะจริง ฉันได้อธิบายเรื่องนี้ไว้ในคำตอบแล้ว แต่คุณสามารถค้นพบสิ่งนี้ได้โดยอ่านหน้าคู่มือภายใต้ "คืนค่า" หรือโดยลองดู
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)
ฉันใช้สิ่งนี้:
php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)
นี่คือจาก Drush codebase, environment.inc ที่พวกเขามีการตรวจสอบที่คล้ายกันเพื่อให้
ลอง
isset($_SERVER['REQUEST_METHOD'])
หากตั้งไว้แสดงว่าคุณอยู่ในเบราว์เซอร์
อีกวิธีหนึ่งคือคุณสามารถตรวจสอบว่า
isset($_SERVER['argv'])
แต่นั่นอาจไม่เป็นความจริงบน windows CLI, IDK
ตามhttp://jp2.php.net/manual/en/features.commandline.phpมีค่าคงที่จำนวนหนึ่งที่ตั้งค่าเฉพาะเมื่อเรียกใช้จาก CLI เท่านั้น ค่าคงที่เหล่านี้คือ STDIN, STDOUT และ STDERR การทดสอบหนึ่งในนั้นจะบอกคุณว่ามันอยู่ในโหมด cli
วิธี Joomla
if (array_key_exists('REQUEST_METHOD', $_SERVER)) die();
วิธีที่ฉันชอบ:
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
}
วิธีที่ง่ายคือการซักถาม$argv
ตัวแปร (ซึ่งคุณอาจทำกับพารามิเตอร์บรรทัดคำสั่งอยู่ดี) แม้ว่าจะไม่มีพารามิเตอร์$argv
ส่งคืนอาเรย์ที่ว่างเปล่า
หากมีการตั้งค่าก็ใช้ cli จากนั้นคุณสามารถสมมติว่าการเรียกใช้อื่น ๆ ทั้งหมดมาจากเว็บเซิร์ฟเวอร์หรืออื่น ๆ
เช่น:
if (isset($argv)) {
// Do the cli thing.
}
จากคำตอบของ Silver Moon ข้างต้นฉันใช้ฟังก์ชันนี้เพื่อคืนการกระจายบรรทัดที่ถูกต้อง:
/**
* 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>";
}
คำตอบที่ถูกต้องสำหรับคำถามนี้ขึ้นอยู่กับเจตนาที่แท้จริงที่อยู่เบื้องหลัง:
หากอดีตคำตอบที่ได้รับและความคิดเห็นที่เขียนนั้นเพียงพอที่จะหาทางออกที่ได้ผล
ถ้าอย่างหลังสูตรที่ให้ที่นี่จะล้มเหลวหากเครื่องมือทำงานเป็น cronjob หรือเป็นแบ็คกราวน์จาก daemon อื่น - ในกรณีนี้ฉันขอแนะนำให้ทดสอบเพิ่มเติมหากSTDIN
เป็น TTY:
function at_tty() {
return defined("\STDIN") && posix_isatty(\STDIN);
}
วิธีแก้ปัญหาที่ซับซ้อนมากมาย เกี่ยวกับ ...
if($_SERVER['REQUEST_SCHEME']=="http" or $_SERVER['REQUEST_SCHEME']=="https"){
// must be browser :)
}
ฉันจะลอง:
echo exec('whoami');
โดยทั่วไปแล้วเว็บเซิร์ฟเวอร์จะทำงานภายใต้ชื่อผู้ใช้อื่นดังนั้นควรแจ้งให้ทราบ