เป็นวิธีที่ยอมรับได้เพื่อกำหนด commandline vs. http การทำงานของสคริปต์ PHP คืออะไร


155

ฉันมีสคริปต์ PHP ที่ต้องการตรวจสอบว่ามีการดำเนินการผ่านทางบรรทัดคำสั่งหรือผ่านทาง HTTP เพื่อวัตถุประสงค์ในการจัดรูปแบบผลลัพธ์เป็นหลัก วิธีที่ยอมรับได้ของการทำเช่นนี้คืออะไร? ฉันคิดว่ามันจะต้องตรวจสอบSERVER['argc']แต่ปรากฎว่าสิ่งนี้มีอยู่แม้ว่าจะใช้ API เซิร์ฟเวอร์ 'Apache 2.0 Handler' ก็ตาม

คำตอบ:


228

ใช้php_sapi_name()ฟังก์ชั่น

if (php_sapi_name() == "cli") {
    // In cli-mode
} else {
    // Not in cli-mode
}

นี่คือบันทึกย่อที่เกี่ยวข้องจากเอกสาร:

php_sapi_name - ส่งคืนประเภทของส่วนต่อประสานระหว่างเว็บเซิร์ฟเวอร์และ PHP

แม้ว่าจะไม่ครบถ้วนสมบูรณ์ค่าส่งคืนที่เป็นไปได้ ได้แก่ aolserver, apache, apache2filter, apache2handler, caudium, cgi (จนถึง PHP 5.3), cgi-fcgi, cli, cli-server, ความต่อเนื่อง, ฝัง, isapi, litespeed, pi3web, roxen, thttpd, tux และ webjames

ใน PHP> = 4.2.0 นอกจากนี้ยังมีค่าคงที่ที่กำหนดไว้ล่วงหน้าที่มีค่าเช่นเดียวกับPHP_SAPIphp_sapi_name()


ขอบคุณ ฉันรู้สึกทึ่งกับสาเหตุที่หมอ ตัวอย่างตรวจสอบอักขระ 3 ตัวแรกในขณะที่คำอธิบายระบุว่าสตริงควรเป็น "cgi" แต่นอกเหนือจากนั้นฉันคิดว่านี่สมบูรณ์แบบ
บ๊อบบี้แจ็ค

เว้นแต่แน่นอนสตริงกลับเป็น 'cgi' ซึ่งยังบ่งบอกถึง php ถูกดำเนินการจากคอนโซล ในขณะที่ whaddayaknow กรณีของฉัน
Adriano Varoli Piazza

@Adriano: บางทีในกรณีของคุณ php-cgi ใช้เพื่อรันสคริปต์

3
@ บ๊อบบี้ตัวอย่างในเอกสาร php.net ตรงกับทั้ง "cgi" และ "cgi-fcgi" เพียงแค่ดูอักขระสามตัวแรกของสตริง ... นั่นเป็นเหตุผลและมันสมเหตุสมผลจริงๆ หากมีสิ่งใดที่เพิ่งได้รับคืน @hop สำหรับการโทร php ไม่มีภาษาสำหรับโปรแกรมเมอร์ที่จริงจัง: D
ChrisR

1
บันทึกที่น่าสนใจที่นี่: php.net/manual/en/function.php-sapi-name.phpขึ้นอยู่กับไบนารีจริงที่เรียกว่าคุณสามารถเรียกใช้ php จากบรรทัดคำสั่งและยังได้รับ cgi-fgi
DAB

22

สิ่งนี้จะได้ผลเสมอ (ถ้ารุ่น PHP เป็น 4.2.0 หรือสูงกว่า)

define('CLI', PHP_SAPI === 'cli');

ซึ่งทำให้ง่ายต่อการใช้งานที่ด้านบนของสคริปต์ของคุณ:

<?php PHP_SAPI === 'cli' or die('not allowed');

8
ตัวอย่างที่สองของคุณดูเหมือนเป็นงานที่ไม่ใช่งานแต่งฉันคาดว่าCLI or die('not allowed');
Madbreaks

1
@ เบรกเกอร์ฉันบอกว่ามีการใช้สองอย่างแยกกัน ฉันถือว่าทั้งสองอย่างใดอย่างหนึ่ง - แต่ถ้าคุณใช้ทั้งสองอย่างนั้นCLI or die('not allowed');สมบูรณ์แบบ
Xeoncross

ขอบคุณสำหรับการชี้แจง +1
Madbreaks

7
Which makes it easy to use at the top of your scriptsไม่ได้ทำให้ฟังดูเหมือนใช้สองอย่างแยกกัน ใช่ฉันเป็นหมอผี
George Dimitriadis


8

ฉันคิด

$_SERVER['REMOTE_ADDR']

จะไม่ถูกบรรจุจาก CLI

นอกจากนี้ปุ่ม HTTP_ * ทั้งหมดใน $ _SERVER superglobal จะไม่ถูกบรรจุจาก CLI หรือทำตามวิธีที่ถูกต้องที่กล่าวถึง :-)


4

หน้าเอกสารสำหรับphp_sapi_name ระบุวิธีการทำงานอย่างชัดเจน:

ส่งคืนสตริงตัวพิมพ์เล็กที่อธิบายถึงประเภทของอินเทอร์เฟซ (Server API, SAPI) ที่ PHP ใช้ ...

แม้ว่าจะไม่ครบถ้วนสมบูรณ์ค่าส่งคืนที่เป็นไปได้ ได้แก่ aolserver, apache, apache2filter, apache2handler, caudium, cgi (จนถึง PHP 5.3), cgi-fcgi, cli, ความต่อเนื่อง, ฝัง, isapi, litespeed, milter, nsapi, phttpd, pi3webx, thttpd, tux และ webjames

ฉันไม่แน่ใจว่าทำไม hop ไม่คิดว่า PHP เหมาะสำหรับโปรแกรมเมอร์ร้ายแรง (ฉันเป็นโปรแกรมเมอร์ที่จริงจังและฉันใช้ PHP ทุกวัน) แต่ถ้าเขาต้องการช่วยชี้แจงเอกสารให้ชัดเจนบางทีเขาสามารถตรวจสอบเว็บเซิร์ฟเวอร์ที่เป็นไปได้ทั้งหมด ที่ PHP สามารถรันและกำหนดชื่อของประเภทอินเตอร์เฟสที่เป็นไปได้ทั้งหมดสำหรับแต่ละเซิร์ฟเวอร์ เพียงตรวจสอบให้แน่ใจว่าได้อัปเดตรายการนั้นเมื่อมีการเพิ่มเว็บเซิร์ฟเวอร์และอินเทอร์เฟซใหม่

นอกจากนี้บ๊อบบี้ก็พูดว่า:

ฉันรู้สึกทึ่งกับสาเหตุที่หมอ ตัวอย่างตรวจสอบอักขระ 3 ตัวแรกในขณะที่คำอธิบายระบุว่าสตริงควรเป็น "CGI" อย่างแน่นอน

คำอธิบายสำหรับตัวอย่างสถานะ:

ตัวอย่างนี้ตรวจสอบ cgi สตริงย่อยเนื่องจากอาจเป็น cgi-fcgi


อ่า - ในวันนั้นฉันไม่ได้สนใจอย่างไม่น่าเชื่อหรือตัวอย่างได้รับการปรับปรุงตั้งแต่ฉันแสดงความคิดเห็นนั้น แม้ว่าสุดใจเห็นด้วยกับคะแนนของคุณเกี่ยวกับ PHP แม้ว่า; การทุบตีทำให้เหนื่อยมาก
Bobby Jack
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.