Pass BASH associative arrays to PHP script

2019-07-12 04:45发布

Is it possible to pass BASH associative arrays as argv to PHP scripts?

I have a bash script, that collects some variables to a bash associative array like this. After that, I need to send it to PHP script:

typeset -A DATA
DATA[foo]=$(some_bash_function "param1" "param2")
DATA[bar]=$(some_other_bash_function)

php script.php --data ${DATA[@]}

From PHP script, i need to access the array in following manner:

<?php

    $vars = getopt("",array(
        "data:"
    ));

    $data = $vars['data'];

    foreach ($data as $k=>$v) {
          echo "$k is $v";
    }

?>

What I've tried

Weird syntax around the --data parameter follows advice from a great post about bash arrays from Norbert Kéri how to force passed parameter as an array:

You have no way of signaling to the function that you are passing an array. You get N positional parameters, with no information about the datatypes of each.

However this sollution still does not work for associative arrays - only values are passed to the function. Norbert Kéri made a follow up article about that, however its eval based solution does not work for me, as I need to pass the actual array as a parameter.

Is the thing I'm trying to achieve impossible or is there some way? Thank you!

Update: What I am trying to accomplish

I have a few PHP configuration files of following structure:

<?php
return array(
    'option1' => 'foo',
    'option2' => 'bar'
)

My bash script collects data from user input (through bash read function) and stores them into bash associative array. This array should be later passed as an argument to PHP script.

php script.php --file "config/config.php" --data $BASH_ASSOC_ARRAY

So instead of complicated seds functions etc. I can do simple:

<?php

    $bash_input = getopt('',array('file:,data:'));
    $data = $bash_input['data'];

    $config = require($config_file);
    $config['option1'] = $data['option1'];
    $config['option2'] = $data['option2'];

    // or

    foreach ($data as $k=>$v) {
         $config[$k] = $v;
    }

    // print to config file
    file_put_contents($file, "<?php \n \n return ".var_export($config,true).";");
?>

This is used for configuring Laravel config files

2条回答
男人必须洒脱
2楼-- · 2019-07-12 05:16

Different Approach to @will's

Your bash script:

typeset -A DATA
foo=$(some_bash_function "param1" "param2")
bar=$(some_other_bash_function)

php script.php "{'data': '$foo', 'data2': '$bar'}"

PHP Script

<?php

    $vars = json_decode($argv[1]);

    $data = $vars['data'];

    foreach ($data as $k=>$v) {
          echo "$k is $v";
    }

?>

EDIT (better approach) Credit to @will

typeset -A DATA
DATA[foo]=$(some_bash_function "param1" "param2")
DATA[bar]=$(some_other_bash_function)

php script.php echo -n "{"; for key in ${!DATA[@]}; do echo - "'$key'":"'${DATA[$key]}'", | sed 's/ /,/g' ; done; echo -n "}"
查看更多
放我归山
3楼-- · 2019-07-12 05:28

this does what you want (i think) all in one bash script. You can obviously move the php file out though.

declare -A assoc_array=([key1]=value1 [key2]=value2 [key3]=value3 [key4]=value4)

#These don't come out necesarily ordered
echo ${assoc_array[@]} #echos values
echo ${!assoc_array[@]} #echos keys

echo "" > tmp

for key in ${!assoc_array[@]}
do
echo $key:${assoc_array[$key]} >> tmp   # Use some delimeter here to split the keys from the values
done

cat > file.php << EOF
<?php

    \$fileArray = explode("\n", file_get_contents("tmp"));

    \$data = array();

    foreach(\$fileArray as \$line){
        \$entry = explode(":", \$line);
        \$data[\$entry[0]] = \$entry[1];
    }

    var_dump(\$data);

?>
EOF


php file.php

the escaping is necessary in the cat block annoyingly.

查看更多
登录 后发表回答