PHP - Arrays and Foreach - php

I searched in Google and consulted the PHP documentation, but couldn't figure out how the following code works:
$some='name=Licensing Module;nextduedate=2013-04-10;status=Active|name=Test Addon;nextduedate=2013-04-11;status=Active';
function getActiveAddons($somet) {
$addons = array( );
foreach ($somet as $addon) {
if ($addon['status'] == 'Active') {
$addons[] = $addon['name'];
continue;
}
}
return $addons;
}
echo (count( getActiveAddons( $some ) ) ? implode( '<br />', getActiveAddons( $some ) ) : 'None');
The code always echo's None.
Please help me in this.

I don't know where you got this code from but you've initialized $some the wrong way. It is expected as an array like this:
$some = array(
array(
'name' => 'Licensing Module',
'nextduedate' => '2013-04-10',
'status' => 'Active'
),
array(
'name' => 'Test Addon'
'nextduedate' => '2013-04-11',
'status' => 'Active'
)
);
I guess the article you've read is expecting you to parse the original string into this format.
You can achieve this like this:
$string = 'name=Licensing Module;nextduedate=2013-04-10;status=Active|name=Test Addon;nextduedate=2013-04-11;status=Active';
$result = array();
foreach(explode('|', $string) as $record) {
$item = array();
foreach(explode(';', $record) as $column) {
$keyval = explode('=', $column);
$item[$keyval[0]] = $keyval[1];
}
$result[]= $item;
}
// now call your function
getActiveAddons($result);

$some is not an array so foreach will not operate on it. You need to do something like
$some = array(
array(
'name' => 'Licensing Module',
'nextduedate' => '2013-04-10',
'status' => 'Active'
),
array(
'name' => 'Test Addon',
'nextduedate' => '2013-04-11',
'status'=> 'Active'
)
);
This will create a multidimensional array that you can loop through.
function getActiveAddons($somet) {
$addons = array( );
foreach ($somet as $addon) {
foreach($addon as $key => $value) {
if ($key == 'status' && $value == 'Active') {
$addons[] = $addon['name'];
continue;
}
}
}
return $addons;
}

First, your $some variable is just a string. You could parse the string into an array using explode(), but it's easier to just start as an array:
$some = array(
array(
"name" => "Licensing Module",
"nextduedate" => "2013-04-10",
"status" => "Active",
),
array(
"name" => "Test Addon",
"nextduedate" => "2013-04-11",
"status" => "Active",
)
);
Now, for your function, you are on the right track, but I'll just clean it up:
function getActiveAddons($somet) {
if (!is_array($somet)) {
return false;
}
$addons = array();
foreach ($somet as $addon) {
if ($addon['status'] == 'Active') {
$addons[] = $addon['name'];
}
}
if (count($addons) > 0) {
return $addons;
}
return false;
}
And finally your output (you were calling the function twice):
$result = getActiveAddons($some);
if ($result === false) {
echo "No active addons!";
}
else {
echo implode("<br />", $result);
}

Related

recursion function on tree data to get path

I want to write function which receive me path to top element, but I can't figure out how it should work..
My example data:
$data = array(
3546456 => array(
5345345,
12312312,
56456546,
),
12312312 => array(
34534534,
5675675,
8678678,
),
567978 => array(
234,
756756,
8678678,
),
);
//I have function to return parent.
$parents = getParents(8678678); // eg. $object_id = 8678678 - return [12312312, 567978] , $object_id = 12312312 - return [3546456]
// and my recursion function I tried.
function getObjectPath($object_id) {
if ($object_id == null) {
return [];
}
$parents = getObjectParents($object_id);
foreach ($parents as $parent) {
return array($object_id => getObjectPath($parent->nid));
}
}
It doesn't work way I need, on the return in getObjectPath(8678678) I'd like to have return array like that:
array(
3546456 => array(
12312312 => array(
8678678
)
),
567978 => array(
8678678
)
);
I think you almost got it, need to have some other check before returning
$data = array(
3546456 => array(
5345345,
12312312,
56456546,
),
12312312 => array(
34534534,
5675675,
8678678,
),
567978 => array(
234,
756756,
8678678,
),
);
//I have function to return parent.
$parents = getObjectPath(8678678, $data); // eg. $object_id = 8678678 - return [12312312, 567978] , $object_id = 12312312 - return [3546456]
echo "<pre>";
print_r($parents);
// and my recursion function I tried.
function getParents($object_id, $data) {
$return = [];
foreach($data as $key => $value) {
if(in_array($object_id, $value)) {
$return[] = $key;
}
}
return $return;
}
// and my recursion function I tried.
function getObjectPath($object_id, $data) {
$return = [];
$parents = getParents($object_id, $data);
foreach($parents as $parent) {
$temp = getObjectPath($parent, $data);
if(!empty($temp)) {
$return[key($temp)][$parent] = $object_id;
} else {
$return[$parent] = $object_id;
}
}
return $return;
}

