PHP vượt qua $ _GET trong dấu nhắc lệnh linux


125

Nói rằng chúng tôi thường truy cập thông qua

http://localhost/index.php?a=1&b=2&c=3

Làm thế nào để chúng ta thực hiện tương tự trong dấu nhắc lệnh linux?

php -e index.php

Nhưng những gì về việc vượt qua các biến $ _GET? Có lẽ một cái gì đó như php -e index.php --a 1 --b 2 --c 3? Nghi ngờ rằng sẽ làm việc.

Cảm ơn bạn!

Câu trả lời:


122

Thông thường, để truyền đối số cho tập lệnh dòng lệnh, bạn sẽ sử dụng argvbiến toàn cục hoặc getopt :

// bash command:
//   php -e myscript.php hello
echo $argv[1]; // prints hello

// bash command:
//   php -e myscript.php -f=world
$opts = getopt('f:');
echo $opts['f']; // prints world

$ _GET đề cập đến các tham số phương thức HTTP GET, không có sẵn trong dòng lệnh, vì chúng yêu cầu một máy chủ web để cư trú.

Nếu bạn thực sự muốn cư trú $ _GET, bạn có thể làm điều này:

// bash command:
//   export QUERY_STRING="var=value&arg=value" ; php -e myscript.php
parse_str($_SERVER['QUERY_STRING'], $_GET);
print_r($_GET);
/* outputs:
     Array(
        [var] => value
        [arg] => value
     )
*/

Bạn cũng có thể thực thi một tập lệnh đã cho, điền $_GETtừ dòng lệnh mà không phải sửa đổi tập lệnh đã nói:

export QUERY_STRING="var=value&arg=value" ; \
php -e -r 'parse_str($_SERVER["QUERY_STRING"], $_GET); include "index.php";'

Lưu ý rằng bạn có thể làm tương tự với $_POST$_COOKIElà tốt.


1
Điều đáng chú ý là, trên máy Centos 6 của chúng tôi chạy PHP 5.3, cuộc gọi php [script name] "a=1&b=2&c=3"sẽ không được thực hiện $_SERVER['QUERY_STRING'], nhưng bạn có thể dễ dàng ảnh hưởng đến điều tương tự bằng cách tham khảo $_SERVER['argv'][1].
Eric L.

4
Hãy thử câu trả lời này để điền chuỗi truy vấn từ dòng lệnh mà không sửa đổi tập lệnh PHP.
qris

Đây không phải là câu trả lời tốt nhất. Xem câu trả lời khác trên trang này: stackoverflow.com/a/11965479/543738
LS

Câu trả lời hữu ích, mặc dù nếu như tôi đang tự hỏi những dấu hai chấm đó là gì sau tên đối số getopt(), thì điều này rõ ràng cho PHP biết bạn muốn đối số f chứ không phải tùy chọn f (sẽ được chỉ định trừ dấu hai chấm). Vì vậy, nó chỉ là cú pháp.
Mitya

Tôi thực sự thích câu trả lời cuối cùng, và tôi đã sử dụng nó ngày hôm qua. Nó có thể được biến thành một kịch bản, quá.
Revierpost

239

Từ câu trả lời này trên ServerFault :

Sử dụng php-cginhị phân thay vì chỉ phpvà truyền các đối số trên dòng lệnh, như thế này:

php-cgi -f index.php left=1058 right=1067 class=A language=English

Điều này đặt điều này vào $_GET:

Array
(
    [left] => 1058
    [right] => 1067
    [class] => A
    [language] => English
)

Bạn cũng có thể đặt các biến môi trường sẽ được đặt bởi máy chủ web, như thế này:

REQUEST_URI='/index.php' SCRIPT_NAME='/index.php' php-cgi -f index.php left=1058 right=1067 class=A language=English

10
+1 và +1: Câu trả lời này phải là câu trả lời được chấp nhận. Ít rắc rối hơn nhiều! Không cần thay đổi nguồn php.
micha

2
Tuyệt vời, điều này có thể dễ dàng gói gọn trong bất kỳ tập lệnh phụ thuộc hệ điều hành nào.
Sebastian

2
+1, giải pháp tuyệt vời, tôi đang backporting tất cả các kịch bản CLI của tôi để hỗ trợ này ngay bây giờ;)
Ehime

