Multidimensional Array search by string - php

I have a multidimensional array that's contains all user data , and I've build a function to get array value with the given key .
the problem is that the array is multidimensional array , and I don't know how many level .
this is the function
function getUserSessionData($key)
{
$arrKeys = explode('.', $key);
if(count($arrKeys) == 1){
if(isset($_SESSION['user_data'][$arrKeys[0]])){
return $_SESSION['user_data'][$arrKeys[0]];
}
}
else{
if(isset($_SESSION['user_data'][$arrKeys[0]][$arrKeys[1]])){
return $_SESSION['user_data'][$arrKeys[0]][$arrKeys[1]];
}
}
return 0;
}
and this is an example of the call.
getUserSessionData('profile.firstName');
The (.) indicates of level of the array .
the function is support only tow levels .. is there any way to enhance this function so it can support more than tow levels ??

Sure, use a looping structure:
function getUserSessionData($key) {
$parts = explode('.', $key);
$data = $_SESSION["user_data"];
while (count($parts) > 0) {
$part = array_shift($parts);
$data = $data[$part];
}
return $data;
}
Or independently of the session:
function resolveKey($array, $key) {
$parts = explode('.', $key);
while (count($parts) > 0) {
$part = array_shift($parts);
$array = $array[$part];
}
return $array;
}
echo resolveKey(array(
"foo" => array(
"bar" => array(
"baz" => "ipsum"
)
)
), "foo.bar.baz"); // "ipsum"
echo resolveKey($_SESSION["user_data"], 'profile.firstName');

Here's a PHP-Fiddle
function getUserSessionData($key){
$arrKeys = explode('.', $key);
$data = $_SESSION['user_data'];
foreach($arrKeys as $k){
if(isset($data[$k])) $data = $data[$k];
else return false;
}
return $data;
}
Example usage:
session_start();
$_SESSION['user_data'] = [];
$_SESSION['user_data']['user'] = [];
$_SESSION['user_data']['user']['name'] = [];
$_SESSION['user_data']['user']['name']['first'] = "robert";
echo getUserSessionData("user.name.first"); // echos "robert"

Thank you #Halcyon
you've been very helpful.
but I've modified your function to get it to work .
this is the new function
function getUserSessionData($key) {
$data = Yii::app()->session['account_data']['user_data'];
$parts = explode('.', $key);
while (count($parts) > 0) {
$part = $parts[0];
if(!isset($data[$part])){
return 0;
}
$data = $data[$part];
array_shift($parts);
}
return $data;
}

Related

Find and extract words from strings

I need to find and extract words (array) in a string. I tried many techniques, and I found how to find first occurrences, but can't get it to work recursively.
$uda_state = [
"uda actif",
"uda stagiaire",
"stagiaire uda",
"uda",
"apprenti actra",
"actra apprenti",
"actra"
];
$arr = [
'<p>Nothing here</p>',
'<p>UDA Stagiaire et ACTRA</p>',
'<p>Stagiaire UDA</p>',
'<p>Should not pop</p>'
];
function contains($str, array $arr)
{
foreach($arr as $a) {
if ($pos = stripos($str,$a)) return true;
}
return false;
}
function extractWord($str, array $arr)
{
foreach($arr as $a) {
if ($pos = stripos($str, $a)) return $arr;
}
}
function find_uda_actra($str, array $arr = []) {
global $uda_state;
if (contains($str, $uda_state)) {
$word = extractWord($str, $uda_state);
$arr[] = $word;
$str = str_ireplace($word, '', $str);
if ($str != '') {
if (contains($str, $uda_state)) {
list($str, $arr) = find_uda_actra($str, $arr);
}
else {
return [$str, $arr];
}
} else {
return [$str, $arr];
}
}
return [$str, $arr];
}
foreach ($arr as $str) {
list($content, $uda) = find_uda_actra($str);
echo 'Content:'.PHP_EOL;
var_dump($content);
echo 'UDA:'.PHP_EOL;
var_dump($uda);
}
All I get now is emptied content and the whole $uda_state in each $uda. I need only the one that was found.
3v4l link for sandbox.

How to build a Multidimensional array in PHP

