foreach results in endless loop - php

I have an array stored in $_SESSION:
var_dump($_SESSION['session_article']);
//result:
array(2) {
[0]=> array(2) {
["id"]=> string(1) "3"
["amount"]=> int(2)
}
[1]=> array(2) {
["id"]=> string(2) "13"
["amount"]=> int(1)
}
}
If I do:
for($artKey = 0;$artKey < count($_SESSION['session_article']);$artKey++){
$cartArt = $_SESSION['session_article'][$artKey];
//stuff that doesn't affect key or value
}
everything is fine ...but if I do:
foreach($_SESSION['session_article'] as $artKey => $cartArt){
//stuff that doesn't affect key or value
}
the page won't stop to load (infinite loading, like the foreach never terminates)

I would like to you know that the computer is not a dumb machine, so whenever you do not get the right result then its not the computers problem, it is in how you code.
So lets take a look at your code first you var_dump($_SESSION['session_article']) you got an array with two elements each being an associative array. Now observe that this is an array of arrays so you code in scenario 2 is wrong.
If it were to be just a single array say $myArray = ['Simon', 'Peter', 'You'] then this woul have worked fine (note I used the short array syntax here you can use array() if you prefer). But the problem is you have multidimensional Arrays so you could should be
foreach($_SESSION['session_article'], list($a,))
{
//stuffs here
}
or better walk through the $_SESSION['session_article'] as an associative array like so
$myArray = $_SESSION['session_article']
$field = count($myArray, COUNT_RECURSIVE - (int)2)
for ($record = 0; $record < $myArray.length; $record++) {
//record number
for ($field = 0; $field < $field ; $field++) {
//combine record and field here
}
}
Hope I could lend a helping hand?
Please checkout
http://php.net/manual/en/function.count.php
http://php.net/manual/en/control-structures.foreach.php
They really have a good doc, just take you time.

Related

Inefficient nested foreach loop

I have two array and want to merge it by using key of main array;
// $result : main dataset (multidimensional array)
// $referenceData : data related with main dataset and want to merge it into main dataset (multidimensional array)
if ($result) {
foreach ($result as $key => $val) {
foreach ($referenceData[$val['id']] as $refKey => $refVal) {
$result[$key][$refKey] = $refVal;
}
}
}
The thing is, when the result is high (even for 1000 elements on each) it takes more than 5-10 seconds which is quite unexpected for me.
I tried to use array_merge and array_merge_recursive instead of two foreach but I kept failing. Is there any way I could improve the logic? Thanks in advance.
Edit (added sample array);
result :
array(1) {
[0]=>
array(6) {
["id"]=>
string(5) "13020"
["name"]=>
string(23) "Data Stream 1"
["rank"]=>
string(1) "3"
["data_1"]=>
string(2) "63"
["data_2"]=>
string(2) "256"
["data_3"]=>
string(3) "469"
}
}
referenceData:
array(1) {
[13020]=>
array(5) {
["percent"]=>
float(20.987654320988)
["count_min"]=>
string(1) "1"
["count_max"]=>
int(2)
["checked"]=>
bool(false)
["cond_id"]=>
string(1) "0"
}
}
You need to make the first array structure exactly like the second array so that you can easily merge them. To do so you can do like below : (Its a reference code, you need to change it at your end)
$rows = $db->table('<table name>')->get()->getResultArray();
$result = [];
foreach ($rows as $row) {
$result[$row['id']] = $row;
}
Once both arrays have a similar structure, then you can go for a single foreach() and + operator to combine child arrays.
$finalArray = [];
foreach($result as $key=>$value){
$finalArray[$key] = $value+$referenceData[$key];
}
print_r($finalArray);
Output: https://3v4l.org/qBa4V
Note: if you want to re-index this new array (in case you want indexes like 0,1,2... so on) then you can do:
$finalArray = array_values($finalArray);

find if value exist in php into mysql built array

