Cannot add data to PHP array in CodeIgniter - php

I have a PHP array, actually a MySQL row constructed with CodeIgniter's Active Record.
So I have an array which var_dumps like this :
array (size=10)
0 =>
array (size=4)
'user_id' => string '2' (length=1)
'puzzle_id' => string '17' (length=2)
'birth' => string '2014-01-26 16:08:25' (length=19)
1 =>
array (size=4)
'user_id' => string '2' (length=1)
'puzzle_id' => string '16' (length=2)
'birth' => string '2014-01-26 02:07:05' (length=19)
2 => .....
this is constructed like this :
$this->db->order_by("birth" , "desc");
$rows = $this->db->get("my_table" , $limit)->result_array();
foreach($rows as $row)
{
$row['testindex'] = "testvalue";
}
return $rows;
so why does my array NOT have the "testindex" indices ?
Thanks for any help !

Because that's not how PHP and foreach() in particular works.
$row in your code is a copy of the corresponding element in $rows, not the actual element. Modifying a copy doesn't modify the original.
You'd want to do this:
for ($i = 0, $c = count($rows); $i < $c; $i++)
{
$rows[$i]['testindex'] = 'testvalue';
}

Try this (PHP 5+):
foreach($rows as &$row)
{
$row['testindex'] = "testvalue";
}

I think I can do this with foreach too.
Like this :
foreach($rows as $key => $value)
{
$rows[$key]['testindex'] = "testvalue";
}

Related

How to avoid errors while parsing through array in PHP?

I am trying to migrate user data from a Drupal database to Wordpress. I'm trying to parse through a data column from Drupal and reorganize it so I can import it where I need to in the Wordpress database. The data column in Drupal is a serialized string:
a:12:{s:23:"profile_membership_type";s:4:"Full";s:21:"ms_membership_add_new";s:0:"";s:18:"ms_membership_mpid";s:0:"";s:25:"ms_membership_amount_paid";s:0:"";s:32:"ms_membership_transaction_number";s:0:"";s:30:"ms_membership_current_payments";i:1;s:26:"ms_membership_max_payments";s:0:"";s:24:"ms_membership_start_date";a:3:{s:4:"year";s:4:"2014";s:5:"month";s:1:"2";s:3:"day";s:2:"13";}s:27:"ms_membership_should_expire";b:0;s:24:"ms_membership_expiration";a:3:{s:4:"year";s:4:"2014";s:5:"month";s:1:"2";s:3:"day";s:2:"13";}s:20:"ms_membership_status";i:3;s:7:"contact";i:1;}
I keep getting this error:
Warning: Invalid argument supplied for foreach()
This is my code thus far:
$fixed = preg_replace_callback(
'/s:([0-9]+):\"(.*?)\";/',
function ($matches) { return "s:".strlen($matches[2]).':"'.$matches[2].'";'; },
$data
);
$original_array = unserialize($fixed);
foreach ($original_array as $key => $value) {
echo $value['profile_membership_type'];
};
check with if condition before iteration
if(is_array($original_array) && !empty($original_array)){
foreach ($original_array as $key => $value) {
echo $value['profile_membership_type'];
}
}
Just cast to an array.
foreach ( (array) $original_array as $key => $value) {
echo $value['profile_membership_type'];
}
You can easily check to see if the variable you're iterating through is an array;
if(isset($original_array) && is_array($original_array)) {
foreach ( $original_array as $key => $value) {
echo $value['profile_membership_type'];
}
}
Edited to include a check to ensure the variable exists.
You have a php serialized string.
I presume the leading f in your question is a typo, as the rest is a valid serialized array:
$array = unserialize('a:12:{s:23:"profile_membership_type";s:4:"Full";s:21:"ms_membership_add_new";s:0:"";s:18:"ms_membership_mpid";s:0:"";s:25:"ms_membership_amount_paid";s:0:"";s:32:"ms_membership_transaction_number";s:0:"";s:30:"ms_membership_current_payments";i:1;s:26:"ms_membership_max_payments";s:0:"";s:24:"ms_membership_start_date";a:3:{s:4:"year";s:4:"2014";s:5:"month";s:1:"2";s:3:"day";s:2:"13";}s:27:"ms_membership_should_expire";b:0;s:24:"ms_membership_expiration";a:3:{s:4:"year";s:4:"2014";s:5:"month";s:1:"2";s:3:"day";s:2:"13";}s:20:"ms_membership_status";i:3;s:7:"contact";i:1;}');
var_dump($array);
/*
array (size=12)
'profile_membership_type' => string 'Full' (length=4)
'ms_membership_add_new' => string '' (length=0)
'ms_membership_mpid' => string '' (length=0)
'ms_membership_amount_paid' => string '' (length=0)
'ms_membership_transaction_number' => string '' (length=0)
'ms_membership_current_payments' => int 1
'ms_membership_max_payments' => string '' (length=0)
'ms_membership_start_date' =>
array (size=3)
'year' => string '2014' (length=4)
'month' => string '2' (length=1)
'day' => string '13' (length=2)
'ms_membership_should_expire' => boolean false
'ms_membership_expiration' =>
array (size=3)
'year' => string '2014' (length=4)
'month' => string '2' (length=1)
'day' => string '13' (length=2)
'ms_membership_status' => int 3
'contact' => int 1
*/
Note that there is only a single profile_membership_type element, so there is no need to loop:
echo $array['profile_membership_type']; // Full

