How to get an associative array from a string? - php

This is the initial string:-
NAME=Marco\nLOCATION=localhost\nSECRET=fjsdgfsjfdskffuv=\n
This is my solution although the "=" in the end of the string does not appear in the array
$env = file_get_contents(base_path() . '/.env');
// Split string on every " " and write into array
$env = preg_split('/\s+/', $env);
//create new array to push data in the foreach
$newArray = array();
foreach($env as $val){
// Split string on every "=" and write into array
$result = preg_split ('/=/', $val);
if($result[0] && $result[1])
{
$newArray[$result[0]] = $result[1];
}
}
print_r($newArray);
This is the result I get:
Array ( [Name] => Marco [LOCATION] => localhost [SECRET] => fjsdgfsjfdskffuv )
But I need :
Array ( [Name] => Marco [LOCATION] => localhost [SECRET] => fjsdgfsjfdskffuv= )

You can use the limit parameter of preg_split to make it only split the string once
http://php.net/manual/en/function.preg-split.php
you should change
$result = preg_split ('/=/', $val);
to
$result = preg_split ('/=/', $val, 2);
Hope this helps

$string = 'NAME=Marco\nLOCATION=localhost\nSECRET=fjsdgfsjfdskffuv=\n';
$strXlate = [ 'NAME=' => '"NAME":"' ,
'LOCATION=' => '","LOCATION":"',
'SECRET=' => '","SECRET":"' ,
'\n' => '' ];
$jsonified = '{'.strtr($string, $strXlate).'"}';
$array = json_decode($jsonified, true);
This is based on 1) translation using strtr(), preparing an array in json format and then using a json_decode which blows it up nicely into an array...
Same result, other approach...

You can also use parse_str to parse URL syntax-like strings to name-value pairs.
Based on your example:
$newArray = [];
$str = file_get_contents(base_path() . '/.env');
$env = explode("\n", $str);
array_walk(
$env,
function ($i) use (&$newArray) {
if (!$i) { return; }
$tmp = [];
parse_str($i, $tmp);
$newArray[] = $tmp;
}
);
var_dump($newArray);
Of course, you need to put some sanity check in the function since it can insert some strange stuff in the array like values with empty string keys, and whatnot.

Related

Turn string back into an array [duplicate]

