Items in Arrays, are they references? - php

look at the code below:
$index = GetIndexForId($itemid);
$item = null;
if( $index == -1 )
{
$item = array();
$this->items[] = $item;
$index = count($this->items)-1;
}
else
$item = $this->items[$index];
$item['id'] = $itemid;
$item['qty'] = $qty;
$item['options'] = $options;
$this->items[$index] = $item; // This line is my question
The last line, is it necessary? I really dont know how php handles array assignment.
P.S. GetIndexForId just searches for if the current ID already exists in the array, and the other "undeclared" variables are parameters.

From the documentation:
Array assignment always involves value copying. Use the reference operator to copy an array by reference.
So yes, given your code, the last line is necessary, but $this->items[] = $item; is superfluous.

If you want to update your Object, yes you need this last line

Any value type like boolean, int... will not be passed by reference. But if your array is filled with objects, it WILL be passed by reference. In your exemple, you need the last line. But as I said, if $item were an object you wouldn't need the last line. It is possible to pass a value type by reference with the reference operator.
Learn how to use the reference operator
HERE

Related

PHP array_push error

My code is as below,
$products = array();
for($i=0; $i < sizeof($sales); $i++){
if(!in_array($sales[$i]['Product']['product'], (array)$products)){
$products = array_push((array)$products, $sales[$i]['Product']['product']);
}
}
I'm getting an error called Fatal error: Only variables can be passed by reference...
I'm using php5
You don't use array_push like that, that's your basic problem. You're trying to fix an error you're producing by casting $products to an array, which causes a new error. You use array_push like this:
array_push($products, ...);
You do not assign the return value back to $products, because the return value is the new number of elements in the array, not the new array. So either:
array_push($products, $sales[$i]['Product']['product']);
or:
$products[] = $sales[$i]['Product']['product'];
Not:
$products = array_push($products, $sales[$i]['Product']['product']);
and most certainly not:
$products = array_push((array)$products, $sales[$i]['Product']['product']);
Please RTM: http://php.net/array_push
The first parameter ($products in your case) has to be a reference, therefore a variable has to be passed. You now cast the variable to an array first and the result of that cast cannot be passed by reference since it is not assigned to a variable. You will have to assign it to a variable first or remove the cast.

foreach without doing a loop in PHP