php loop through complex posts

I am new to web programming and I have such a complex posts all over my work this was the result for a var_dump($_POST) , I am using gettype() function to determine that if the value in the $arr array is another array or not , I am not convenient of such behave of code of mine , neither the problems that I always met when going to loop for insertion
the question is if there is smarter technique to loop within like this complex posts , secondly how to catch the name,phone in the 2d array that called assistant (called assistant['name'],assistant[phone])
<?php
$arr = array(
"name"=> "mmmkkkk",
"phones"=> array(
"01553338897" ,
"09090909098"
),
"address"=> "107 ostras., Germany",
"assistant"=> array(
"name" => array(
"kmkkm",
"komar"
),
"phone"=> array(
"01043338897" ,
"09099090090"
)
)
);
foreach($arr as $key => $p_value)
{
if(gettype($p_value)=="array")
{
echo $key.":"."</br>";
foreach($p_value as $newp_value => $val )
{
if(gettype($val)=="array")
{
foreach($val as $vkey)
{
echo $vkey."</br>";
}
}
else{echo $val."</br>";}
}
}else{echo $key.":".$p_value."</br>";}
}
?>
You can use Recursive function like this.
<?php
$arr = array(
"name"=> "mmmkkkk",
"phones"=> array(
"01553338897" ,
"09090909098"
),
"address"=> "107 ostras., Germany",
"assistant"=> array(
"name" => array(
"kmkkm",
"komar"
),
"phone"=> array(
"01043338897" ,
"09099090090"
)
)
);
function rec($arr) {
foreach($arr as $key => $p_value)
{
if (is_array($p_value)) {
rec($p_value);
} else {
echo $key.":".$p_value."\n";
}
}
}
rec($arr);
?>
Think recursive
function walkThrough($array, $tabulation = 0) {
foreach($array as $key => $value) {
printf ('%s%s:', str_repeat(4*$tabulation, ' '));
if (is_array($value)) walkThrough ( $value, ($tabulation+1) );
else printf('%s<br />', $value);
}
}
Use this Recursive function
function recursivefunc($arr,$key =''){
if(is_array($arr)){
foreach($arr as $k => $v){
if (is_array($v) && !empty($v)) {
recursivefunc($v,$k);
} else {
$keys = ($key=='') ? $k : $key;
echo $keys.":".$v.'</br>';
}
}
}
}
recursivefunc($arr);
Out put :
name:mmmkkkk
phones:01553338897
phones:09090909098
address:107 ostras., Germany
name:kmkkm
name:komar
phone:01043338897
phone:09099090090

Getting Nested Values From Associative Array

This is sort of a general implementation question. If I have an arbitrarily deep array, and I do not know before hand what the keys will be, what is the best way to access the values at specific paths of the associative array? For example, given the array:
array(
'great-grandparent' = array(
'grandparent' = array(
'parent' = array(
'child' = 'value';
),
'parent2' = 'value';
),
'grandparent2' = 'value';
)
);
Whats the best way to access the value at $array['great-grandparent']['grandparent']['parent']['child'] keeping in mind that I don't know the keys beforehand. I have used eval to construct the above syntax as a string with variable names and then eval'd the string to get the data. But eval is slow and I was hoping for something faster. Something like $class->getConfigValue('great-grandparent/grandparent/'.$parent.'/child'); that would return 'value'
Example of Eval Code
public function getValue($path, $withAttributes=false) {
$path = explode('/', $path);
$rs = '$r = $this->_data[\'config\']';
foreach ($path as $attr) {
$rs .= '[\'' . $attr . '\']';
}
$rs .= ';';
$r = null;
#eval($rs);
if($withAttributes === false) {
$r = $this->_removeAttributes($r);
}
return $r;
}
I don't know about the potential speed but you don't need to use eval to do a search like that :
$conf = array(
'great-grandparent' => array(
'grandparent' => array(
'parent' => array(
'child' => 'value searched'
),
'parent2' => 'value'
),
'grandparent2' => 'value'
)
);
$path = 'great-grandparent/grandparent/parent/child';
$path = explode('/', $path);
$result = $conf;
while(count($path) > 0) {
$part = array_shift($path);
if (is_array($result) && array_key_exists($part, $result)) {
$result = $result[$part];
} else {
$result = null;
break;
}
}
echo $result;
Here we go, my solution:
$tree = array(
'great-grandparent' => array(
'grandparent' => array(
'parent' => array(
'child' => 'value1'
),
'parent2' => 'value2'
),
'grandparent2' => 'value3'
)
);
$pathParts = explode('/','great-grandparent/grandparent/parent/child');
$pathParts = array_reverse($pathParts);
echo retrieveValueForPath($tree, $pathParts);
function retrieveValueForPath($node, $pathParts) {
foreach($node as $key => $value) {
if(($key == $pathParts[count($pathParts)-1]) && (count($pathParts)==1)) {
return $value;
}
if($key == $pathParts[count($pathParts)-1]) {
array_pop($pathParts);
}
if(is_array($value)) {
$result = retrieveValueForPath($value, $pathParts);
}
}
return $result;
}