I have an array:
$a = array('foo' => 'fooMe');
and I do:
print_r($a);
which prints:
Array ( [foo] => printme )
Is there a function, so when doing:
needed_function(' Array ( [foo] => printme )');
I will get the array array('foo' => 'fooMe'); back?
I actually wrote a function that parses a "stringed array" into an actual array. Obviously, it's somewhat hacky and whatnot, but it works on my testcase. Here's a link to a functioning prototype at http://codepad.org/idlXdij3.
I'll post the code inline too, for those people that don't feel like clicking on the link:
<?php
/**
* #author ninetwozero
*/
?>
<?php
//The array we begin with
$start_array = array('foo' => 'bar', 'bar' => 'foo', 'foobar' => 'barfoo');
//Convert the array to a string
$array_string = print_r($start_array, true);
//Get the new array
$end_array = text_to_array($array_string);
//Output the array!
print_r($end_array);
function text_to_array($str) {
//Initialize arrays
$keys = array();
$values = array();
$output = array();
//Is it an array?
if( substr($str, 0, 5) == 'Array' ) {
//Let's parse it (hopefully it won't clash)
$array_contents = substr($str, 7, -2);
$array_contents = str_replace(array('[', ']', '=>'), array('#!#', '#?#', ''), $array_contents);
$array_fields = explode("#!#", $array_contents);
//For each array-field, we need to explode on the delimiters I've set and make it look funny.
for($i = 0; $i < count($array_fields); $i++ ) {
//First run is glitched, so let's pass on that one.
if( $i != 0 ) {
$bits = explode('#?#', $array_fields[$i]);
if( $bits[0] != '' ) $output[$bits[0]] = $bits[1];
}
}
//Return the output.
return $output;
} else {
//Duh, not an array.
echo 'The given parameter is not an array.';
return null;
}
}
?>
If you want to store an array as string, use serialize [docs] and unserialize [docs].
To answer your question: No, there is no built-in function to parse the output of print_r into an array again.
No. But you can use both serialize and json_* functions.
$a = array('foo' => 'fooMe');
echo serialize($a);
$a = unserialize($input);
Or:
echo json_encode($a);
$a = json_decode($input, true);
you cannot do this with print_r,
var_export should allow something similar, but not exactly what you asked for
http://php.net/manual/en/function.var-export.php
$val = var_export($a, true);
print_r($val);
eval('$func_val='.$val.';');
There is a nice Online-Tool which does exatly what its name is:
print_r to json online converter
From a JSON Object its not far to creating an array with the json_decode function:
To get an array from this, set the second paramter to true. If you don't, you will get an object instead.
json_decode($jsondata, true);
I think my function is cool too, works with nested arrays:
function print_r_reverse($input)
{
$output = str_replace(['[', ']'], ["'", "'"], $input);
$output = preg_replace('/=> (?!Array)(.*)$/m', "=> '$1',", $output);
$output = preg_replace('/^\s+\)$/m', "),\n", $output);
$output = rtrim($output, "\n,");
return eval("return $output;");
}
NB: better not use this with user input data
Here is a print_r output parser, producing the same expression in PHP syntax. It is written as an interactive Stack Snippet, so you can use it here:
function parse(s) {
const quote = s => '"' + s.replace(/["\\]/g, '\\$&') + '"';
const compress = indent => " ".repeat(((indent.length + 4) >> 3) * 4);
return "$data = " + (s.replace(/\r\n?/g, "\n") + "\n").replace(
/(Array|\w+ (Object)) *\n *\( *\n|^( *)(?:\[(?:(0|-?[1-9]\d*)|(.*?))\] => |(\) *\n+))|(-?\d+(?:\.\d+)?(?:E[-+]\d+)?)\n|(.*(?:\n(?! *\) *$| *\[.*?\] => ).*)*)\n/gm,
(_, array, object, indent, index, key, close, number, string) =>
object ? "(object) [\n"
: array ? "[\n"
: close ? compress(indent) + "],\n"
: indent ? compress(indent) + (index ?? quote(key)) + " => "
: (number ?? quote(string)) + ",\n"
).replace(/,\n$/, ";");
}
// I/O handling
const [input, output] = document.querySelectorAll("textarea");
(input.oninput = () => output.value = parse(input.value))();
textarea { width: 23em; height: 12em }
<table><tr><th>Input print_r format</th><th>Output PHP syntax</th></tr>
<tr><td><textarea>
Array
(
[0] => example
[1] => stdClass Object
(
[a[] => 1.43E+19
["] => quote
[] =>
)
)
</textarea></td><td><textarea readonly></textarea></td></tr></table>
Remarks
Don't remove any line breaks from the original print_r output. For instance, both the opening and closing parentheses after Array must appear on separate lines.
Don't change the spacing around => (one space before, one after).
As print_r does not distinguish between null, "" or false (it produces no output for these values), nor between true and 1 (both are output as 1), this converter will never produce null, false or true.
As print_r does not distinguish between numbers and strings (9 could represent a number or a string), this converter will assume that the data type is to be numeric when such ambiguity exists.
stdClass Object is supported and translates to (object) [...] notation
MyClass Object will be treated as if it was a stdClass object.
String literals in the output are double quoted and literal double quotes and backslashes are escaped.
Quick function (without checks if you're sending good data):
function textToArray($str)
{
$output = [];
foreach (explode("\n", $str) as $line) {
if (trim($line) == "Array" or trim($line) == "(" or trim($line) == ")") {
continue;
}
preg_match("/\[(.*)\]\ \=\>\ (.*)$/i", $line, $match);
$output[$match[1]] = $match[2];
}
return $output;
}
This is the expected input:
Array
(
[test] => 6
)
This is how I interpreted the question:
function parsePrintedArray($s){
$lines = explode("\n",$s);
$a = array();
foreach ($lines as $line){
if (strpos($line,"=>") === false)
continue;
$parts = explode('=>',$line);
$a[trim($parts[0],'[] ')] = trim($parts[1]);
}
return $a;
}
Works for both objects and arrays:
$foo = array (
'foo' => 'bar',
'cat' => 'dog'
);
$s = print_r($foo,1);
$a = parsePrintedArray($s);
print_r($a);
Output:
Array
(
[foo] => bar
[cat] => dog
)
doesnt work on nested arrays, but simple and fast.
use
var_export(array('Sample array', array('Apple', 'Orange')));
Output:
array (
0 => 'Sample array',
1 =>
array (
0 => 'Apple',
1 => 'Orange',
),
)
json_encode() and json_decode() function will do it.
$asso_arr = Array([779] => 79 => [780] => 80 [782] => 82 [783] => 83);
$to_string = json_encode($asso_arr);
It will be as a json format {"779":"79","780":"80","782":"82","783":"83"}
Then we will convert it into json_decode() then it gives associative array same as original:
print_r(json_decode($to_string));
Output will be Array([779] => 79 => [780] => 80 [782] => 82 [783] => 83) in associative array format.

PHP Array to string

I am getting array from one of my network devices and I don't understand how I can get output array to string.
I get this array:
Array
(
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.1] => STRING: "sensitive_data_1"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.2] => STRING: "sensitive_data_2"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.3] => STRING: "sensitive_data_3"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.4] => STRING: "sensitive_data_4"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.5] => STRING: "sensitive_data_5"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.6] => STRING: "sensitive_data_6"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.7] => STRING: "sensitive_data_7"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.8] => STRING: "sensitive_data_8"
)
And I don't know how can I get only sensitive_data_1-8 to my values.
EDIT: I want output like:
$value[1] = "sensitive_data_1";
$value[2] = "sensitive_data_2";
Use array_map() function then substr() to get the portion of array's string value
$array = array(
// Your array data here
);
$value = array_map(function($e) {
return substr($e, 8);
}, $array);
echo $value[0]; // Outputs "sensitive_data_1"
echo $value[1]; // Outputs "sensitive_data_2"
Simple work around if you want to start with $value[1]
$array = array(
// Your array data here
);
$value = array_map(function($e) {
return substr($e, 8);
}, $array);
array_unshift($value, ''); // Add dummy data
unset($value[0]); // Remove dummy data
echo $value[1]; // Outputs: "sensitive_data_1"
echo $value[2]; // Outputs: "sensitive_data_2"

