Я поддерживаю библиотеку 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' )