Merging array values into single key and multiple values in php

I want the array to merge into a key value pair. look at the example below
Here is my code and array $aExtraFilter
array (size=4)
0 =>
array (size=2)
'key' => string 'CookTech' (length=8)
'value' => string 'Broil' (length=5)
1 =>
array (size=2)
'key' => string 'CookTech' (length=8)
'value' => string 'Pan Fry' (length=7)
2 =>
array (size=2)
'key' => string 'CookSkills' (length=10)
'value' => string 'Intro' (length=5)
3 =>
array (size=2)
'key' => string 'CookSkills' (length=10)
'value' => string 'Knife Skills' (length=12)
Here is my code:
$aExtraFilter2 = [];
$extrafilterkey = '';
$extrafiltervalue = [];
foreach ($aExtraFilter as $key => $value) {
$extrafilterkey = $value['key'];
$aExtraFilter2[$extrafilterkey] = [];
array_push($extrafiltervalue, $value['value']);
$aExtraFilter2[$extrafilterkey] = implode(',', $extrafiltervalue);
}
var_dump($aExtraFilter2);
the output is :
array (size=2)
'CookTech' => string 'Broil,Pan Fry' (length=13)
'CookSkills' => string 'Broil,Pan Fry,Intro,Knife Skills' (length=32)
I want it to look like this:
array (size=2)
'CookTech' => string 'Broil,Pan Fry' (length=13)
'CookSkills' => string 'Intro,Knife Skills' (length=32)
I think I'm almost there but I guess I need some help.
This line does nothing because it is superseded just a bit later as the same variable is being set:
$aExtraFilter2[$extrafilterkey] = [];
This line appends to the array regardless of what you have as $value['key'], which is why you get all keys lumped together in the output:
array_push($extrafiltervalue, $value['value']);
This will produce a desired output:
// fill array of arrays
$aExtraFilter2 = [];
foreach ($aExtraFilter as $key => $value) {
if (!array_key_exists($value['key'], $aExtraFilter2)) $aExtraFilter2[$value['key']] = [];
$aExtraFilter2[$value['key']][] = $value['value'];
}
// convert to string (if needed at all, depends on what you're doing later)
foreach ($aExtraFilter2 as $key => $set) {
$aExtraFilter2[$key] = join(',', $set);
}
The typical way to code this is by creating a temporary structure, based on the key and comprising an array with the values:
$tmp = [];
foreach ($aExtraFilter as $pair) {
$tmp[$pair['key']][] = $pair['value'];
}
The structure would look like this afterwards:
[
'CookTech' => ['Broil', 'Pan Fry'],
'CookSkills' => ['Intro', 'Knife Skills'],
]
Then, you map that array against the representation you want to have:
$aExtraFilter2 = array_map(function($values) {
return join(',', $values);
}, $tmp);
See also: array_map()

How to remove a specific index from a multidimensional array in php