How to match string to an Array to get the value?

I have an array with corresponding value.
Array
(
[0] => BBsma=200
[1] => SMAperiod=300
[2] => SMA1=400
[3] => SMA2=500
[4] => EMAperiod=300
[5] => EMA1=24
[6] => EMA2=8
)
Now I want to match a certain string like for example BBsma that should return 200. Any help?
Got the array using these codes.
$txt = file_get_contents('INDICATORS.txt');
$rows = explode("\n", $txt);
array_shift($rows);
INDICATORS.txt content
BBperiod=100
BBsma=200
SMAperiod=300
SMA1=400
SMA2=500
EMAperiod=300
EMA1=24
EMA2=8
After you explode your text to the lines use this code:
for($i=0;$i<sizeof($rows);$i++)
{
$temp=explode("=",$rows[$i]);
if(sizeof($temp)==2)
{
$arr[$temp[0]]=$temp[1];
}
}
You will have named array in $arr
if you want to cast second part to int, you just change 6-line to this:
$arr[$temp[0]]=intval($temp[1]);
You could iterate over every line of your array and find the value with a regular match.
Code:
$txt = file_get_contents('INDICATORS.txt');
$rows = explode("\n", $txt);
/*
$rows = [
"BBsma=200",
"SMAperiod=300",
"SMA1=400",
"SMA2=500",
"EMAperiod=300",
"EMA1=24",
"EMA2=8",
];
*/
foreach ($rows as $k=>$v) {
if (preg_match("/(BBsma|SMAperiod|EMAperiod)=([0-9]+)/", $v, $matches)) {
echo "found value " . $matches[2] . " for entry " . $matches[1] . " in line " . $k . PHP_EOL;
}
}
Output:
found value 200 for entry BBsma in line 0
found value 300 for entry SMAperiod in line 1
found value 300 for entry EMAperiod in line 4
You can explode by new line as PHP_EOL like this
$col = "BBsma";
$val = "";
foreach(explode(PHP_EOL,$str) as $row){
$cols = explode("=",$row);
if(trim($cols[0]) == $col){
$val = $cols[1];
break;
}
}
echo "Value $col is : $val";
Live Demo
If your going to use the array a few times, it may be easier to read the file into an associative array in the first place...
$rows = [];
$file = "INDICATORS.txt";
$data = file($file, FILE_IGNORE_NEW_LINES);
foreach ( $data as $item ) {
$row = explode("=", $item);
$rows [$row[0]] = $row[1];
}
echo "EMA1 =".$rows['EMA1'];
This doesn't do the array_shift() but not sure why it's used, but easy to add back in.
This outputs...
EMA1 =24
I think that using array filter answers your question the best. It returns an array of strings with status code 200. If you wanted to have better control later on and sort / search through codes. I would recommend using array_walk to create some sort of multi dimensional array. Either solution will work.
<?php
$arr = [
"BBsma=200",
"SMAperiod=300",
"SMA1=400",
"SMA2=500",
"EMAperiod=300",
"EMA1=24",
"EMA2=8",
];
$filtered = array_filter($arr,"filter");
function filter($element) {
return strpos($element,"=200");
}
var_dump($filtered); // Returns array with all matching =200 codes: BBSMA=200
Output:
array (size=1)
0 => string 'BBsma=200' (length=9)
Should you want to do more I would recommend doing something like this:
///////// WALK The array for better control / manipulation
$walked = [];
array_walk($arr, function($item, $key) use (&$walked) {
list($key,$value) = explode("=", $item);
$walked[$key] = $value;
});
var_dump($walked);
This is going to give you an array with the parameter as the key and status code as it's value. I originally posted array_map but quickly realized array walk was a cleaner solution.
array (size=7)
'BBsma' => string '200' (length=3)
'SMAperiod' => string '300' (length=3)
'SMA1' => string '400' (length=3)
'SMA2' => string '500' (length=3)
'EMAperiod' => string '300' (length=3)
'EMA1' => string '24' (length=2)
'EMA2' => string '8' (length=1)
Working with the array becomes a lot easier this way:
echo $walked['BBsma']; // 200
$anything = array("BBsma"=>"200", "SMAperiod"=>"300", "SMA1"=>"400");
echo "the value is " . $anything['BBsma'];
This will return 200