i build an array from mysql this way
$q="select account_code from chart_master;";
// Generate resultset
$result_set = $con->query($q);
$list = Array();
while( $myrow = mysqli_fetch_array($result_set) ) {
$list[] = $myrow;
}
when i dump $list i get:
array(79) { [0]=> array(2) { [0]=> string(8) "11011001" ["account_code"]=> string(8) "11011001" } [1]=> array(2) { [0]=> string(8) "11011002" ["account_code"]=> string(8) "11011002" } [2]=> array(2) { [0]=> string(8) "11011005" ["account_code"]=> string(8) "11011005" } ...
i now want to check if a value is found in the values 11011001, 11011002 etc with this code:
if (in_array($row['1'], $list))
{
echo $row['1']." found in the array";
}
with $row['1'] being one of the searched value.
I guess I am not looking at the right depth in the array because my in_array does not return anything.
Thoughts?
You should go through each element of your $list array and apply in_array to it.
foreach($list as $listItem){
if(in_array($row['1'], $listItem)){
echo $row['1']." found in the array";
}
}
in_array() only checks one dimension. That's why you need to go iterate through the first dimension and apply it to the second one.
The most succinct version of this I can imagine would be:
$exists = array_search('1001010101', array_column($list, 'account_code')) !== false;
This grabs the account_code column from the multidimensional array and looks inside that column for the value provided. If you only need an existence check, this seems to be a fast way of doing it.
However, if you don't need the rest of that SQL result set, I'd look into maybe doing a COUNT() or using a WHERE to narrow the result set instead. That would be more resource efficient.

How to merge specific key to one array with PHP?

I need to get that value in the array with "clean_bin_number" and pull it out from each of the main arrays. And have only the values in one array.
Hopefully you guys can understand what I'm trying to do....
Here some code examples:
array(2) {
[0]=>
array(1) {
["clean_bin_number"]=>
array(1) {
[0]=>
array(1) {
[0]=>
string(7) "1004445"
}
}
}
[1]=>
array(1) {
["clean_bin_number"]=>
array(1) {
[0]=>
array(1) {
[0]=>
string(7) "3087762"
}
}
}
}
I'd like to get a result like that:
array {
[0] => "1004445",
[1] => "3087762"
}
Thanks
Here are some ways to go about what you want to achieve:
array_walk array_map for foreach
Hint:
foreach($array as $inner)
{
$bin = $inner["clean_bin_number"][0][0];
// ...
}
So your input array is:
$input = array(
array("clean_bin_number" => array(array("1004445")) ),
array("clean_bin_number" => array(array("3087762")) )
);
Now you can very easily just iterate over that array and extract the routes/parts you need, or if those exist not only once, iterate over the sub parts.
Example:
$new_arr = array();
foreach ($input as $element) {
$new_arr[] = $element['clean_bin_number'][0][0];
}
See this working here.
You should have been able to find another solution thou. If not, you have clearly not finished reading/watching beginner tutorials for PHP. Go do that if you want to keep working with PHP. Find Tutorials online like this youtube video or this article.
Asking questions to get specific solutions takes longer than actually doing a bit of learning if you ask me.

Assign value to array in for loop

I know init php array method is
$a=array("星期日","星期一","星期二","星期三","星期四","星期五","星期六");
but i must assign in two dim array, such data is
[0]=> array(6) { ["id"]=> string(1) "2" ["menu_name"]=> string(12) "小吃菜單" ["button_pic_save_path"]=> string(40) "/images/left_button/menu/normal_menu.gif" ["cover_button_pic_save_path"]=> string(46) "/images/left_button/menu/normal_menu_cover.gif" ["order_number"]=> string(1) "0" ["modify_time"]=> string(19) "2013-04-07 09:37:43" } }
[1]=> array(6) { ["id"]=> string(1) "3" ["menu_name"]=> string(12) "小吃菜單" ["button_pic_save_path"]=> string(40) "/images/left_button/menu/normal_menu.gif" ["cover_button_pic_save_path"]=> string(46) "/images/left_button/menu/normal_menu_cover.gif" ["order_number"]=> string(1) "0" ["modify_time"]=> string(19) "2013-04-07 09:37:43" } }
now my Implement code as follow..
$query_menu_data = select_sql(QUERY_MENU_SQL_STR);
if(count($query_menu_data) >= 1)
{
$ary_menu[count($query_menu_data)];
for($loop_i = 0; $loop_i < count($query_menu_data); $loop_i++)
{
for($loop_j = 0; $loop_j < count($ARY_MENU_FIELD); $loop_j++)
{
// hash key
/*
$ary_menu[$loop_i] = array(
$ARY_MENU_FIELD[$loop_j] => $query_menu_data[$loop_i][$loop_j]
);
*/
$ary_menu[$loop_i] = array(
$ARY_MENU_FIELD[$loop_j] => $query_menu_data[$loop_i][$loop_j]
);
} // end loop j
} // end loop i
}
the result of array always save the last data, what method can I solve it.
Thank to every body, the solve method is in comment.
You need to initialize the menu entry. after doing that you need to fill each menu field for this menu.
code:
for($loop_i = 0; $loop_i < count($query_menu_data); $loop_i++)
{
$ary_menu[$loop_i] = array();
for($loop_j = 0; $loop_j < count($ARY_MENU_FIELD); $loop_j++)
{
// hash key
/*
$ary_menu[$loop_i] = array(
$ARY_MENU_FIELD[$loop_j] => $query_menu_data[$loop_i][$loop_j]
);
*/
$ary_menu[$loop_i][$ARY_MENU_FIELD[$loop_j]] = $query_menu_data[$loop_i][$loop_j];
} // end loop j
} // end loop i
i cant verify, if $query_menu_data has the correct data structure, but from your problem description, there should be no problem there.
It looks like your inner loop (loop_j) may never execute since you did not have $ARY_MENU_FIELD defined before you first execute it (and it is created/modified inside that loop). Is there other code you are not showing?
When you encounter problems with arrays only containing the "last" bit of data after a traversal/loop, you should assume that you are making an overwriting error somewhere.
Looking at your loop, the assignment comes in the second loop, with...
$ary_menu[$loop_i] = array(...
The = equals sign above should be the clue your looking for. You're assigning the index of $loop_i in the array $ary_menu over and over, every time the inner $loop_j for-loop runs. This is where the reassignment occurs.
Since I do not know exactly what you're trying to look for in a final array, I can only give an assumption on a solution. This might be doing something like...
$ary_menu[$loop_i][] = array(....)
What this will do is essentially make $ary_menu[$loop_i] an array of its own, appending the new value in each loop iteration. This will solve the problem of overwriting. But again, I'm not sure if that's what you're looking to do.

How to rename the key in a foreach loop?

I'm trying to generate an XML from a database call, and the utility class I'm using throws an error Illegal character in tag name. tag: 0
I figured this is because of the array being [0],[1],[2] etc. Really I should set them all to be something standard, like 'asset' since they are all assets, but I can't do that because then keys will be identical, but maybe the ID would work. But I don't know how to change the key that I'm on within a foreach loop.
I tried:
foreach ($assets as &$key => &$asset) {
$key2 = $asset->isci;
$asset = get_object_vars($asset);
}
But I cannot pass reference for $key.
This is a brief representation of what the array looks like:
array(2) {
[0]=>
array(25) {
["id"]=>
string(2) "27"
}
[1]=>
array(25) {
["id"]=>
string(2) "25"
}
[2]=>
array(25) {
["id"]=>
string(1) "1"
}
}
Modifying keys of an array while looping over it is generally a bad idea - even if the language supported it, it can be very confusing to debug.
The simplest approach is to simply build a new array based on the old one, but with better keys:
$rekeyed_assets = array();
foreach ($assets as $old_key => $asset)
{
$new_key = $asset->isci;
$asset = get_object_vars($asset);
$rekeyed_assets[ $new_key ] = $asset;
}
The most convenient way is to change all the keys and then use array_combine to create a new array with the modified keys. Here's how you can do that in bulk using array_map and an anonymous function:
$newKeys = array_map(function($asset) { return $asset->isci; }, $assets);
$assets = array_combine($newKeys, $assets);
You can also do the same for the values:
$newKeys = array_map(function($asset) { return $asset->isci; }, $assets);
$newValues = array_map(function($asset) { return get_object_vars($asset); }, $assets);
$assets = array_combine($newKeys, $newValues);
This method does have a drawback (increased memory usage) which may be an issue if your array has millions of items, but in that case it's highly likely that it would be better to restructure the program so that it does not need to keep huge arrays in memory in the first place.

Categories