Get array's key recursively and create underscore separated string

Right now i got an array which has some sort of information and i need to create a table from it. e.g.
Student{
[Address]{
[StreetAddress] =>"Some Street"
[StreetName] => "Some Name"
}
[Marks1] => 100
[Marks2] => 50
}
Now I want to create database table like which contain the fields name as :
Student_Address_StreetAddress
Student_Address_StreetName
Student_Marks1
Student_Marks2
It should be recursive so from any depth of array it can create the string in my format.
You can use the RecursiveArrayIterator and the RecursiveIteratorIterator (to iterate over the array recursively) from the Standard PHP Library (SPL) to make this job relatively painless.
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
$keys = array();
foreach ($iterator as $key => $value) {
// Build long key name based on parent keys
for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
$key = $iterator->getSubIterator($i)->key() . '_' . $key;
}
$keys[] = $key;
}
var_export($keys);
The above example outputs something like:
array (
0 => 'Student_Address_StreetAddress',
1 => 'Student_Address_StreetName',
2 => 'Student_Marks1',
3 => 'Student_Marks2',
)
(Working on it, here is the array to save the trouble):
$arr = array
(
'Student' => array
(
'Address' => array
(
'StreetAddress' => 'Some Street',
'StreetName' => 'Some Name',
),
'Marks1' => '100',
'Marks2' => '50',
),
);
Here it is, using a modified version of #polygenelubricants code:
function dfs($array, $parent = null)
{
static $result = array();
if (is_array($array) * count($array) > 0)
{
foreach ($array as $key => $value)
{
dfs($value, $parent . '_' . $key);
}
}
else
{
$result[] = ltrim($parent, '_');
}
return $result;
}
echo '<pre>';
print_r(dfs($arr));
echo '</pre>';
Outputs:
Array
(
[0] => Student_Address_StreetAddress
[1] => Student_Address_StreetName
[2] => Student_Marks1
[3] => Student_Marks2
)
Something like this maybe?
$schema = array(
'Student' => array(
'Address' => array(
'StreetAddresss' => "Some Street",
'StreetName' => "Some Name",
),
'Marks1' => 100,
'Marks2' => 50,
),
);
$result = array();
function walk($value, $key, $memo = "") {
global $result;
if(is_array($value)) {
$memo .= $key . '_';
array_walk($value, 'walk', $memo);
} else {
$result[] = $memo . $key;
}
}
array_walk($schema, 'walk');
var_dump($result);
I know globals are bad, but can't think of anything better now.
Something like this works:
<?php
$arr = array (
'Student' => array (
'Address' => array (
'StreetAddress' => 'Some Street',
'StreetName' => 'Some Name',
),
'Marks1' => array(),
'Marks2' => '50',
),
);
$result = array();
function dfs($data, $prefix = "") {
global $result;
if (is_array($data) && !empty($data)) {
foreach ($data as $key => $value) {
dfs($value, "{$prefix}_{$key}");
}
} else {
$result[substr($prefix, 1)] = $data;
}
}
dfs($arr);
var_dump($result);
?>
This prints:
array(4) {
["Student_Address_StreetAddress"] => string(11) "Some Street"
["Student_Address_StreetName"] => string(9) "Some Name"
["Student_Marks1"] => array(0) {}
["Student_Marks2"] => string(2) "50"
}
function getValues($dataArray,$strKey="")
{
global $arrFinalValues;
if(is_array($dataArray))
{
$currentKey = $strKey;
foreach($dataArray as $key => $val)
{
if(is_array($val) && !empty($val))
{
getValues($val,$currentKey.$key."_");
}
else if(!empty($val))
{
if(!empty($strKey))
$strTmpKey = $strKey.$key;
else
$strTmpKey = $key;
$arrFinalValues[$strTmpKey]=$val;
}
}
}
}