How to get value from nested array using string

I have an array like this:
$temp = array( '123' => array( '456' => array( '789' => '0' ) ),
'abc' => array( 'def' => array( 'ghi' => 'jkl' ) )
);
I have a string like this:
$address = '123_456_789';
Can I get value of $temp['123']['456']['789'] using above array $temp and string $address?
Is there any way to achieve this and is it good practice to use it?
This is a simple function that accepts an array and a string address where the keys are separated by any defined delimiter. With this approach, we can use a for-loop to iterate to the desired depth of the array, as shown below.
<?php
function delimitArray($array, $address, $delimiter="_") {
$address = explode($delimiter, $address);
$num_args = count($address);
$val = $array;
for ( $i = 0; $i < $num_args; $i++ ) {
// every iteration brings us closer to the truth
$val = $val[$address[$i]];
}
return $val;
}
$temp = array("123"=>array("456"=>array("789"=>"hello world")));
$address = "123_456_789";
echo delimitArray($temp,$address,"_");
?>
Hello if string $address = '123_456_789'; is your case then you can use explode function to split the string by using some delimeter and you can output your value
<?php
$temp = array('123' => array('456' => array('789' => '0')),
'abc' => array('def' => array('ghi' => 'jkl')),
);
$address = '123_456_789';
$addr = explode("_", $address);
echo $temp[$addr[0]][$addr[1]][$addr[2]];
Using this array library you can easily get element value by either converting your string to array of keys using explode:
Arr::get($temp, explode('_', $address))
or replacing _ with . to take advantage of dot notation access
Arr::get($temp, str_replace('_', '.', $address))
Another benefit of using this method is that you can set default fallback value to return if element with given keys does not exists in array.