Nhược điểm duy nhất tôi thấy cho đến nay là đầu ra của thiết bị đầu cuối là HTML với <br /> thay vì chỉ \ n. Điều này áp dụng cho tất cả các thông báo và các lỗi là tốt, ví dụ<b>Notice</b>: Undefined index: testing in <b> ... </b><br />
bafromca

+1 Tuyệt vời, Điều này hoạt động trong Tập lệnh bình thường $ _GET Giá trị cho Ex như: php-cgi -f /var/www/vhosts/example.com/public_html/index.php action=DoSomething Hoạt động tốt ..
Ajmal Praveen

16

Tôi không có tệp nhị phân php-cgi trên Ubuntu, vì vậy tôi đã làm điều này:

% bí danh php-cgi = "php -r '"' parse_str (implode ("&", mảng_slice ($ argv, 2)), $ _GET); bao gồm ($ argv [1]); '"' -"
% php-cgi test1.php foo = 123
<html>
Bạn đặt foo thành 123.
</ html>

% mèo test1.php
<html> Bạn đặt foo thành <? php in $ _GET ['foo']?>. </ html>

Trông giống như một cách php để sửa chữa nhân viên.
FelikZ

14

Đôi khi, bạn không có tùy chọn chỉnh sửa tệp php để đặt $ _GET thành các tham số được truyền vào và đôi khi bạn không thể hoặc không muốn cài đặt php-cgi.

Tôi thấy đây là giải pháp tốt nhất cho trường hợp đó:

php -r '$_GET["key"]="value"; require_once("script.php");' 

Điều này tránh thay đổi tệp php của bạn và cho phép bạn sử dụng lệnh php đơn giản. Nếu bạn đã cài đặt php-cgi, bằng mọi cách hãy sử dụng nó, nhưng đây là điều tốt nhất tiếp theo. Nghĩ rằng lựa chọn này là xứng đáng được đề cập

-r có nghĩa là chạy mã php trong chuỗi sau đây. bạn đặt giá trị $ _GET theo cách thủ công ở đó, rồi tham chiếu tệp bạn muốn chạy.

Cần lưu ý rằng bạn nên chạy tệp này trong thư mục bên phải, thường xuyên nhưng không phải lúc nào cũng là thư mục chứa tệp php. Yêu cầu các câu lệnh sẽ sử dụng vị trí lệnh của bạn để giải quyết các url tương đối, KHÔNG phải vị trí của tệp


1
Tôi muốn cảm ơn bạn cho giải pháp này. Theo ý kiến ​​của tôi đây nên là câu trả lời được chấp nhận. Bạn không phải cài đặt thêm một thư viện để sử dụng nó.
kiếm thuật

Đây là cách tốt hơn so với câu trả lời được chấp nhận. Upvote cho bạn!
faraday703

giải pháp tuyệt vời và dễ dàng!
derRobert

Câu trả lời tuyệt vời. Bạn chỉ thiếu một trích dẫn kết thúc trong mã của bạn :)
Pedro Araujo Jorge

10
php file_name.php var1 var2 varN

Sau đó, đặt các $_GETbiến của bạn trên dòng đầu tiên của bạn trong PHP, mặc dù đây không phải là cách mong muốn để đặt $_GETbiến và bạn có thể gặp sự cố tùy thuộc vào những gì bạn làm sau đó với biến đó.

if (isset($argv[1])) {
   $_GET['variable_name'] = $argv[1];
}

các biến bạn khởi chạy tập lệnh sẽ có thể truy cập được từ $argvmảng trong ứng dụng PHP của bạn. mục nhập đầu tiên sẽ là tên của tập lệnh mà chúng xuất phát, vì vậy bạn có thể muốn thực hiện array_shift($argv)bỏ mục nhập đầu tiên đó nếu bạn muốn xử lý một loạt các biến. Hoặc chỉ cần tải vào một biến cục bộ.


giải pháp đơn giản và đơn giản nhất
João Pimentel Ferreira

9

Hãy thử sử dụng WGET:

WGET 'http://localhost/index.php?a=1&b=2&c=3'

1
Bạn muốn gửi URL trong dấu ngoặc đơn, như là? và & trong phần truy vấn là các siêu ký tự shell (ký tự đại diện char đơn + "chạy lệnh này trong nền").
Marc B

7
Điều này sẽ hoạt động, nhưng yêu cầu một máy chủ web đang chạy và làm cho toàn bộ quá trình không hiệu quả hơn một chút so với yêu cầu.
Brad