How is it possible to perform a foreach function without doing a loop for example
foreach($result['orders'] as $order) {
But I don't want to do a foreach I want something like
$result['orders'] == $order;
Or something like that instead of doing it inside an loop because $result['orders'] is only returning 1 result anyway so I don't see the point in doing it in a loop.
Thank you
You can get the first (and apparently only) element in the array with any array function that gets an element from the array, e.g. array_pop() or array_shift():
$order = array_shift( $result['orders']);
Or list():
list( $order) = $result['orders'];
Or, if you know it's numerically indexed, access it directly:
$order = $results['orders'][0];
Are you maybe just looking for this?
$result['orders'] = $result['orders'][0];
You have a comparison operator (==) rather than an assignment operator (=) in your second code example. If you are just trying to set a variable equal to a position in an array, you can use:
$order = $results['orders'];
I am not sure if that is what you are trying to accomplish though.

Efficiency of using foreach loops to clear a PHP array's values

Which is more efficient for clearing all values in an array? The first one would require me to use that function each time in the loop of the second example.
foreach ($array as $i => $value) {
unset($array[$i]);
}
Or this
foreach($blah_blah as $blah) {
$foo = array();
//do something
$foo = null;
}
I don't want to use unset() because that deletes the variable.
Like Zack said in the comments below you are able to simply re-instantiate it using
$foo = array(); // $foo is still here
If you want something more powerful use unset since it also will clear $foo from the symbol table, if you need the array later on just instantiate it again.
unset($foo); // $foo is gone
$foo = array(); // $foo is here again
If we are talking about very large tables I'd probably recommend
$foo = null;
unset($foo);
since that also would clear the memory a bit better. That behavior (GC) is however not very constant and may change over PHP versions. Bear in mind that re-instantiating a structure is not the same as emptying it.
If you just want to reset a variable to an empty array, you can simply reinitialize it:
$foo = array();
Note that this will maintain any references to it:
$foo = array(1,2,3);
$bar = &$foo;
// ...
$foo = array(); // clear array
var_dump($bar); // array(0) { } -- bar was cleared too!
If you want to break any references to it, unset it first:
$foo = array(1,2,3);
$bar = &$foo;
// ...
unset($foo); // break references
$foo = array(); // re-initialize to empty array
var_dump($bar); // array(3) { 1, 2, 3 } -- $bar is unchanged
Unsetting the variable is a nice way, unless you need the reference of the original array!
To make clear what I mean:
If you have a function wich uses the reference of the array, for example a sorting function like
function special_sort_my_array(&$array)
{
$temporary_list = create_assoziative_special_list_out_of_array($array);
sort_my_list($temporary_list);
unset($array);
foreach($temporary_list as $k => $v)
{
$array[$k] = $v;
}
}
it is not working! Be careful here, unset deletes the reference, so the variable $array is created again and filled correctly, but the values are not accessable from outside the function.
So if you have references, you need to use $array = array() instead of unset, even if it is less clean and understandable.
I'd say the first, if the array is associative. If not, use a for loop:
for ($i = 0; $i < count($array); $i++) { unset($array[$i]); }
Although if possible, using
$array = array();
To reset the array to an empty array is preferable.
Isn't unset() good enough?
unset($array);
How about $array_name = array(); ?
Use array_splice to empty an array and retain the reference:
array_splice($myArray, 0);
i have used unset() to clear the array but i have come to realize that unset() will render the array null hence the need to re-declare the array like for example
<?php
$arr = array();
array_push($arr , "foo");
unset($arr); // this will set the array to null hence you need the line below or redeclaring it.
$arr = array();
// do what ever you want here
?>
Maybe simple, economic way (less signs to use)...
$array = [];
We can read in php manual :
As of PHP 5.4 you can also use the short array syntax, which replaces array() with [].
I see this questions is realla old, but for that problem I wrote a recursive function to unset all values in an array. Recursive because its possible that values from the given array are also an array. So that works for me:
function empty_array(& $complete_array) {
foreach($complete_array as $ckey => $cvalue)
{
if (!is_array($cvalue)) {
$complete_array[$ckey] = "";
} else {
empty_array( $complete_array[$ckey]);
}
}
return $complete_array;
}
So with that i get the array with all keys and sub-arrays, but empty values.
The unset function is useful when the garbage collector is doing its rounds while not having a lunch break;
however unset function simply destroys the variable reference to the data, the data still exists in memory and PHP sees the memory as in use despite no longer having a pointer to it.
Solution:
Assign null to your variables to clear the data, at least until the garbage collector gets a hold of it.
$var = null;
and then unset it in similar way!
unset($var);
The question is not really answered by the posts. Keeping the keys and clearing the values is the focus of the question.
foreach($resultMasterCleaned['header'] as $ekey => $eval) {
$resultMasterCleaned[$key][$eval] = "";
}
As in the case of a two dimensional array holding CSV values and to blank out a particular row. Looping through seems the only way.
[] is nearly 30% faster then as array()
similar as pushing new element to array
$array[] = $newElement then array_push($array, $newElement)
(keep in mind array_push is slower only for single or 2 new elements)
Reason is we skip overhead function to call those
PHP array vs [ ] in method and variable declaration

Want to delete array

Can anyone help me to improve this code? I want to delete array if it already exists. Thanks
if(count($cart['Item']) > 0) {
unset($cart['Item']);
$items['Item'] = array();
$cart = array_merge($cart, $items);
}
Apparently you want the $cart['Item'] variable to be an empty array after this step, no matter what it was before. So:
$cart['Item'] = array();
Done.
if(!empty($cart['Item'])) {
unset($cart['Item']);
}
!empty requires the array item to be both existent and not falsy (e.g. empty)
unset will delete the given key from $cart
However, if you want to replace it with a new, empty array:
$cart['Item'] = array();
No need to do anything else. PHP has a Garbage Collector.
If you just need to check if it exists. using isset() is faster in your case. Then you can just override it without any unsetting.
if( isset($cart['Item']))
{
$cart['Item'] = array();
}
you can try this,
if(isset($cart['Item']) && !empty($cart['Item'])) {
unset($cart['Item']);
}else{
$items['Item'] = array();
$cart = array_merge($cart, $items);
}
Thanks.

cleanest way to skip a foreach if array is empty [duplicate]

This question already has answers here:
Invalid argument supplied for foreach()
(20 answers)
Closed 7 years ago.
Not a major problem but I was wondering if there is a cleaner way to do this. It would be good to avoid nesting my code with an unnecessary if statement. If $items is empty php throws an error.
$items = array('a','b','c');
if(!empty($items)) { // <-Remove this if statement
foreach($items as $item) {
print $item;
}
}
I could probably just use the '#' error suppressor, but that would be a bit hacky.
There are a million ways to do this.
The first one would be to go ahead and run the array through foreach anyway, assuming you do have an array.
In other cases this is what you might need:
foreach ((array) $items as $item) {
print $item;
}
Note: to all the people complaining about typecast, please note that the OP asked cleanest way to skip a foreach if array is empty (emphasis is mine). A value of true, false, numbers or strings is not considered empty.
In addition, this would work with objects implementing \Traversable, whereas is_array wouldn't work.
The best way is to initialize every bloody variable before use.
It will not only solve this silly "problem" but also save you a ton of real headaches.
So, introducing $items as $items = array(); is what you really wanted.
$items = array('a','b','c');
if(is_array($items)) {
foreach($items as $item) {
print $item;
}
}
If variable you need could be boolean false - eg. when no records are returned from database or array - when records are returned, you can do following:
foreach (($result ? $result : array()) as $item)
echo $item;
Approach with cast((Array)$result) produces an array of count 1 when variable is boolean false which isn't what you probably want.
I wouldn't recommend suppressing the warning output. I would, however, recommend using is_array instead of !empty. If $items happens to be a nonzero scalar, then the foreach will still error out if you use !empty.
I think the best approach here is to plan your code so that $items is always an array. The easiest solution is to initialize it at the top of your code with $items=array(). This way it will represent empty array even if you don't assign any value to it.
All other solutions are quite dirty hacks to me.
foreach((array)$items as $item) {}
i've got the following function in my "standard library"
/// Convert argument to an array.
function a($a = null) {
if(is_null($a))
return array();
if(is_array($a))
return $a;
if(is_object($a))
return (array) $a;
return $_ = func_get_args();
}
Basically, this does nothing with arrays/objects and convert other types to arrays. This is extremely handy to use with foreach statements and array functions
foreach(a($whatever) as $item)....
$foo = array_map(a($array_or_string)....
etc
Ternary logic gets it down to one line with no errors. This solves the issue of improperly cast variables and undefined variables.
foreach (is_array($Items) || is_object($Items) ? $Items : array() as $Item) {
It is a bit of a pain to write, but is the safest way to handle it.
You can check whether $items is actually an array and whether it contains any items:
if(is_array($items) && count($items) > 0)
{
foreach($items as $item) { }
}
Best practice is to define variable as an array at the very top of your code.
foreach((array)$myArr as $oneItem) { .. }
will also work but you will duplicate this (array) conversion everytime you need to loop through the array.
since it's important not to duplicate even a word of your code, you do better to define it as an empty array at top.

Categories