Можно ли передать массив в качестве аргумента командной строки в PHP-скрипт?

Я поддерживаю библиотеку PHP, которая отвечает за выборку и хранение входящих данных (POST, GET, аргументы командной строки и т. Д.). Я только что исправил ошибку, которая не позволила бы ей получать переменные массива из POST и GET, и мне интересно, применимо ли это также к части, связанной с командной строкой.

Можете ли вы передать массив в качестве аргумента командной строки для PHP?

Непосредственно нет, все аргументы, переданные в командной строке, являются строками, но вы можете использовать строку запроса как один аргумент для передачи всех переменных с их именами:

php myscript.php a[]=1&a[]=2.2&a[b]=c <?php parse_str($argv[1]); var_dump($a); ?> /* array(3) { [0]=> string(1) "1" [1]=> string(3) "2.2" ["b"]=>string(1) "c" } */ 

Строго говоря, нет. Однако вы можете передать сериализованную версию (используя PHP serialize() и unserialize() или используя json) массив в качестве аргумента, если сценарий десериализует его.

что-то вроде

 php MyScript.php "{'colors':{'red','blue','yellow'},'fruits':{'apple','pear','banana'}}" 

Я не думаю, что это идеально, но я бы предложил вам подумать о другом способе решения любой проблемы, которую вы пытаетесь решить.

Как было сказано, вы можете использовать serialize для передачи массивов и других данных в командной строке.

 shell_exec('php myScript.php '.escapeshellarg(serialize($myArray))); 

И в myScript.php:

 $myArray = unserialize($argv[1]); 

Следующий блок кода будет выполнять передачу массива в виде набора значений, разделенных запятыми:

 <?php $i_array = explode(',',$argv[1]); var_dump($i_array); ?> 

ВЫВОД:

 php ./array_play.php 1,2,3 array(3) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" } 

Вам нужно выяснить какой-то способ кодирования вашего массива в виде строки. Затем вы можете передать эту строку в PHP CLI в качестве аргумента командной строки и затем декодировать эту строку.

Следуя приведенным ниже инструкциям, вы можете сделать такой вызов:

phpcl yourscript.php _GET = '{"key1": "val1", "key2": "val2"}'

Чтобы получить эту работу, вам нужно выполнить код перед вызовом сценария. Я использую оболочку bash в linux и в моем файле .bashrc. Я установил интерфейс командной строки, чтобы сделать флаг php ini auto_prepend_file загруженным файлом начальной загрузки командной строки (этот файл должен быть найден где-то в вашем php_include_path):

 alias phpcl='php -d auto_prepend_file="system/bootstrap/command_line.php"' 

Это означает, что каждый вызов из командной строки будет выполнять этот файл перед запуском сценария, который вы вызываете. auto_prepend_file – отличный способ загрузить систему, я использую ее в своем стандартном php.ini, чтобы установить окончательные исключения и обработчики ошибок на системном уровне. Установка этой командной строки auto_prepend_file переопределяет мой обычный параметр, и я выбираю просто обрабатывать аргументы командной строки, чтобы установить $ _GET или $ _POST. Вот файл, который я добавляю:

 <?php // Parse the variables given to a command line script as Query Strings of JSON. // Variables can be passed as separate arguments or as part of a query string: // _GET='{ "key1": "val1", "key2": "val2" }' foo='"bar"' // OR // _GET='{ "key1": "val1", "key2": "val2" }'\&foo='"bar"' if ($argc > 1) { $parsedArgs = array(); for ($i = 1; $i < $argc; $i++) { parse_str($argv[$i], $parsedArgs[$i]); } foreach ($parsedArgs as $arg) { foreach ($arg as $key => $val) { // Set the global variable of name $key to the json decoded value. $$key = json_decode($val, true); } } unset($parsedArgs); } ?> с <?php // Parse the variables given to a command line script as Query Strings of JSON. // Variables can be passed as separate arguments or as part of a query string: // _GET='{ "key1": "val1", "key2": "val2" }' foo='"bar"' // OR // _GET='{ "key1": "val1", "key2": "val2" }'\&foo='"bar"' if ($argc > 1) { $parsedArgs = array(); for ($i = 1; $i < $argc; $i++) { parse_str($argv[$i], $parsedArgs[$i]); } foreach ($parsedArgs as $arg) { foreach ($arg as $key => $val) { // Set the global variable of name $key to the json decoded value. $$key = json_decode($val, true); } } unset($parsedArgs); } ?> 

Он перебирает все переданные аргументы и задает глобальные переменные с использованием переменных переменных (обратите внимание на $$). На странице руководства говорится, что переменные переменные не работают с суперглобалями, но, похоже, для меня это работает с $ _GET (я предполагаю, что это работает и с POST). Я выбираю передать значения в виде JSON. Возвращаемое значение json_decode будет NULL при ошибке, вы должны сделать проверку ошибок на декоде, если вам это нужно.

В случае, если вы выполняете скрипт командной строки с аргументами через код, лучше всего его закодировать –

 base64_encode(json_encode($arr)); 

при отправке и декодировании при приеме в другом скрипте.

 json_decode(base64_decode($argv[1])); 

Это также решит проблему получения json без кавычек вокруг ключей и значений. Потому что без кавычек это считается плохим json, и вы не сможете его декодировать.

Поэтому, если CLI как таковой

 php path\to\script.php param1=no+array param2[]=is+array param2[]=of+two 

Тогда функция, которая читает это, может быть

 function getArguments($args){ unset($args[0]); //remove the path to script variable $string = implode('&',$args); parse_str($string, $params); return $params; } не function getArguments($args){ unset($args[0]); //remove the path to script variable $string = implode('&',$args); parse_str($string, $params); return $params; } 

Это даст вам

 Array ( [param1] => no array [param2] => Array ( [0] => is array [1] => of two ) ) 

Вроде.

Если вы передадите что-то вроде этого:

 $php script.php --opt1={'element1':'value1','element2':'value2'} 

Вы получите это в аргументе opt1:

 Array( [0] => 'element1:value1' [1] => 'element2:value2' ) 

поэтому вы можете преобразовать это с помощью этого фрагмента:

 foreach($opt1 as $element){ $element = explode(':', $element); $real_opt1[$element[0]] = $element[1]; } 

который превращает его в это:

 Array( [element1] => 'value1' [element2] => 'value2' )