I have a string as:
$string = "My name is {name}. I live in {detail.country} and age is {detail.age}";
and I have an array like that and it will be always in that format.
$array = array(
'name' => 'Jon',
'detail' => array(
'country' => 'India',
'age' => '25'
)
);
and the expected output should be like :
My name is Jon. I live in India and age is 25
So far I tried with the following method:
$string = str_replace(array('{name}','{detail.country}','{detail.age}'), array($array['name'],$array['detail']['country'],$array['detail']['age']));
But the thing is we can not use the plain text of string variable. It should be dynamic on the basis of the array keys.
You can use preg_replace_callback() for a dynamic replacement:
$string = preg_replace_callback('/{([\w.]+)}/', function($matches) use ($array) {
$keys = explode('.', $matches[1]);
$replacement = '';
if (sizeof($keys) === 1) {
$replacement = $array[$keys[0]];
} else {
$replacement = $array;
foreach ($keys as $key) {
$replacement = $replacement[$key];
}
}
return $replacement;
}, $string);
It also exists preg_replace() but the above one allows matches processing.
You can use a foreach to achieve that :
foreach($array as $key=>$value)
{
if(is_array($value))
{
foreach($value as $key2=>$value2)
{
$string = str_replace("{".$key.".".$key2."}",$value2,$string);
}
}else{
$string = str_replace("{".$key."}",$value,$string);
}
}
print_r($string);
The above will only work with a depth of 2 in your array, you'll have to use recurcivity if you want something more dynamic than that.
Here's a recursive array handler: http://phpfiddle.org/main/code/e7ze-p2ap
<?php
function replaceArray($oldArray, $newArray = [], $theKey = null) {
foreach($oldArray as $key => $value) {
if(is_array($value)) {
$newArray = array_merge($newArray, replaceArray($value, $newArray, $key));
} else {
if(!is_null($theKey)) $key = $theKey . "." . $key;
$newArray["{" . $key . "}"] = $value;
}
}
return $newArray;
}
$array = [
'name' => 'Jon',
'detail' => [
'country' => 'India',
'age' => '25'
]
];
$string = "My name is {name}. I live in {detail.country} and age is {detail.age}";
$array = replaceArray($array);
echo str_replace(array_keys($array), array_values($array), $string);
?>
echo "my name is ".$array['name']." .I live in ".$array['detail']['countery']." and my age is ".$array['detail']['age'];
Related
I have string :
$string = "'id_konversi_aktivitas' => 'f4d943e7', 'nim' => '180218038'"
And I will convert to array like this :
$data = array($string);
But the result is like this :
array(1) { [0]=> string(87) "'id_konversi_aktivitas' => 'f4d943e7', 'nim' => '180218038'" }
I want result like this :
array(2) { ["id_konversi_aktivitas"] => "f4d943e7", ["nim"] => "180218038" }
there is no core PHP function to achieve what you are looking for. You can try in the following way.
$string = "'id_konversi_aktivitas' => 'f4d943e7', 'nim' => '180218038'";
$arrayStr = explode(',', $string);
$myArr = [];
foreach ($arrayStr as $arr) {
$eachArr = explode('=>', $arr);
$myArr[trim($eachArr[0])] = $eachArr[1];
}
print_r($myArr);
I made a function specifically for this problem, I hope it helps you out.
function stringToArray($string) {
$output = [];
$array = explode(",", $string);
foreach($array as $elem) {
$item = explode("=>", $elem);
$newItem = [
trim(str_replace("'", "", $item[0])) => $item[1]
];
array_push($output, $newItem);
}
return $output;
}
Here's how I used it
<?php
$string = "'id_konversi_aktivitas' => 'f4d943e7', 'nim' => '180218038'";
function stringToArray($string) {
$output = [];
$array = explode(",", $string);
foreach($array as $elem) {
$item = explode("=>", $elem);
$newItem = [
trim(str_replace("'", "", $item[0])) => $item[1]
];
array_push($output, $newItem);
}
return $output;
}
$data = stringToArray($string);
print_r($data[0]["id_konversi_aktivitas"]);
// >> 'f4d943e7'
Using regular expressions instead of a simple explode makes parsing a bit safer. preg_match_all returns the result in a form that returns the desired array with array_combine without a loop.
string = "'id_konversi_aktivitas' => 'f4d\'943e7', 'nim' => '180218038'";
preg_match_all("~'(.+?)' *=> *'(.+?)'(,|$)~",$string,$match);
$array = array_combine($match[1],$match[2]);
var_dump($array);
I added a ' to the string from the request for testing purposes.
Demo: https://3v4l.org/6YO8Q
I have a string containing an array key position which I am trying to use this position to access the array ($arr).
Example of string ($str) which has a string value of svg.1.linearGradient.0.#style
This would be the equivalent of ['svg'][1]['linearGradient'][0]['#style']
How can I use the string to access/retrieve data from $arr using the above position?
For example, lets say i wanted to unset the array key unset($arr['svg'][1]['linearGradient'][0]['#style']) - how can i achieve this programmatically?
You can use the mechanism of passing the value by reference:
$result = &$arr;
$path = explode('.', $str);
for($i = 0; $i < count($path); $i++) {
$key = $path[$i];
if (is_array($result) && array_key_exists($key, $result)) {
if ($i == count($path) - 1) {
unset($result[$key]); // deleting an element with the last key
} else {
$result = &$result[$key];
}
} else {
break; // not found
}
}
unset($result); // resetting value by reference
print_r($arr);
fiddle
One method could be to split the string on ., then iterate through the "keys" to traverse your $arr object. (Please excuse my poor php, it's been a while...)
Example:
$arr = (object)[
"svg" => (array)[
(object)[],
(object)[
"linearGradient" => [
(object)[
"#style" => "testing",
],
],
],
],
];
$str = "svg.1.linearGradient.0.#style";
$keys = explode('.', $str);
$val = $arr;
foreach($keys as $key) {
$val = is_object($val)
? $val->$key
: $val[$key];
}
echo $val;
https://3v4l.org/h8YPv
Unsetting a key given the path:
$arr = (object)[
"svg" => (array)[
(object)[],
(object)[
"linearGradient" => [
(object)[
"#style" => "testing",
],
],
],
],
];
$str = "svg.1.linearGradient.0.#style";
$keys = explode('.', $str);
$exp = "\$arr";
$val = $arr;
foreach($keys as $index => $key) {
$exp .= is_object($val)
? "->{'" . $key . "'}"
: "[" . $key . "]";
$val = is_object($val) ? $val->$key : $val[$key];
}
eval("unset($exp);");
https://3v4l.org/Fdo6B
Docs
explode()
eval()
I have an array in PHP:-
$arr = ["BX_NAME0","BX_NAME1","BX_NAME2","BX_categoryName0","BX_categoryName1","BX_categoryName2","BHA_categories0","BHA_categories1","BHA_categories2"]
Here I want to group together elements based on same ending integer together in json like
$post_data = array(
'0' => array(
'BX_NAME0' => $item_type,
'BX_categoryName0' => $string_key,
'BHA_categories0' => $string_value
),
'1' => array(
'BX_NAME1' => $item_type,
'BX_categoryName1' => $string_key,
'BHA_categories1' => $string_value
),
);
I have Used:- filter_var($key , FILTER_SANITIZE_NUMBER_INT);
to get the integer part of the array elements but don't known how to group them further.
You can do it like below using preg_match():-
$new_array = array();
foreach ($arr as $ar){
preg_match_all('!\d+!', $ar, $matches); //get the number from string
$new_array[$matches[0][0]][$ar] = '';
}
echo "<pre/>";print_r($new_array);
Output:- https://eval.in/715548
It should be something like this:-
$arr = array("BX_NAME0","BX_NAME1","BX_NAME2","BX_categoryName0","BX_categoryName1","BX_categoryName2","BHA_categories0","BHA_categories1","BHA_categories2");
$post_data = array();
foreach($arr as $value) {
$key = filter_var($value , FILTER_SANITIZE_NUMBER_INT);
if(isset($post_data[$key]) && !is_array($post_data[$key])) {
$post_data[$key] = array();
}
$post_data[$key][] = $value;
}
print_r($post_data);
Tested and works
However, I suggest you use substr() to get the last character of the array item, for performance and stuff..
By using filter_var() method
$arr = ["BX_NAME0","BX_NAME1","BX_NAME2","BX_categoryName0","BX_categoryName1","BX_categoryName2","BHA_categories0","BHA_categories1","BHA_categories2"];
foreach($arr as $a){
$int = filter_var($a, FILTER_SANITIZE_NUMBER_INT);
$newarr[$int][$a] = '';
}
print_r($newarr);
Output:-https://eval.in/715581
I am trying to convert a multidimensional array into a string.
Till now I have been able to convert a pipe delimited string into an array.
Such as:
group|key|value
group|key_second|value
Will render into the following array:
$x = array(
'group' => array(
'key' => 'value',
'key_second' => 'value'
),
);
However, now I want it to be the other way around, where a multidimensional array is provided and I want to convert it to a pipe delimited string just like in the first code example.
Any ideas how to do this ?
PS: Please do note that the array can dynamically have any depth.
For example:
$x['group']['sub_group']['category']['key'] = 'value'
Translates to
group|sub_group|category|key|value
I have created my own function:
This should have no problem handling even big arrays
function array_to_pipe($array, $delimeter = '|', $parents = array(), $recursive = false)
{
$result = '';
foreach ($array as $key => $value) {
$group = $parents;
array_push($group, $key);
// check if value is an array
if (is_array($value)) {
if ($merge = array_to_pipe($value, $delimeter, $group, true)) {
$result = $result . $merge;
}
continue;
}
// check if parent is defined
if (!empty($parents)) {
$result = $result . PHP_EOL . implode($delimeter, $group) . $delimeter . $value;
continue;
}
$result = $result . PHP_EOL . $key . $delimeter . $value;
}
// somehow the function outputs a new line at the beginning, we fix that
// by removing the first new line character
if (!$recursive) {
$result = substr($result, 1);
}
return $result;
}
Demo provided here http://ideone.com/j6nThF
You can also do this using a loop like this:
$x = array(
'group' => array(
'key' => 'value',
'key_second' => 'value'
)
);
$yourstring ="";
foreach ($x as $key => $value)
{
foreach ($x[$key] as $key2 => $value2)
{
$yourstring .= $key.'|'.$key2.'|'.$x[$key][$key2]."<BR />";
}
}
echo $yourstring;
Here is a working DEMO
This code should do the thing.
You needed a recursive function to do this. But be careful not to pass object or a huge array into it, as this method is very memory consuming.
function reconvert($array,$del,$path=array()){
$string="";
foreach($array as $key=>$val){
if(is_string($val) || is_numeric($val)){
$string.=implode($del,$path).$del.$key.$del.$val."\n";
} else if(is_bool($val)){
$string.=implode($del,$path).$del.$key.$del.($val?"True":"False")."\n";
} else if(is_null($val)){
$string.=implode($del,$path).$del.$key.$del."NULL\n";
}else if(is_array($val)=='array') {
$path[]=$key;
$string.=reconvert($val,$del,$path);
array_pop($path);
} else {
throw new Exception($key." has type ".gettype($val).' which is not a printable value.');
}
}
return $string;
}
DEMO: http://ideone.com/89yLLo
You can do it by
Look at serialize and unserialize.
Look at json_encode and json_decode
Look at implode
And Possible duplicate of Multidimensional Array to String
You can do this if you specifically want a string :
$x = array(
'group' => array(
'key' => 'value',
'key_second' => 'value'
),
'group2' => array(
'key2' => 'value',
'key_second2' => 'value'
),
);
$str='';
foreach ($x as $key=>$value)
{
if($str=='')
$str.=$key;
else
$str.="|$key";
foreach ($value as $key1=>$value1)
$str.="|$key1|$value1";
}
echo $str; //it will print group|key|value|key_second|value|group2|key2|value|key_second2|value
I'm trying to create a multidimensional array from a string (received from $_GET, input is validated, but not in this example). Each '-' will indicate a level in the multidimensional array.
Values can look like this (any form really, as long as '-' is present between keys). The array of values can map to any depth in the multidimensional array.
$array = array(
'page-title' => 'Title of a page',
'page-url' => 'http://www.mypage.com',
'meta-page-author' => 'Some guy',
'meta-page-created' => 'some timestamp'
);
I've tried different solutions, but the only thing working until now is the inital loop and extract of keys.
foreach ($array as $key => $value) {
if (strpos($key, '-') !== false) {
$keyArray = explode('-', $key);
// ??
}
}
The output I'm hoping for, should look like this:
array(
'page' => array(
'title' => 'Title of a page',
'url' => 'http://www.mypage.com'
),
'meta' => array(
'page' => array(
'author' => 'Some guy',
'created' => 'some timestamp'
)
)
);
Something like this should work:
<?php
$array = array(
'page-title' => 'Title of a page',
'page-url' => 'http://www.mypage.com',
'meta-page-author' => 'Some guy',
'meta-page-created' => 'some timestamp'
);
$result = array();
foreach ($array as $key => $value) {
$keys = strpos($key, '-') !== false ? explode('-', $key) : array($key);
$ptr = &$result;
foreach ($keys as $k) {
if (!isset($ptr[$k])) {
$ptr[$k] = array();
}
$ptr = &$ptr[$k];
}
if (empty($ptr)) {
$ptr = $value;
} else {
$ptr[] = $value;
}
}
print_r($result);
What I did was explode your keys just like you were doing. I then looped through them creating a new array if the array didn't already exist. Using a reference I save the current point I was at in the array. Then once I had hit the last key I assigned the value. Hope this helps.
EDIT: Based on cHao's recommendation I changed
$keys = strpos($key, '-') !== false ? explode('-', $key) : $key;
to
$keys = strpos($key, '-') !== false ? explode('-', $key) : array($key);
to prevent failure on the foreach.
EDIT 2: I changed
$ptr = $value;
to
if (empty($ptr)) {
$ptr = $value;
} else {
$ptr[] = $value;
}
to handle cases like:
$array = array(
'page-title' => 'Title of a page',
'page-url' => 'http://www.mypage.com',
'meta-page-author' => 'Some guy',
'meta-page-created' => 'some timestamp',
'page' => 'foo'
);
Just so you're aware, PHP can be made to accept whole big arrays like that. If you name the form elements like 'somename[page][title]', then when the form returns, you should see them already arranged as an array in $_GET.
In case you have your heart set on the current naming scheme, though...
$result = array();
foreach ($array as $key => $value) {
$current =& $result;
if (strpos($key, '-') !== false) {
$keyArray = explode('-', $key);
$bottomKey = array_pop($keyArray);
foreach ($keyArray as $subKey) {
if (!isset($current[$subKey]))
$current[$subKey] = array();
$current =& $current[$subKey];
}
} else {
$bottomKey = $key;
}
$current[$bottomKey] = $value;
}
<?php
$array = array(
'page-title' => 'Title of a page',
'page-url' => 'http://www.mypage.com',
'meta-page-author' => 'Some guy',
'meta-page-created' => 'some timestamp'
);
$result = array();
foreach ($array as $key => $value) {
if (strpos($key, '-') !== false) {
$ak = "result['" . str_replace('-', '\'][\'', $key) . "'] = \"".$value."\"";
eval('$'.$ak.';');
}
}
var_dump($result);
?>
hope that helps