Why is php handling for different than foreach? - php

I made an array $brands inside class Cars, the print_r output looks like this:
Array ( [0] => Array ( [id] => 1
[name] => 'Porsche'
)
[1] => Array ( [id] => 2
[name] => 'Bugatti'
)
[2] => Array ( [id] => 3
[name] => 'BMW'
)
)
But when I'd like to link to a certain brand, I don't want to use strtolower() to make a lowercased hyperlink. I would like to echo $cars->brands[$i]['url'] (instead of strtolower($cars->brands[$i]['name'])).
class Cars {
So I needed to create a for loop, to create the ['url'] key in the array. I thought that a foreach would work:
foreach ($this->brands as $brand => $row) {
$row['url'] = strtolower($row['name']);
}
But it didn't. Even this did not work: $row['name'] = strtolower($row['name']);.
But this worked, though:
for ($i = 0; $i < count($this->brands); $i++) {
$this->brands[$i]['url'] = strtolower($this->brands[$i]['name']);
}
}
My question here is: how? why?

You need to work on a reference. Insert a & and it will work
foreach ($this->brands as $brand => &$row) {
$row['url'] = strtolower($row['name']);
}
or you could work on the original array like:
foreach ($this->brands as $brand => $row) {
$this->brands[$brand]['url'] = strtolower($row['name']);
}

if you want to edit the element being iterated you can add a & before $row
foreach ($this->brands as $brand => &$row) {
$row['url'] = strtolower($row['name']);
}
but this is not necessary, just access the array from the variable available outside of the foreach loop e.g $this->brands
foreach ($this->brands as $brand => $row) {
$this->brands[$brand]['url'] = strtolower($row['name']);
}

because you are overwriting array key('url').
$row is a local copy of $this->brands any changes to $row will not reflect on $this->brands.
change this
foreach ($this->brands as $brand => $row) {
$row['url'] = strtolower($row['name']);
}
with this
foreach ($this->brands as $brand => $row) {
$this->brands[$brand]['url'] = strtolower($row['name']);
}
Happy Coding.

Related

Build tree from foreach loop php

I have following foreach loop :
foreach($mydata as $data){
$section = $data->section;
$category = $data->category;
$item = $data->item;
}
I want to build tree like this :
- section
_ category
- items
...
For now i did like this :
$tmp = [];
$newarray = [];
foreach($mydata as $data){
$section = $data->section;
$category = $data->category;
$item = $data->item;
if( !in_array($category, $temp)){
$newarray[$section][] = $category;
}
}
// output:
Array(
[SectionName_one] => Array(
[0] => categoryOneName_one
[1] => categoryOneName_two
[2] => categoryOneName_three
)
[SectionName_two] => Array(
[0] => categoryTwoName_one
[1] => categoryTwoName_two
[2] => categoryTwoName_three
)
...
)
And i am blocked here, i don't know how to insert items elements for each category, if you hava an idea thanks to help me :)
Thank you
foreach ($mydata as $data){
$newarray[$data->section][$data->category][]= $data->item;
}
PHP is quite forgiving with non-existent array keys.

Retrieving data from Multi dimensional Array in Codeigniter