I am trying to remove pieces of a multidimensional array if a certain condition is met. The array can be as shown below, call it $friends:
array (size=3)
0 =>
array (size=1)
0 =>
object(stdClass)[500]
public 'id' => int 2
public 'first_name' => string 'Mary' (length=4)
public 'last_name' => string 'Sweet' (length=5)
1 =>
array (size=1)
0 =>
object(stdClass)[501]
public 'id' => int 9
public 'first_name' => string 'Joe' (length=3)
public 'last_name' => string 'Bob' (length=3)
2 =>
array (size=1)
0 =>
object(stdClass)[502]
public 'id' => int 1
public 'first_name' => string 'Shag' (length=4)
public 'last_name' => string 'Well' (length=4)
I have a function called is_followed, that let's me see if the id of one of the people in the array is being followed by the "user". The code I am trying is:
//remove followed friends from the $friends array
$i=0;
foreach($friends as $friend) {
foreach($friend as $f) {
if(Fanfollow::is_followed($id,$f->id)) {
unset($friend[$i]);
}
}
$i++;
}
The $id is the id of the current user.
However, this is not working. I know that using unset on $friend and not $friends is probably the issue. But using unset on $friends also won't work, because it is the higher level array. Any ideas? Thank you.
If you're trying to take down the first parent keys, use the first foreach keys instead:
foreach($friends as $i => $friend) {
// ^ assign a key
foreach($friend as $f) {
if(Fanfollow::is_followed($id,$f->id)) {
unset($friends[$i]);
// unset this
}
}
}
Or if only for that single friend:
foreach($friends as $friend) {
foreach($friend as $i => $f) {
// ^ this key
if(Fanfollow::is_followed($id,$f->id)) {
unset($friend[$i]);
// unset this
}
}
}
array_filter comes to the rescue:
array_filter($friend,
function($f) use($id) { return Fanfollow::is_followed($id,$f->id)); }
);
Though the solution with foreach is legit, array_filteris much more clear and sematically correct.

Why does assigning a new value to an array fail in PHP?

Consider:
array (size=1)
0 =>
array (size=5)
'name' => string '15268459735 Farming and Projects XXXXX' (length=38)
'region' => string '2' (length=1)
'entitynumber' => string '2012/002086/24' (length=14)
'ownership' => string '6' (length=1)
'id' => string '26249' (length=5)
Why does the following still return the same array without the owner element?
foreach ($result as $row)
{
$row['owner'] = 1;
}
Try passing the array by reference:
foreach ($result as &$row) {
$row['owner'] = 1;
}
See also: What's the & for, anyway?

Multi Dimensional array - Maintaining data integrity

I've got the current array
array
161 =>
array
'cat_id' => string '5' (length=1)
'temp_id' => string '2' (length=1)
'prod_id' => string '44' (length=2)
162 =>
array
'cat_id' => string '3' (length=1)
'temp_id' => string '2' (length=1)
'prod_id' => string '44' (length=2)
164 =>
array
'cat_id' => string '2' (length=1)
'temp_id' => string '2' (lenth=1)
'prod_id' => string '45' (length=2)
I am using this function to remove the duplicate array values:
function removeDupes($array) {
$temp = array();
foreach ($array as $k => &$v) {
if (in_array($v['prod_id'],$temp)) {
unset($array[$k]);
}
$temp[] = $v['prod_id'];
}
return $array;
}
This removes any duplicate value in the array if prod_id is a duplicate in a previous array.
I'd like to maintain the full category id list for the product and at the moment, these get deleted when I unset the entire key=>value pair.
Has anyone got any ideas how I could achieve this?
EDIT as per comment:
I'm looking for something like this as a result:
array
161 =>
'cat_id' => array('5','3')
'prod_id' => 44
So I have removed the duplicate array entry that duplicated the product ID but maintained the Category ID's. I hope that helps.
Maybe something like this:
$input = array(); // define your array
$output = array(); // here will be output
$temp = array();
foreach($input as $key => $value)
{
if (isset($temp[$value['prod_id']]))
{
$output[$temp[$value['prod_id']]]['cat_id'][] = $value['cat_id'];
}
else
{
$output[$key] = array(
'cat_id' => array($value['cat_id']),
'prod_id' => $value['prod_id']
);
$temp[$value['prod_id']] = $key;
}
}
First thing that came to my mind is to iterate over your structure, build a helping structure of array_index => prod_id of first occurrence (for this example array(44 => 161, 45 => 164)). You remove every but first and at the same time add prod_id to the first one found.

Categories