2010-05-20 12 views
19

Estoy manteniendo una biblioteca PHP que es responsable de buscar y almacenar datos entrantes (POST, GET, argumentos de línea de comandos, etc.). Acabo de arreglar un error que no le permitiría obtener variables de matriz de POST y GET y me pregunto si esto también es aplicable a la parte que trata con la línea de comando.¿Es posible pasar una matriz como un argumento de línea de comando a una secuencia de comandos PHP?

¿Se puede pasar una matriz como argumento de línea de comando a PHP?

Respuesta

9

Directamente no, todos los argumentos que se pasan en la línea de comandos son cadenas, pero se puede utilizar la cadena de consulta como un argumento para pasar todas las variables con sus nombres:

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" 
} 
*/ 
10

Estrictamente hablando, no. Sin embargo, podría pasar un serializado (ya sea usando el serialize() de PHP unserialize() o utilizando json) como argumento, siempre que el script lo deserialice.

algo así como

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

No creo sin embargo, esto es ideal, me gustaría sugerir que piensa de una manera diferente de hacer frente a cualquier problema que estamos tratando de resolver.

+2

Es 'unserialize()' not 'deserialize()' –

+0

@ dev-null-dweller, gracias - modificado. –

+1

unserialize() es inseguro y, por lo tanto, no debería recomendarse. –

1

Necesita encontrar una forma de codificar su matriz como una cadena. Luego puede pasar esta cadena a PHP CLI como un argumento de línea de comando y luego decodificar esa cadena.

1

Después de seguir el conjunto de instrucciones, usted puede hacer una llamada como esta:

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

para conseguir este funcionamiento que necesita para ejecutar código antes del script siendo llamado. Yo uso un shell bash en Linux y en mi archivo .bashrc puedo configurar la interfaz de línea de comandos para hacer que la bandera auto_prepend_file php ini cargar mi archivo de arranque de línea de comandos (este archivo debe encontrarse en algún lugar de su php_include_path):

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

Esto significa que cada llamada desde la línea de comandos ejecutará este archivo antes de ejecutar el script que usted llama. auto_prepend_file es una gran manera de arrancar tu sistema, lo uso en mi php.ini estándar para configurar mis controladores finales de excepciones y errores a nivel de sistema. Establecer esta línea de comando auto_prepend_file anula mi configuración normal y elijo solo manejar los argumentos de línea de comando para poder establecer $ _GET o $ _POST. Aquí está el archivo que he Prefijo:

<?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); 
} 
?> 

Se recorre todos los argumentos pasados ​​y establece las variables globales utilizando variable variables (nótese el $$). La página de manual dice que las variables variables no funcionan con superglobales, pero parece funcionar para mí con $ _GET (supongo que también funciona con POST). Elijo pasar los valores en JSON. El valor de retorno de json_decode será NULL en caso de error, debe hacer una comprobación de errores en la decodificación si la necesita.

6

Como se dijo, puede usar serializar para pasar matrices y otros datos a la línea de comandos.

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

Y en myScript.php:

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

Así que si una CLI es como tal

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

Entonces el eso es función lee esto puede ser

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

Esto le daría

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

El El siguiente bloque de código lo hará pasando la matriz a es un conjunto de valores separados por comas:

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

SALIDA:

php ./array_play.php 1,2,3 

array(3) { 
    [0]=> 
    string(1) "1" 
    [1]=> 
    string(1) "2" 
    [2]=> 
    string(1) "3" 
} 
0

Ordenar de.

Si pasa algo como esto:

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

recibe este en el argumento opt1:

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

lo que puede convertir que el uso de este fragmento:

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

cuales lo convierte en esto:

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

Esto no funcionará bien si un valor tiene dos puntos (':') en él. –

1

En el caso, si se está ejecutando la escritura de línea de comandos con argumentos a través de código a continuación, lo mejor es a base de codificarlo -

base64_encode(json_encode($arr)); 

al enviar y decodificarlo mientras se recibe en otro script.

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

Eso también va a resolver el problema de la recepción de JSON sin comillas en torno a las claves y valores. Porque sin comillas, se considera como bad json y no podrá decodificar eso.

Cuestiones relacionadas