Cách chính tắc để xác định dòng lệnh so với thực thi http của tập lệnh PHP là gì?


155

Tôi có một tập lệnh PHP cần xác định xem nó đã được thực thi thông qua dòng lệnh hay qua HTTP, chủ yếu cho các mục đích định dạng đầu ra. Cách thức kinh điển để làm điều này là gì? Tôi đã nghĩ rằng đó là để kiểm tra SERVER['argc'], nhưng hóa ra điều này là phổ biến, ngay cả khi sử dụng API máy chủ 'Apache 2.0 Handler'.

Câu trả lời:


228

Sử dụng php_sapi_name()chức năng.

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

Dưới đây là một số lưu ý liên quan từ các tài liệu:

php_sapi_name - Trả về loại giao diện giữa máy chủ web và PHP

Mặc dù không đầy đủ, các giá trị trả về có thể bao gồm aolserver, apache, apache2filter, apache2handler, caudium, cgi (cho đến PHP 5.3), cgi-fcgi, cli, cli-server, continuity, embed, isapi, litespeed, milter, pi3web, roxen, thttpd, tux và webjames.

Trong PHP> = 4.2.0, cũng có một hằng số được xác định trước PHP_SAPI, có cùng giá trị như php_sapi_name().


Cảm ơn. Tôi tò mò về lý do tại sao các tài liệu. Ví dụ kiểm tra 3 ký tự đầu tiên, trong khi mô tả cho biết chuỗi phải chính xác là "cgi", nhưng, ngoài điều đó, tôi nghĩ rằng điều này là hoàn hảo.
Bobby Jack

tất nhiên trừ khi chuỗi trả về là 'cgi', đây cũng là dấu hiệu cho thấy php được thực thi từ bàn điều khiển. Như trong, whaddayaknow, trường hợp của tôi.
Quảng trường Adriano Varoli

@Adriano: có thể trong trường hợp của bạn, php-cgi được sử dụng để thực thi tập lệnh.

3
@Bulk, ví dụ trong tài liệu php.net thực sự khớp với cả "cgi" và "cgi-fcgi" bằng cách chỉ nhìn vào ba ký tự đầu tiên của chuỗi ... đó là lý do tại sao và nó thực sự có ý nghĩa. Nếu có bất cứ điều gì, chỉ cần quay lại @hop để gọi php không có ngôn ngữ cho các lập trình viên nghiêm túc: D
ChrisR

1
một lưu ý thú vị ở đây: php.net/manual/en/feft.php-sapi-name.php là tùy thuộc vào nhị phân thực tế được gọi, bạn có thể chạy php từ dòng lệnh và vẫn nhận được cgi-fgi
DAB

22

Điều này sẽ luôn luôn làm việc. (Nếu phiên bản PHP là 4.2.0 trở lên)

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

Điều này làm cho nó dễ sử dụng ở đầu tập lệnh của bạn:

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

8
Đoạn mã thứ hai của bạn có vẻ như không phải là một trình tự, tôi mong đợiCLI or die('not allowed');
Madbreaks

1
@Madbreaks, tôi đã nêu hai cách sử dụng riêng biệt. Tôi đã giả định một trong hai cái này hay cái khác - nhưng nếu bạn sử dụng cả hai sau đó CLI or die('not allowed');là hoàn hảo.
Xeoncross

Cảm ơn đã làm rõ, +1
Madbreaks

7
Which makes it easy to use at the top of your scriptskhông thực sự làm cho nó nghe giống như hai cách sử dụng riêng biệt. Vâng, tôi là một thầy chiêu hồn.
George Dimitriadis

9

Đây là triển khai Drupal 7: drupal_is_cli () :

function drupal_is_cli() {
  return (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)));
}

Tuy nhiên, Drupal 8 khuyên bạn nên sử dụngPHP_SAPI === 'cli'


8

tôi nghĩ

$_SERVER['REMOTE_ADDR']

sẽ không được điền từ CLI.

Ngoài ra, tất cả các khóa HTTP_ * trong siêu lớp $ _SERVER sẽ không được nhập từ CLI hoặc thực hiện đúng cách mà hop vừa đề cập :-)


4

Trang tài liệu cho php_sapi_name nêu rõ cách thức hoạt động của nó:

Trả về một chuỗi chữ thường mô tả loại giao diện (API máy chủ, SAPI) mà PHP đang sử dụng ....

Mặc dù không đầy đủ, các giá trị trả về có thể bao gồm aolserver, apache, apache2filter, apache2handler, caudium, cgi (cho đến PHP 5.3), cgi-fcgi, cli, continuity, embed, isapi, litespeed, milter, nsapi, thoggd, tux và webjames.

Tôi không chắc tại sao hop không nghĩ rằng PHP dành cho các lập trình viên nghiêm túc (Tôi là một lập trình viên nghiêm túc và tôi sử dụng PHP hàng ngày), nhưng nếu anh ta muốn giúp làm rõ tài liệu thì có lẽ anh ta có thể kiểm toán tất cả các máy chủ web có thể PHP có thể chạy và xác định tên của tất cả các loại giao diện có thể có cho mỗi máy chủ. Chỉ cần đảm bảo giữ cho danh sách đó được cập nhật khi các máy chủ và giao diện web mới được thêm vào.

Ngoài ra, Bobby nói:

Tôi tò mò về lý do tại sao các tài liệu. ví dụ kiểm tra 3 ký tự đầu tiên, trong khi mô tả cho biết chuỗi phải chính xác là "CGI"

Mô tả cho ví dụ nêu:

Ví dụ này kiểm tra cgi chuỗi con vì nó cũng có thể là cgi-fcgi.


À - hoặc là tôi cực kỳ không quan tâm ngày hôm đó, hoặc ví dụ đã được cập nhật kể từ khi tôi đưa ra nhận xét đó. Mặc dù hoàn toàn đồng ý với quan điểm của bạn về PHP; bashing được RẤT mệt mỏi.
Bobby Jack
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.