PHP string to nested / multidimensional array - php

I have this example php string:
$string = "#[item_1][door] #[mozart][grass] = yes #[mozart][green] = no #[mozart][human] #[blue][movie]=yes #[item_1][beat] = yes #[item_1][music] = no
";
now $string idented just to easy view:
#[item_1][door]
#[mozart][grass] = yes
#[mozart][green] = no
#[mozart][human]
#[blue][movie]=yes
#[item_1][beat] = yes
#[item_1][music] = no
I want to know how can i get this string ( or other string following this style ) and transform in an array that looks like:
Array
(
[item_1] => Array
(
[door] => Array
(
[mozart] => Array
(
[grass] => yes
[green] => no
[human] => Array
(
[blue] => Array
(
[movie] => yes
)
)
)
)
[beat] => yes
[music] => no
)
)
What i tried
I tried to use and recursive function to create an nested array but i can't have access to the array pointer ( in deep levels ) in recursive functions.. don't know why.. maybe is the wrong patch to the answer.
thank you,

OK, I hope you still need this, because I wasted more time than I'd like to admin getting this right :)
Basically, my approach was to first manipulate the string into the format [set][of][keys]=value, and then loop through the string of keys and comparing them with the last set of keys to create the correct key hierarchy. I used eval because it's easier, but you can write a replacement function if you can't stomach seeing that function in your code:
//FIRST WE GET THE STRING INTO EASIER TO WORK WITH CHUNKS
$original_string = "#[item_1][door] #[mozart][grass] = yes #[mozart][green] = no #[mozart][human] #[blue][movie]=yes #[item_1][beat] = yes #[item_1][music] = no ";
$cleaned_string = str_replace('] #[','][',$original_string);
/* This results in clusters of keys that equal a value:
#[item_1][door][mozart][grass] = yes #[mozart][green] = no #[mozart][human][blue][movie]=yes #[item_1][beat] = yes #[item_1][music] = no
OR (with line breaks for clarity):
#[item_1][door][mozart][grass] = yes
#[mozart][green] = no
#[mozart][human][blue][movie]=yes
#[item_1][beat] = yes
#[item_1][music] = no */
//break it up into an array:
$elements = explode('#',$cleaned_string);
//create a variable to compare the last string to
$last_keys = "";
//and another that will serve as our final array
$array_of_arrays = array();
//now loop through each [item_1][door][mozart][grass] = yes,[mozart][green] = no, etc
foreach($elements as $element){
if ($element==""){continue;} //skip the first empty item
//break the string into [0] = group of keys and [1] the value that terminates the string
//so [item_1][door][mozart][grass] = yes BECOMES [item_1][door][mozart][grass], AND yes
$pieces = explode('=',str_replace(array('[',']'),array("['","']"),trim($element)));
//now compare this set of keys to the last set of keys, and if they overlap merge them into a single key string
$clean_keys = combine_key_strings($pieces[0],$last_keys);
//set the new key string the value for the next comparison
$last_keys = $clean_keys;
//and (ugly, I know) we use an eval to convert "[item_1][door][mozart][grass]='yes'" into a properly keyed array
eval("\$array_of_arrays".$clean_keys." = '".trim($pieces[1])."';");
}
//now dump the contents
print_r($array_of_arrays);
//THIS FUNCTION COMPA
function combine_key_strings($new,$old){
//get the key that starts the newer string
$new_keys = explode('][',$new);
$first_key = $new_keys[0].']';
//see if it appears in the last string
$last_occurance = strrpos ($old,$first_key);
//if so, merge the two strings to create the full array keystring
if (is_int($last_occurance)){
return substr($old,0,$last_occurance).$new;
}
return $new;
}
This should spit out your correctly nested array:
Array
(
[item_1] => Array
(
[door] => Array
(
[mozart] => Array
(
[grass] => yes
[green] => no
[human] => Array
(
[blue] => Array
(
[movie] => yes
)
)
)
)
[beat] => yes
[music] => no
)
)
Good night!

Related

Decode serialized cookie and loop options

I store form elements as serialized data in a cookie.
On another page I want to collect this cookie but the cookie contains this string:
form_key=kcE3W2vzParNhPN5&options%5B1508%5D=2025&options%5B1509%5D=1234&options%5B1510%5D=5678&options%5B1511%5D=&options%5B1512%5D=&options%5B1513%5D=&productId=59891
%5B and %5D are brackets I figured, but how can I look through all these options in the string and get their ID + value into an array with PHP.
So from above string I would like to create an array with:
arr = array (
[1508] = '2025';
[1509] = '1234';
[1510] = '5678';
[1511] = '';
[1512] = '';
);
I think what you want is parse_str():
$str = "form_key=kcE3W2vzParNhPN5&options%5B1508%5D=2025&options%5B1509%5D=1234&options%5B1510%5D=5678&options%5B1511%5D=&options%5B1512%5D=&options%5B1513%5D=&productId=59891";
$output = array();
parse_str($str, $output);
print_r($output); // $output['options'] will contain your array you're looking for.
See execution here:
Array
(
[form_key] => kcE3W2vzParNhPN5
[options] => Array
(
[1508] => 2025
[1509] => 1234
[1510] => 5678
[1511] =>
[1512] =>
[1513] =>
)
[productId] => 59891
)

pull dynamic element in single array