I am trying to build a multidimensional array in PHP using an array of string that I am cutting up so the string of 1:wlrb#yahoo.com:7:8.35 becomes
"id": "1",
"email_address": "wlrb#yahoo.com",
"domain": "yahoo.com",
"number_of_orders": "7",
"total_order_value": "£8.35"
In JavaScript I would create an object containing the above values and put it into an array but what is the equivalent in PHP?
So far I have the below code which gives me
Array ( [0] => stdClass Object ( [id] => 1 [email] => wlrb#yahoo.com
[domain] => yahoo.com [number_of_orders] => 7 [total_order_value] =>
8.35 )
<?php
$data = file_get_contents('orderdata');
/* echo $data; */
$lines = explode("\n", $data);
array_splice($lines, 0, 8);
/* var_dump($lines); */
array_splice($lines, -3);
/* var_dump($lines); */
/* removes all NULL, FALSE and Empty Strings but leaves 0 (zero) values */
$lines = array_values(array_filter($lines, 'strlen'));
function arraySort($lines ,$i) {
$rep = new stdClass();
$rep->id = strId($lines, $i);
$rep->email = strEmail($lines, $i);
$rep->domain = strDomain($lines, $i);
$rep->number_of_orders = orderNo($lines, $i);
$rep->total_order_value = orderValue($lines, $i);
/* var_dump($rep); */
return $rep;
}
function strDomain($lines, $i) {
if($lines[$i] == null){
return "";
}
else {
$str = $lines[$i];
$splt = explode(':', $str);
$domain = explode('#', $splt[1]);
return $domain[1];
}
}
function strId($lines, $i) {
if($lines[$i] == null){
return "";
}
else {
$str = $lines[$i];
$splt = explode(':', $str);
return $splt[0];
}
}
function strEmail($lines, $i) {
if($lines[$i] == null){
return "";
}
else {
$str = $lines[$i];
$splt = explode(':', $str);
return $splt[1];
}
}
function orderNo($lines, $i) {
if($lines[$i] == null){
return "";
}
else {
$str = $lines[$i];
$splt = explode(':', $str);
return $splt[2];
}
}
function orderValue($lines, $i) {
if($lines[$i] == null){
return "";
}
else {
$str = $lines[$i];
$splt = explode(':', $str);
return '£' + $splt[3];
}
}
$reports = array();
$reps = array();
for($i = 0, $length = count($lines); $i < $length; ++$i) {
$reps = arraySort($lines, $i);
array_push($reports, $reps);
}
?>
but when I try to search the array with
$filteredArray =
array_filter($reports, function($element) use($search){
return isset($element['domain']) && $element['domain'] == $search;
});
I get the following error
Fatal error: Uncaught Error: Cannot use object of type stdClass as
array in phpData.php:110 Stack trace: #0
[internal function]: {closure}(Object(stdClass)) #1
phpData.php(111): array_filter(Array,
Object(Closure)) #2 {main} thrown in
phpData.php on line 110
Is this because of the use of $rep = new stdClass();in my arraySort function? If so what should I be using?
The easiest and shortest solution would be :
$value = "1:wlrb#yahoo.com:7:8.35";
$keys = array('id', 'email_address', 'number_of_orders', 'total_order_value');
$fused = array_combine($keys, explode(':', $value));
$fused['domain'] = strDomain($fused['email_address']); //using your "strDomain()" function
It will give you the array you want, except you won't have the £ sign in your order value.
you can use object obtention method like this:
$filteredArray =
array_filter($reports, function($element) use($search){
return isset($element->domain) && $element->domain == $search;
});

Comma separated string to parent child relationship array php

I have a comma separated string like
$str = "word1,word2,word3";
And i want to make a parent child relationship array from it.
Here is an example:
Try this simply making own function as
$str = "word1,word2,word3";
$res = [];
function makeNested($arr) {
if(count($arr)<2)
return $arr;
$key = array_shift($arr);
return array($key => makeNested($arr));
}
print_r(makeNested(explode(',', $str)));
Demo
function tooLazyToCode($string)
{
$structure = null;
foreach (array_reverse(explode(',', $string)) as $part) {
$structure = ($structure == null) ? $part : array($part => $structure);
}
return $structure;
}
Please check below code it will take half of the time of the above answers:
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
$result = array($arr[$i] => $result);
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';
Here is another code for you, it will give you result as you have asked :
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
if($i == 0){
$result = array($arr[$i] => $result);
}else{
$result = array(array($arr[$i] => $result));
}
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';

How to get both array key from value in 2 dimensional array (PHP)

$arr['animal'][0] = 'Dog';
$arr['animal'][1] = 'Cat';
From that array basically I need to create a function with the array value parameter and then it gives me the array keys.
For example:
find_index('Cat');
Output :
The result is animal, 1
You could probably do something like
function find_index($value) {
foreach ($arr as $index => $index2) {
$exists = array_search($value, $index2);
if ($exists !== false) {
echo "The result is {$index}, {$exists}";
return true;
}
}
return false;
}
Try this:
$arr['animal'][0] = 'Dog';
$arr['animal'][1] = 'Cat';
function find_index($searchVal, $arr){
return array_search($searchVal, $arr);
}
print_r(find_index('Cat', $arr['animal']));
Consider this Array,
$arr['animal'][] = 'Dog';
$arr['animal'][] = 'Cat';
$arr['insects'][] = 'Insect1';
$arr['insects'][] = 'Insect2';
Here is Iterator Method,
$search = 'InsectSub1';
$matches = [];
$arr_array = new RecursiveArrayIterator($arr);
$arr_array_iterator = new RecursiveIteratorIterator($arr_array);
foreach($arr_array_iterator as $key => $value)
{
if($value === $search)
{
$fill = [];
$fill['category'] = $arr_array->key();
$fill['key'] = $arr_array_iterator->key();
$fill['value'] = $value;
$matches[] = $fill;
}
}
if($matches)
{
// One or more Match(es) Found
}
else
{
// Not Found
}
$arr['animal'][] = 'Dog';
$arr['animal'][] = 'Cat';
$arr['insects'][] = 'Insect1';
$arr['insects'][] = 'Insect2';
$search_for = 'Cat';
$search_result = [];
while ($part = each($arr)) {
$found = array_search($search_for, $part['value']);
if(is_int($found)) {
$fill = [ 'key1' => $part['key'], 'key2' => $found ];
$search_result[] = $fill;
}
}
echo 'Found '.count($search_result).' result(s)';
print_r($search_result);

Is it possible for a variable to evaluate to a multi-dimensional PHP array index

Given a multidimensional array or dictionary $array.
And assuming that $array['foo']['bar']['baz'] = 'something';
Is there a way other than via an eval statement for me use the multi-dimentional index foo/bar/baz? (The use case is in creating the index dynamically i.e. The function does not know what /foo/bar/baz/ is).
The only way I could figure to do this was:
$item = testGetIndex($array, "'foo']['bar']['baz'");
function testGetIndex($array, $index) {
eval('$item = $array[' . $index . '];');
return $item;
}
Note:
I should mention that I do not want to search this array. This is a weird use case. I am being passed a very large multi dimensional array and it's ugly to have to use constructs like..
$array[foo][bar]..[baz] to make modifications to the array.
Blatently reusing my answer here:
function recurseKeys(array $keys,array $array){
$key = array_shift($keys);
if(!isset($array[$key])) return null;
return empty($keys) ?
$array[$key]:
recurseKeys($keys,$array[$key];
}
$values = recurseKeys(explode('/','foo/bar/baz'),$yourArray);
edit: as Jack pointed out, recursion is not needed:
function findByKey(array $keys,array $array){
while(!is_null($key = array_shift($keys))){
if(!isset($array[$key])) return null;
$array = $array[$key];
}
return $array;
}
$values = findByKey(explode('/','foo/bar/baz'),$yourArray);
To modify an array using a path:
function setPath(&$root, $path, $value)
{
$paths = explode('/', $path);
$current = &$root;
foreach ($paths as $path) {
if (isset($current[$path])) {
$current = &$current[$path];
} else {
return null;
}
}
return $current = $value;
}
$path = 'foo/bar/baz';
$root = array('foo' => array('bar' => array('baz' => 'something')));
setPath($root, $path, '123');
You can tweak the function to just return a reference to the element you wish to change:
function &getPath(&$root, $path)
{
$paths = explode('/', $path);
$current = &$root;
foreach ($paths as $path) {
if (isset($current[$path])) {
$current = &$current[$path];
} else {
return null;
}
}
return $current;
}
$x = &getPath($root, $path);
$x = 456; // $root['foo']['bar']['baz'] == 456
A simple loop can make it, like:
function get(array $array, $keys) {
$val = $array;
foreach (explode('/', $keys) as $part) {
if (!isset($val[$part])) {
return null;
}
$val = $val[$part];
}
return $val;
}
$array['foo']['bar']['baz'] = 'something';
echo get($array, 'foo/bar/baz');
http://ideone.com/vcRvXW
Edit:
For modification, just use references:
function set(array &$array, $keys, $value) {
$val = &$array;
foreach (explode('/', $keys) as $part) {
if (!isset($val[$part])) {
$val[$part] = array();
}
$val = &$val[$part];
}
$val = $value;
}
http://ideone.com/WUNhF6

Categories