PHP optional function arguments with array. How to code / Better way to code?

I'm sure there is a better to this. Any help will be greatly appreciated.
I want to pass an array to a php function that contains the argument and all the arguments are optional. I'm using code ignitor and am by no means an expert. Below is what i have been using so far:
function addLinkPost($postDetailArray) {
if (isset($postDetailArray['title'])) {
$title = $postDetailArray['title']; }
else {
$title = "Error: No Title";
}
if (isset($postDetailArray['url'])) {
$url = $postDetailArray['url'];
} else {
$url = "no url";
}
if (isset($postDetailArray['caption'])) {
$caption = $postDetailArray['caption'];
} else {
$caption = "";
}
if (isset($postDetailArray['publish'])) {
$publish = $postDetailArray['publish'];
} else {
$publish = TRUE;
}
if (isset($postDetailArray['postdate'])) {
$postdate = $postDetailArray['postdate'];
} else {
$postdate = "NOW()";
}
if (isset($postDetailArray['tagString'])) {
$tagString = $postDetailArray['tagString'];
} else {
$tagString = "";
}
You can use an array of defaults and then merge the argument array with the defaults. The defaults will be overridden if they appear in the argument array. A simple example:
$defaults = array(
'foo' => 'aaa',
'bar' => 'bbb',
'baz' => 'ccc',
);
$options = array(
'foo' => 'ddd',
);
$merged = array_merge($defaults, $options);
print_r($merged);
/*
Array
(
[foo] => ddd
[bar] => bbb
[baz] => ccc
)
*/
In your case, that would be:
function addLinkPost($postDetailArray) {
static $defaults = array(
'title' => 'Error: No Title',
'url' => 'no url',
'caption' => '',
'publish' => true,
'postdate' => 'NOW()',
'tagString' => '',
);
$merged = array_merge($defaults, $postDetailArray);
$title = $merged['title'];
$url = $merged['url'];
$caption = $merged['caption'];
$publish = $merged['publish'];
$postdate = $merged['postdate'];
$tagString = $merged['$tagString'];
}
You could do it like this:
function addLinkPost(array $postDetailArray)
{
$fields = array(
'key' => 'default value',
'title' => 'Error: No Title',
);
foreach ($fields as $key => $default) {
$$key = isset($postDetailArray[$key]) ? $postDetailArray[$key] : $default;
}
}
Simply edit the $fields array with your key and its default value.
Using the array as an argument is a good idea in this case. However, you could simplify the code in the function a bit by using the ternary operator (http://dk.php.net/ternary):
$title = isset($postDetailArray['title']) ? $postDetailArray['title'] : 'Error: No Title';
You could simplify it even more by doing the following:
function addLinkPost($data) {
$arguments = array('title', 'url', 'caption', 'publish', 'postdate', 'tagString');
foreach ($arguments as $value) {
$$value = isset($data[$value]) ? $data[$value] : 'Error: No '.$value;
}
}
Try this:
function addLinkPost($postDetailArray) {
foreach($array as $key=>$value){
$$key = (isset($value) && !empty($value)) ? $value : ('no '.$key);
}
//all keys are available as variables
var_dump($url); var_dump($publish); //etc
}
You could make all elements of the array parameters of the function. Check if the first is an array in the function and if so, extract the array.
function addLinkPost($title = null, $url = null, $caption = null, $publish = null, $postDate = null, $tagString = null)
{
if(is_array($title)) {
extract($title);
}
....
}
Maybe that makes the code a little more clear.
How about:
function getdefault($value, $default = null) {
return isset($value) ? $value : $default;
}
function addLinkPost($postDetailArray) {
$title = getdefault($postDetailArray['title'], 'Error: No Title');
$url = getdefault($postDetailArray['url'], 'no url');
$caption = getdefault($postDetailArray['caption'], '');
$publish = getdefault($postDetailArray['publish'], TRUE);
$postdate = getdefault($postDetailArray['postdate'], 'NOW()');
$tagString = getdefault($postDetailArray['tagString'], '');
}
or alternatively:
$defaults = array(
'title' => 'Error: No Title',
'url' => 'no url',
'caption' => '',
'publish' => TRUE,
'postdate' => 'NOW()',
'tagString' => '',
);
function addLinkPost($postDetailArray) {
global $defaults;
foreach ($defaults as $k => $v) {
$$k = isset($postDetailArray[$k]) ? $postDetailArray[$k] : $v;
}
}
With the one warning that if you have an array key of 'defaults' in $defaults, it will overwrite the global $defaults.

Categories