I am trying to pull dynamic element in single array but result is not showing properly
Ex:
$array =array();
$element="'abc1','abc2'";
$array=array('abc',$element);
//I want result like that:
array[
[0]=>abc,
[1]=>abc1,
[2]=>ab
]
If you need to parse a string of elements to an array you can use one of the csv functions. You may then merge your arrays.
$array = array('abc');
$string_elements = "'abc1','abc2'";
$array_elements = str_getcsv($string_elements, ',', "'");
$array = array_merge($array, $array_elements);
var_export($array);
Output:
array (
0 => 'abc',
1 => 'abc1',
2 => 'abc2',
)
Alternatively to add each array element to the end of another array you can push them like so using a splat:
array_push($array, ...$array_elements);
According to my understanding, $element is storing string not an array so even if you try to get output it will display in following format
Array
(
[0] => abc
[1] => 'abc1','abc2'
)
Instead of this you can store array in $element variable and use array_merge() function to get required output e.g.
$element = array('abc1','abc2');
$array = array('abc');
$result = array_merge($array,$element);
// Output
Array
(
[0] => abc
[1] => abc1
[2] => abc2
)

PHP String/Variable To Array And Check String/Variable Null

Hello I want create string to array. I have 4 variables:
<?php
$name = "John";
$address = "Moscow";
$born_date = "13-11-1995";
$color = "red";
$join = $name.":".$address.":".$born_date.":".$color;
$array = explode(':', $join);
print_r ($array);
?>
This array result is:
Array ( [0] => John [1] => Moscow [2] => 1995-11-13 [3] => red )
When I change $color variable to null like $color="";
This result like this:
Array ( [0] => John [1] => Moscow [2] => 1995-11-13 [3] => )
I want array number 3 not to show. I want if all $variable == NULL / $variable=="undefined" / $varable=""
Show like this:
Array ( [0] => John [1] => Moscow [2] => 1995-11-13)
The array shows only variable filled.
I'm not sure what your requirements are, but it seems strange to create this array by joining the variables together and then exploding them. You could just add them directly to the array, and add the color conditionally:
$array = array($name, $address, $born_date);
if ($color) {
$array[] = $color;
}
If you need all of the elements to be added conditionally, you can create an array containing all of them and then use array_filter as Rasclatt suggested to eliminate the empty ones.
$array = array($name, $address, $born_date, $color);
$array = array_filter($array);
If it is important that the keys remain sequential, you can use
$array = array_values(array_filter($array));

Multidimesional array pointers

I'm building an array piece by piece following a specific pattern.
For example, I have this string <val0=0, val1=<val2=2, val3=<val4=4>>, val5=5> and I need to translate it to an associative array. So every time I find < I have to create a new array and store the following elements until the next >.
The string above should result in something like this:
Array
(
[val0] => 0
[val1] => Array
(
[val2] => 2
[val3] => Array
(
[val4] => 4
)
)
[val5] => 5
)
Everything is working fine for non-multidimensional arrays using str_split to break the string in pieces and iterating over them in a for loop but I'm having difficulties to find a workaround every time there is a nesting array in the string.
What I need is a way to have a pointer to the last created array inside the main array.
Is there a way to store an array pointer reference in a variable so I could do this:
print_r($MULTIARRAY['val1']['val3']);
// prints: array()
$pointer = pointer($MULTIARRAY['val1']['val3']);
$pointer[] = 'AAA';
$pointer[] = 'BBB';
print_r($MULTIARRAY['val1']['val3']);
// prints: array(
// [0] => AAA
// [1] => BBB
//)
Here you go, it's called reference
$a[1][22] = array();
$pointer = &$a[1][22];
$pointer[] = 3;
$pointer[] = 4;
print_r($a);

checking to see if a vaule is in a particular key of an array

I'm new to working with arrays so I need some help. With getting just one vaule from an array. I have an original array that looks like this:
$array1= Array(
[0] => 1_31
[1] => 1_65
[2] => 29_885...)
What I'm trying to do is seach for and return just the value after the underscore. I've figured out how to get that data into a second array and return the vaules as a new array.
foreach($array1 as $key => $value){
$id = explode('_',$value);
}
which gives me:
Array ( [0] => 1 [1] => 31 )
Array ( [0] => 1 [1] => 65 )
Array ( [0] => 29 [1] => 885 )
I can also get a list of the id's or part after the underscore by using $id[1] I'm just not sure if this is the best way and if it is how to do a search. I've tried using in_array() but that searches the whole array and I couldn't make it just search one key of the array.
Any help would be great.
If the part after underscore is unique, make it a key for new array:
$newArray = array();
foreach($array1 as $key => $value){
list($v,$k) = explode('_',$value);
$newArray[$k] = $v;
}
So you can check for key existence with isset($newArray[$mykey]), which will be more efficient.
You can use preg_grep() to grep an array:
$array1= array("1_31", "1_65", "29_885");
$num = 65;
print_r(preg_grep("/^\d+_$num$/", $array1));
Outputs:
Array
(
[1] => 1_65
)
See http://ideone.com/3Fgr8
I would say you're doing it just about as well as anyone else would.
EDIT
Alternate method:
$array1 = array_map(create_function('$a','$_ = explode("_",$a); return $_[1];'),$array1);
echo in_array(3,$array1) ? "yes" : "no"; // 3 being the example
I would have to agree. If you wish to see is a value exists in an array however just use the 'array_key_exists' function, if it returns true use the value for whatever.

Categories