Access multidimensional array with a path-like string - php

I have a function called get_config() and an array called $config.
I call the function by using get_config('site.name') and am looking for a way to return the value of $config so for this example, the function should return $config['site']['name'].
I'm nearly pulling my hair out - trying not to use eval()! Any ideas?
EDIT: So far I have:
function get_config($item)
{
global $config;
$item_config = '';
$item_path = '';
foreach(explode('.', $item) as $item_part)
{
$item_path .= $item."][";
$item = $config.{rtrim($item_path, "][")};
}
return $item;
}

This should work:
function get_config($config, $string) {
$keys = explode('.', $string);
$current = $config;
foreach($keys as $key) {
if(!is_array($current) || !array_key_exists($key, $current)) {
throw new Exception('index ' . $string . ' was not found');
}
$current = $current[$key];
}
return $current;
}

you could try something like...
function get_config($item)
{
global $config;
return $config[{str_replace('.','][',$item)}];
}

Inside your get_config function, you can parse the string using explode function in php
function get_config($data){
$pieces = explode(".", $data);
return $config[$pieces[0]][$pieces[1]];
}

Related

How to get values for multiple keys?

I want to get values using multiple keys.
I have a php code that works for single key but i want to get values for multiple keys. How can i do that?
<?php
$arr=array(
'1'=>'India',
'2'=>'Canada',
'3'=>'United',
'4'=>'China',
'5'=>'London',
'6'=>'New Delhi',
);
$key1='4';
$key2='3';
$key3='4';
echo $arr[$key1, $key2, $key3];
?>
I want output like this in proper order
China
United
China
Thanks in advance.
We have interface ArrayAccess in PHP:
https://www.php.net/manual/en/class.arrayaccess.php
So we can write code as following to support multiple keys( Updated the example from above page ):
You will have to update it to fit your requirements.
<?php
class MultipleKeyArray implements ArrayAccess {
private $container = array();
private $separator = ',';
public function __construct($arr ) {
$this->container = $arr;
}
public function setSeparator($str){
$this->separator = $str;
}
public function offsetSet($offsets, $values) {
$os = explode(',',$offsets);
$vs = explode(',',$values);
$max = max(count($os),count($vs));
for($i=0;$i<$max;$i++){
$offset = $os[$i];
$value = $vs[$i];
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
}
public function offsetExists($offsets) {
$os = explode(',',$offsets);
for($i=0;$i<count($os);$i++){
$offset = $os[$i];
if( !isset($this->container[$offset]) ){
return false;
}
}
return true;
}
public function offsetUnset($offsets) {
$os = explode(',',$offsets);
for($i=0;$i<count($os);$i++){
$offset = $os[$i];
unset($this->container[$offset]);
}
}
public function offsetGet($offsets) {
$os = explode(',',$offsets);
$result = '';
for($i=0;$i<count($os);$i++){
$offset = $os[$i];
$result .= ($i>0 ? $this->separator:'') . (isset($this->container[$offset]) ? $this->container[$offset] : '');
}
return $result;
}
}
$arr=array(
'1'=>'India',
'2'=>'Canada',
'3'=>'United',
'4'=>'China',
'5'=>'London',
'6'=>'New Delhi',
);
$o = new MultipleKeyArray($arr);
$o[] = 'new0';
$o['f,g']='new1,new2';
var_dump(isset($o['f,g']));
var_dump(isset($o['1,2,f']));
var_dump(isset($o['f,not,there']));
echo $o['4,3,4']."\n";
echo $o['2,f,g']."\n";
$o->setSeparator("|");
echo $o['4,3,4']."\n";
Output:
bool(true)
bool(true)
bool(false)
China,United,China
Canada,new1,new2
China|United|China
PHP index cannot take array - you should do that with loop or PHP array function.
First define array of the key you need as:
$keys = [$key1, $key2, $key3];
Now use a foreach loop to echo them as:
foreach($keys as $k)
echo $arr[$k] . PHP_EOL;
And the one-liner:
array_walk($keys, function($k) use ($arr) {echo $arr[$k] . PHP_EOL;});

Using a delimited string, how do I get an array item relative to the parsed string?

Given a string in the format of "one/two" or "one/two/three", with / as delimiters, I need to get the value (as a reference) in a 2d array. In this specific case, I'm accessing the $_SESSION variable.
In the SessionAccessor::getData($str) function, I don't know what to put in there to make it parse the delimited string and return the array item. The idea is I won't know which array key I'm accessing. The function will be generic.
class SessionAccessor {
static &function getData($str) {
// $str = 'one/two/three'
return $_SESSION['one']['two']['three'];
}
}
/** Below is an example of how it will be expected to work **/
/**********************************************************/
// Get a reference to the array
$value =& SessionAccessor::getData('one/two/three');
// Set the value of $_SESSION['one']['two']['three'] to NULL
$value = NULL;
Here's the solution provided by #RocketHazmat here at StackOverflow:
class SessionAccessor {
static function &getVar($str) {
$arr =& $_SESSION;
foreach(explode('/',$str) as $path){
$arr =& $arr[$path];
}
return $arr;
}
}
From what you've described, it sounds like this is what you're after;
&function getData($str) {
$path = explode('/', $str);
$value = $_SESSION;
foreach ($path as $key) {
if (!isset($value[$key])) {
return null;
}
$value = $value[$key];
}
return $value;
}
EDIT
To also allow for the values to be set, it would be best to use a setData method. This should hopefully do what you hoped for;
class SessionAccessor {
static function getData($str) {
$path = explode('/', $str);
$value = $_SESSION;
foreach ($path as $key) {
if (!isset($value[$key])) {
return null;
}
$value = $value[$key];
}
return $value;
}
static function setData($str, $newValue) {
$path = explode('/', $str);
$last = array_pop($path);
$value = &$_SESSION;
foreach ($path as $key) {
if (!isset($value[$key])) {
$value[$key] = array();
}
$value = &$value[$key];
}
$value[$last] = $newValue;
}
}

How to echo variable outside of a function?

I have this code that echoes values from an array. I'd like to be able to echo the variable elsewhere in my code though. I've tried wrapping a function around it and echoing the function but I can't get anything to work. Here's the code that I have now...
function team(){
if ( ($items = field_get_items('entityform', $entityform, 'field_team_members')) ) {
$values = array_map($items, function($x) { return $x['value']; });
$comma_separated = implode(', ', $values);
foreach ($items as $item) {
$members = $prefix . $item['safe_value'];
$prefix = ', ';
echo $members;
}
}
}
If I simply do team(); it outputs nothing, as well as echo team();. What am I doing wrong here?
Your team function doesn't return anything which is why echo team(); doesn't print anything.
See the documentation on functions for more info: http://php.net/manual/en/functions.returning-values.php
function team(){
$output = '';
if ( ($items = field_get_items('entityform', $entityform, 'field_team_members')) ) {
$values = array_map($items, function($x) { return $x['value']; });
$comma_separated = implode(', ', $values);
$prefix = '';
$members = '';
foreach ($items as $item) {
$members .= $prefix . $item['safe_value'];
$prefix = ', ';
}
$output = $members;
}
return $output;
}
To clarify what i wrote as a comment, i just created a small script:
<?php
function team () {
$string = "hi";
return $string;
}
echo team();
Functions cant work unless until they are called, so you have to call team(); in some way, once called it will for sure display what ever you are trying to echo. Also above function will not display anything unless you force fully exit in that function. Or return some value.

Return in recursive function php

I've got a little problem with recursive function output. Here's the code:
function getTemplate($id) {
global $templates;
$arr = $templates[$id-1];
if($arr['parentId'] != 0) {
$arr['text'] .= str_replace($arr['attr'], $arr['text'], getTemplate($arr['parentId']));
}
return $arr['text'];
}
The problem is that that function returns a value on each iteration like this:
file.exe
category / file.exe
root / category / file.exe
And I need only the last string which resembles full path. Any suggestions?
//UPD: done, the problem was with the dot in $arr['text'] .= str_replace
Try this please. I know its using global variable but I think this should work
$arrGlobal = array();
function getTemplate($id) {
global $templates;
global $arrGlobal;
$arr = $templates[$id-1];
if($arr['parentId'] != 0) {
array_push($arrGlobal, getTemplate($arr['parentId']));
}
return $arr['text'];
}
$arrGlobal = array_reverse($arrGlobal);
echo implode('/',$arrGlobal);
Try this,
function getTemplate($id) {
global $templates;
$arr = $templates[$id-1];
if($arr['parentId'] != 0) {
return $arr['text'] .= str_replace($arr['attr'], $arr['text'], getTemplate($arr['parentId']));
}
}
Give this a try:
function getTemplate($id, array $templates = array())
{
$index = $id - 1;
if (isset($templates[$index])) {
$template = $templates[$index];
if (isset($template['parentId']) && $template['parentId'] != 0) {
$parent = getTemplate($template['parentId'], $templates);
$template['text'] .= str_replace($template['attr'], $template['text'], $parent);
}
return $template['text'];
}
return '';
}
$test = getTemplate(123, $templates);
echo $test;

PHP Strings/Functions: Converting a string into a chain of functions

Having a string like
12345.find_user.find_last_name
how can i split at the charachter "." and convert it to a function-call:
find_last_name(find_user(12345));
and so on....could be of N-Elements (n-functions to run)....how do i do this effectivly, performance-wise also?
Edit, here is the solution based on your replies
thanks Gaurav for your great help. Here is my complete solution based on yours:
i protected the foreach with if(function_exists($function)){ to protect the whole thing from fatal php errors, and i added a complete example:
$mystring = '12345.find_user.find_last_name';
convert_string_to_functions($mystring);
function convert_string_to_functions($mystring){
$functions = explode('.', $mystring);
$arg = array_shift($functions);
foreach($functions as $function){
if(function_exists($function)){
$arg = $function($arg);
} else {
echo 'Function '.$function.' Not found';
}
}
echo $arg;
}
function find_last_name($mystring=''){
return $mystring.' i am function find_last_name';
}
function find_user($mystring=''){
return $mystring.' i am function find_user';
}
$string = '12345.find_user.find_last_name';
$functions = explode('.', $string);
$arg = array_shift($functions);
foreach($functions as $function){
$arg = $function($arg);
}
echo $arg;

Categories