How to parse a urlencoded query string into an array in PHP (without name changes)

I know what you're thinking. "I can answer this question so quick! It's the parse_str function!" But I've got a little twist for you.
You see, PHP converts the names of all query data into valid PHP variable names. What? Even when they're not being stored as variables? Where is that documented? It isn't.
$payload = 'data.name=value&data.other=value2';
parse_str($payload, $values);
var_export($values);
// Outputs: array('data_name' => 'value', 'data_other' => 'value2')
// Expected: array('data.name' => 'value', 'data.other' => 'value2')
How can I parse a query string without this happening?
You can avoid PHP's renaming of parameter names by parsing the query string yourself. Split the string on & and = characters, and then urldecode() each part:
<?php
$payload = 'data.name=value&data.other=value2';
$values = array();
$nv_strings = explode ('&', $payload);
foreach ($nv_strings as $s) {
$nv = explode ('=', $s, 2);
$name = urldecode ($nv[0]);
$value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
$values[$name] = $value;
}
print_r ($values);
// Array
// (
// [data.name] => value
// [data.other] => value2
// )
If your query string contains duplicate keys, the above code will overwrite the previous keys. This also can be solved:
<?php
$payload = 'key=val1&key=val2&key=val3';
$values = array();
$nv_strings = explode ('&', $payload);
foreach ($nv_strings as $s) {
$nv = explode ('=', $s, 2);
$name = urldecode ($nv[0]);
$value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
$values[] = array ($name => $value);
}
print_r ($values);
// Array
// (
// [0] => Array ([key] => val1)
// [1] => Array ([key] => val2)
// [2] => Array ([key] => val3)
// )
You may want to consolidate the duplicate keys into subarrays:
<?php
$payload = 'key1=val1&key1=val2&key2=val3';
$values = array();
$nv_strings = explode ('&', $payload);
foreach ($nv_strings as $s) {
$nv = explode ('=', $s, 2);
$name = urldecode ($nv[0]);
$value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
if (isset ($values[$name])) {
if (is_array ($values[$name])) {
$values[$name][] = $value;
} else {
$values[$name] = array ($values[$name], $value);
}
} else {
$values[$name] = $value;
}
}
print_r ($values);
// Array
// (
// [key1] => Array ([0] => val1
// [1] => val2)
// [key2] => val3
// )
You can simplify the code somewhat by always using subarrays:
<?php
$payload = 'key1=val1&key1=val2&key2=val3';
$values = array();
$nv_strings = explode ('&', $payload);
foreach ($nv_strings as $s) {
$nv = explode ('=', $s, 2);
$name = urldecode ($nv[0]);
$value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
if (isset ($values[$name])) {
$values[$name][] = $value;
} else {
$values[$name] = array ($value);
}
}
print_r ($values);
// Array
// (
// [key1] => Array ([0] => val1
// [1] => val2)
// [key2] => Array ([0] => val3)
// )
It is documented completely in PHP Documentation for the function parse_str If the output does not work for your particular use case, then you must use another function, or create your own. The key here is that this function parses the string into variables.
parse_str — Parses the string into variables
Parses str as if it were the query string passed via a URL and sets variables in the current scope.
To parse the string you provided, this would work:
$payload = 'data.name=value';
$map = array();
$vals = preg_split('/=/', $payload);
$i= 0;
while($i < count($vals)) {
$map[$vals[$i]] = $vals[++$i];
$i++;
}
var_dump($map);

Categories