Nó có, nhưng thường $_GETngụ ý một máy chủ web đang chạy.
quickshiftin

6

- Tùy chọn 1: php-cgi -

Sử dụng 'php-cgi' thay cho 'php' để chạy tập lệnh của bạn. Đây là cách đơn giản nhất vì bạn sẽ không cần phải sửa đổi đặc biệt mã php của mình để làm việc với nó:

php-cgi -f /my/script/file.php a=1 b=2 c=3

- Tùy chọn 2: nếu bạn có máy chủ web -

Nếu tệp php nằm trên máy chủ web, bạn có thể sử dụng 'wget' trên dòng lệnh:

wget 'http://localhost/my/script/file.php?a=1&b=2&c=3'

HOẶC LÀ:

wget -q -O - "http://localhost/my/script/file.php?a=1&b=2&c=3"

- Truy cập các biến trong php -

Trong cả hai tùy chọn 1 & 2, bạn truy cập các tham số như thế này:

$a = $_GET["a"];
$b = $_GET["b"];
$c = $_GET["c"];

2

Nếu bạn cần phải vượt qua $_GET, $_REQUEST, $_POST, hoặc bất cứ điều gì khác mà bạn cũng có thể sử dụng chế độ tương tác PHP:

php -a

Sau đó gõ:

<?php
$_GET['a']=1;
$_POST['b']=2;
include("/somefolder/some_file_path.php");

Điều này sẽ tự đặt bất kỳ biến nào bạn muốn và sau đó chạy tệp php của bạn với các biến đó được đặt.


1

Nếu bạn có khả năng chỉnh sửa tập lệnh PHP, bạn có thể điền vào mảng $ _GET một cách giả tạo bằng cách sử dụng đoạn mã sau ở đầu tập lệnh và sau đó gọi tập lệnh với cú pháp: php -f script.php name1=value1 name2=value2

// When invoking the script via CLI like "php -f script.php name1=value1 name2=value2", this code will populate $_GET variables called "name1" and "name2", so a script designed to be called by a web server will work even when called by CLI
if (php_sapi_name() == "cli") {
    for ($c = 1; $c < $argc; $c++) {
        $param = explode("=", $argv[$c], 2);
        $_GET[$param[0]] = $param[1]; // $_GET['name1'] = 'value1'
    }
}

1

Tại dòng lệnh dán như sau

export QUERY_STRING="param1=abc&param2=xyz" ;  
POST_STRING="name=John&lastname=Doe" ; php -e -r 
'parse_str($_SERVER["QUERY_STRING"], $_GET); parse_str($_SERVER["POST_STRING"], 
$_POST);  include "index.php";'

0

Tôi chỉ vượt qua họ như thế này:

php5 script.php param1=blabla param2=yadayada

chỉ hoạt động tốt, mảng $ _GET là:

array(3) {
  ["script_php"]=>
  string(0) ""
  ["param1"]=>
  string(6) "blabla"
  ["param2"]=>
  string(8) "yadayada"
}

chỉ phát hiện ra điều này hoạt động trên máy chủ lưu trữ của tôi, nhưng không phải trên máy chủ cục bộ của tôi, kỳ quái.
Asaf

Có lẽ một sự khác biệt trong phiên bản cài đặt? Phiên bản nào đã làm việc này cho bạn và phiên bản nào đã thất bại?
Kzqai

php 5.2 về lưu trữ, hoạt động, 5.3 cục bộ không ... không quan trọng tôi đã làm theo cách $ argv chỉ trong trường hợp $ _GET trống
Asaf

-1

php -r 'parse_str($argv[2],$_GET);include $argv[1];' index.php 'a=1&b=2'

Bạn có thể tạo phần đầu tiên dưới dạng bí danh:

alias php-get='php -r '\''parse_str($argv[2],$_GET);include $argv[1];'\'

sau đó chỉ cần sử dụng:

php-get some_script.php 'a=1&b=2&c=3'


-2

hoặc chỉ (nếu bạn có LYNX):

lynx 'http://localhost/index.php?a=1&b=2&c=3'

3
Điều này không chạy PHP từ dòng lệnh. Điều này chạy một trình duyệt gọi máy chủ web thông qua dòng lệnh.
Andrea Lazzarotto
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.