I can't quite get my data from an array, it just shows a blank list of list items when I run my foreach loop.
When I print my array it outputs the following:
Array (
[Description] => Array (
[0] => sidewindo
[1] => sidewindo
[2] => sidewindo
[3] => testing )
[comments] => Array (
[0] => sidewindo
[1] => sidewindo
[2] => sidewindo
[3] => testing )
[Fld_id] => 625
[fld_IsPublic] => Array (
[0] => 1 )
[action] => s
[pk_id] => 7 )
My code so far
public function save_data($data)
{
foreach ($data as $row)
{
foreach ($row['Description'] as $show)
{
echo $show;
}
}
And i have tried the following kind of for loop also to retrieve data from the array. I am trying to retrieve data from the array and update it in another table in the database. This code I have written in my model before passing it to the view.
for($i=0;$i<count($comments);$i++)
{
$this->db->update->update('tblname',array('TK_id'=>$data['pk_id'],'Fld_id'=>$data['Fld_id'],'fld_description'=>$data['Description'],'fld_comments'=>$data['comments'],'fld_IsPublic'=>$data['fld_IsPublic']),array('TK_id'=>$data['pk_id'],'Fld_id'=>$data['Fld_id']));
}
}
First of all you should know that echo an array will produce a Notice ( Array to string conversion ), so depending in what environment you are working on you will prefer to use print_r.
Answering your question, before you echo, you should check if it's an array or not
public function save_data($data){
$update = array();
foreach ($data as $key=>$row){
if(is_array($row)){
foreach($row as $key2=>$row2){
$update[$key2] = $row2;
//echo $row2 . "<br>";
}
}else{
$update[$key] = $row;
//echo $row ."<br>";
}
}
}
And now you can use $update to update your table , include this on inside save_data() function, and if you needed, include save_data() inside a foreach. Remember that is recommended to use a where when updating data so:
//$this->db->where('id', $id);
$this->db->update('tblname', $update);
hope that helps
Change Your code from
public function save_data($data)
{
foreach ($data as $row)
{
foreach ($row['Description'] as $show)
{
echo $show;
}
}
to
public function save_data($data)
{
foreach ($data["comments"] as $key=>$row)
{
$data_update = array(
'TK_id' => $data['pk_id'],
'Fld_id' => $data['Fld_id'],
'fld_description' => $data['Description'][$key],
'fld_comments' => $row,
'fld_IsPublic' => $data['fld_IsPublic'][0]
);
$this->db->update('tblname',$data_update,array('TK_id'=>$data['pk_id'],'Fld_id'=>$data['Fld_id']));
//but this will update single row again and again
//my suggetion is use $this->db->insert('tblname',$data_update); instead
}
}
ANd you will be just fine

Trouble printing array using for loop

This is my array structure:
Array
(
[Title] => Array
(
[0] =>
[1] => One
[2] => Two
[3] => Three
[4] => Four
[5] => test
[6] => fsfd
[7] => wa
)
)
I would like to print the title and array elements so that it is structured like this:
Title
One
Two
Three
etc
I am currently having trouble doing this using the conventional for each loop:
foreach($items as $key => $notice ){?>
}?>
What is the best way to do this? Thanks
Your array is nested. Either use
foreach($items['Title'] as $key => $noticeArr ){
Or if you wish to print the keys of the first array use:
foreach($items as $key => $noticeArr ){
echo $key . "\n";
foreach($noticeArr as $notice){
echo $notice . "\n";//Wrap in <li> tags or however you want to display.
}
}
You have an array "Title" inside your array.
You could use the traditional for loop:
for ($i = 0; $i < count($yourArray['Title']); $i++) {
echo $yourArray['Title'][$i];
}
or a foreach:
foreach ($yourArray['Title'] as $item) {
echo $item;
}
You just have to iterate two times, one for the first array and another for the nested one.
$data = array(
'Title' => array('One','Two','Three'),
);
foreach ($data as $name => $results) {
echo $name . "<br />";
foreach ($results as $label)
{
echo $label . "<br />";
}
}
Try this, will work
foreach($items as $key => $noticeArr ){
echo $key . "<br />";
$array = array_filter($noticeArr, create_function('$a','return $a!=="";'));
foreach($array as $notice){
echo "<li>".$notice ."</li>"."<br />";
}
}

Retrieve subarray of array by key value

I have the following array (example, real one is larger)
Array
(
[0] => Array
(
[984ab6aebd2777ff914e3e0170699c11] => Array
(
[id] => 984ab6aebd2777ff914e3e0170699c11
[message] => Test1
)
[1] => Array
(
[ca403872d513404291e914f0cad140de] => Array
(
[id] => ca403872d513404291e914f0cad140de
[message] => Test2
)
)
[2] => Array
(
[ca403872d513404291e914f0cad140de] => Array
(
[id] => ca403872d513404291e914f0cad140de
[message] => Test3
)
[3] => Array
(
[ca403872d513404291e914f0cad140de] => Array
(
[id] => ca403872d513404291e914f0cad140de
[message] => Test4
)
)
)
Now I want to somehow "access" the subarray with a given id, e.g. access the subarray with ID 984ab6aebd2777ff914e3e0170699c11 and then proceed to use this array in a foreach like this..
foreach ($array_with_specific_id as $event) {
echo $event['message'];
}
Is this possible?
Edit:
DB code to produce array in my model:
public function get_event_timeline($id)
{
$data = array();
foreach ($id as $result) {
$query = $this->db->query("SELECT * FROM event_timeline WHERE id = ?", array($result['id']));
foreach ($query->result_array() as $row)
{
array_push($data, array($row['id'] => $row));
}
}
return $data;
}
When populating your array from the database you can cerate an additional $index array like the following scheme:
$index = array (
'984ab6aebd2777ff914e3e0170699c11' => ReferenceToElementInData,
'ca403872d513404291e914f0cad140de' => ReferenceToElementInData,
// ...
)
This can give you quick access to the elements via their id without an additional foreach loop. Of course it will need additional memory, but this should be ok as you will only save refrences to the original data. However, test it.
Here comes an example:
public function get_event_timeline($id)
{
$data = array();
// create an additional index array
$index = array();
// counter
$c=0;
foreach ($id as $result) {
$query = $this->db->query("SELECT * FROM event_timeline WHERE id = ?", array($result['id']));
// every entry in the index is an array with references to entries in $data
$index[$result['id']] = array();
foreach ($query->result_array() as $row)
{
array_push($data, array($row['id'] => $row));
// create an entry in the current index
$index[$row['id']][] = &$data[$c];
$c++;
}
}
return array (
'data' => $data,
'index' => $index
);
}
Now you can access the elements via the index array without an additional foreach loop:
$entry = $index['984ab6aebd2777ff914e3e0170699c11'][0];
If there are multiple results per $id (as you mentioned in the comments you can access them using index greater then zero:
$entry = $index['984ab6aebd2777ff914e3e0170699c11'][1];
$entry = $index['984ab6aebd2777ff914e3e0170699c11'][2];
You can get the count of items per $id by calling
$number = count($index['984ab6aebd2777ff914e3e0170699c11']);
That's much the same like indexes that where used in databases to speed up queries.
I'd probably just get rid of the containing array as it seems unnecessary. However, you could do something like:
function get_message($specific_id, $arrays) {
foreach($arrays as $array) {
if(in_array($specific_id, $array)) {
return $array['message'];
}
}
}
I haven't had a chance to test this, but it should work.
function doTheJob($inputArray, $lookingFor) {
foreach ($inputArray as $subArray) {
foreach ($subArray as $subKey => $innerArray) {
if ($subKey == $lookingFor) {
return $innerArray;
}
}
}
return NULL;
}
Alternatively, you can use array_filter instead of outer foreach.

Getting values from associative array

I have the following main array called $m
Array
(
[0] => Array
(
[home] => Home
)
[1] => Array
(
[contact_us] => Contact Us
)
[2] => Array
(
[about_us] => About Us
)
[3] => Array
(
[feedback_form] => Feedback Form
)
[4] => Array
(
[enquiry_form] => Products
)
[5] => Array
(
[gallery] => Gallery
)
)
I have the values eg home, contact_us in a array stored $options , I need to get the values from the main array called $m using the $options array
eg. If the $options array has value home, i need to get the value Home from the main array ($m)
my code looks as follows
$c = 0;
foreach($options as $o){
echo $m[$c][$o];
++$c;
}
I somehow just can't receive the values from the main array?
I'd first transform $m to a simpler array with only one level:
$new_m = array();
foreach ($m as $item) {
foreach ($item as $key => $value) {
$new_m[$key] = $value;
}
}
Then you can use:
foreach ($options as $o) {
echo $new_m[$o];
}
Try this:
foreach($options as $o){
foreach($m as $check){
if(isset($check[$o])) echo $check[$o];
}
}
Although It would be better TO have the array filled with the only the pages and not a multidimensional array
Assuming keys in the sub arrays are unique you can
merge all sub arrays into a single array using call_user_func_array on array_merge
swap keys and values of your option array
Use array_intersect_key to retrieve an array with all the values.
Example like so:
$options = array('about_us', 'enquiry_form');
$values = array_intersect_key(
call_user_func_array('array_merge', $m), // Merge all subarrays
array_flip($options) // Make values in options keys
);
print_r($values);
which results in:
Array
(
[about_us] => About Us
[enquiry_form] => Products
)
How's this?
foreach( $options as $option )
{
foreach( $m as $m_key => $m_value )
{
if( $option == $m_key )
{
echo 'Name for ' . $options . ' is ' . $m_value;
break;
}
}
}
Try using a recursive array_walk function, for example
$a = array(
array('ooo'=>'yeah'),
array('bbb'=>'man')
);
function get_array_values($item, $key){
if(!is_numeric($key)){
echo "$item\n";
}
}
array_walk_recursive($a,'get_array_values');
Are you sure that the options array is in the same order of $m? Maybe you your
echo $m[$c][$o];
is resolving into a $m[0]['gallery'] which is obviously empty.
you can try different solutions, to me, a nice one (maybe not so efficient) should be like this:
for($c=0, $limit=count($c); $c < $limit; $c++)
if (array_search(key($m[$c]), $options))
echo current($m[$c]);
If you would like to use your approach have to flatten your array with something like this:
foreach ($m as $o)
$flattenedArray[key($o)]=current($o);
foreach ($options as $o)
echo $flattenedArray($o);
Doing this, though, eliminates duplicate voices of your original array if there are such duplicates.
$trails1 = array();
foreach ($trails as $item) {
foreach ($item as $key => $value) {
$trails1[].= $value;
}
}
echo '<pre>';print_r($trails1);
exit;

Categories