Are arrays passed by reference or value in PHP?
For example, let's see this code.
function addWeight($arout, $lineCountry, $lineDomain, $target, $weight)
{
$currentDomain=getDomain();
$currentCountry=getCountry();
if ($currentCountry==$lineCountry && ($currentDomain == $lineDomain || $lineDomain==""))
{
$tarobreakpoint=0;
$arout [$target] = intval($weight);
}
return $arout;
}
Basically it took an array as a parameter. Depending on some circumstances it adds elements to the array. I wonder if this is efficient? If $arout is passed by reference like all arrays should then I think it's efficient. But if it's just copied and passed by value then well it's not.
So what's the verdict?
According to the manual, PHP arrays are passed by value:
Array assignment always involves value copying. Use the reference operator to copy an array by reference.
If you'd like to pass an array's reference, use the corresponding operator (&) as mentioned above, and remove the return $arout; line in the addWeight() function:
<?php
// pass $array by reference using & operator
addWeight(&$array, $lineCountry, $lineDomain, $target, $weight);
Related
I'm currently building code in Laravel and adding the (array) part to my code fixed my laravel sync problem when there was no data being passed in the array. This is the question I learned from and got the (array) code to use.
I'm having a hard time finding the documentation for this in laravel or php and was wondering which language/framework the (array) code originates from and what it exactly does. If you could direct me to the right documentation page I would love that as well.
It's just another way of creating an array by using an existing variable
$x = 1; // int
$y = (array)$x; // array[0] => 1
$z = [$x]; // array[0] => 1
I should note that the last way would be preferred (directly declaring it as an array), since it's clearer what will happen (type juggling can produce unexpected results when converting values like this).
http://php.net/manual/en/language.types.array.php#language.types.array.casting
I think you are struggling with the process of type casting in php, like:
PHP type casting to array
We can convert any data type variable in array using (array) keyword. Any scalar data type conversion into array will create array and add element at 0th index.
For example:
<?php
var_dump((array) , 5);// value 5 in the array with 0th index
var_dump((array) NULL);// Will be empty array
?>
Explanation with example
It's just an array castring, according to the php manual
Converting to array
For any of the types integer, float, string, boolean and resource,
converting a value to an array results in an array with a single
element with index zero and the value of the scalar which was
converted. In other words, (array)$scalarValue is exactly the same as
array($scalarValue).
If an object is converted to an array, the result is an array whose
elements are the object's properties. The keys are the member variable
names, with a few notable exceptions: integer properties are
unaccessible; private variables have the class name prepended to the
variable name; protected variables have a '*' prepended to the
variable name. These prepended values have null bytes on either side.
This can result in some unexpected behaviour:
<?php
>
> class A {
> private $A; // This will become '\0A\0A' }
>
> class B extends A {
> private $A; // This will become '\0B\0A'
> public $AA; // This will become 'AA' }
>
> var_dump((array) new B()); ?>
The above will appear to have two keys named 'AA', although one of
them is actually named '\0A\0A'.
Converting NULL to an array results in an empty array.
I have a array containing to which I have created local variables from using the extract() function with the EXTR_PREFIX_ALL flag set. Afterwards, I called compact() on the new prefixed variables created by extract() but displaying the array created from compact() using print_r() gives an empty array(). Sample code follows:
<?php
$cities = array('City1' => "Chicago", 'City2' => "Boston");
extract($cities, EXTR_PREFIX_ALL, "new");
echo "City 1: {$new_City1} City 2: {$new_City2}" . "<br><br>";
$new_cities = compact($new_City1, $new_City2);
print_r($new_cities);
?>
I am using PHP version 5.6. What am I doing wrong here?
In your current code, you're actually providing the values of each variables you're trying to compact, not the name of the variables. It acts like a variable variables behavior. In order to make it work properly, you provide the variable names as strings or in array form:
$new_cities = compact(array('new_City1', 'new_City2'));
// or
$new_cities = compact('new_City1', 'new_City2');
Here's the excerpt from the manual:
Parameters
varname1
compact() takes a variable number of parameters. Each parameter can be either a string containing the name of the variable, or an array of variable names. The array can contain other arrays of variable names inside it; compact() handles it recursively.
Give it a try
$new_cities = compact('new_City1', 'new_City2');
print_r($new_cities);
For more info
I currently have a php function, in which the 1st parameter is a reference to an array and the 2nd parameter is one of its keys,
function fun(&$a, $k) {
......
}
I want to modify the function so that I just need to pass one parameter $a[$k]. Inside the function , $a can be extracted from $a[$k] and then I can call array_search($a[$k], $a) to get $k. Is that possible in PHP?
function fun(&$ak) {
// $ak is from $a[$k]
// a php utility to extract $a from $ak? ...
$k = array_search($ak, $a);
}
Short answer: No, there's no way to "extract" that information, because that information doesn't exist in the scope of your function.
Long answer:
As people have pointed out in the comments, you simply cannot do this. If you have a function like this:
function fun(&$foo) {
...
}
there is no information passed to that function about where $foo came from. It could be a standalone variable, an array element ($bar[1]), an object property ($baz->bingo), or anything else (think SomeClass::$bar->baz[$bingo->boingo]). There's no way to tell.
To verify this, try var_dump($ak); in your function; it won't contain any information about what array or object it's in (or its array index or property name). It's just like any other variable.
I'm writing some kind of a function that accepts an associative array as an argument.
This array can be:
Empty
Has only one element. With key either pageParam or wrapperClass.
Has two elements. Must be keyed with pageParam and wrapperClass.
Now i've written these checks to ensure that:
The array is not more than 2 elements.
The array does not have any elements other than pageParam and wrapperClass
The problem is, My second check is not working properly. Here's my code :
public function init_paginator(array $parameters = array())
{
if(!empty($parameters))
{
// This check works
if(count($parameters) > 2)
{
throw new \Exception("Paginator only accepts 2 elements in array: pageParam and wrapperClass.");
}
// This check does not work, even if its condition is satisfied
if(!in_array(array_keys($parameters), array('pageParam', 'wrapperClass')))
{
throw new \Exception("Paginator only accepts 2 elements in array: pageParam and wrapperClass.");
}
// Code..
}
}
The exception in the second check is always thrown if i entered the array argument like :
array("dummyKey"=>"dummyValue")
array("dummyKey1"=>"dummyValue1", "dummyKey2"=>"dummyValue2")
array("pageParam"=>"test") Or array("wrapperClass"=>"wrapper_class")
array("pageParam"=>"test", "wrapperClass"=>"wrapper_class")
The last two inputs is what puzzles me! Why the exception is thrown despite that my arguments are right.
Your second check looks for the value array_keys($parameters) inside array('pageParam', 'wrapperClass'). It compares an array of strings with two string values.
What you want is the keys of $parameters to be equal to the values of array('pageParam', 'wrapperClass'), thus:
array_keys($parameters) === array('pageParam', 'wrapperClass');
For arrays, the === operator evaluates to TRUE if both arrays have the same key/value pairs in the same order and of the same types. If you don't care about order, you can use ==.
By the way, this check renders the first one useless.
The doc aren't as descriptive as they should be, but the intent with the two arrays as args is that the needle is an array and the haystack is an array of arrays (multi-dimensional) that may contain the needle array. I'm headed out so will look again later, but maybe this as an alternative:
if(count(array_diff_key(array_keys(array('pageParam', 'wrapperClass')), $parameters)) > 1) {
//exception
}
The problem is in the way you use in_array
It'll never work because it keeps matching an array array_keys($parameters) to strings within another array array('pageParam', 'wrapperClass')
So, it keeps returning false
See PHP: in_array
Using array( array('pageParam', 'wrapperClass'), array('pageParam'), array('wrapperClass'), array()) as second parameter for in_array might work.
I have a small issue with my script.
I'm getting Strict Standards: Only variables should be passed by reference in
if( $checkDNS && ($domain = end(explode('#',$email, 2))) )
From the PHP manual:
This array is passed by reference because it is modified by the function. This means you must pass it a real variable and not a function returning an array because only actual variables may be passed by reference.
So you must use a variable in the end function:
$domain = explode('#',$email, 2);
if( $checkDNS && ($domain = end($domain)) )
From the manual:
mixed end ( array &$array )
end takes the array by reference and move the internal pointer. Your array is the function output, so its unable to correctly modify the array by reference.
Like the message says, end expects a variable because its parameter is a reference.
But since PHP 5.4 you can dereference arrays like that:
$domain = explode('#',$email, 2)[1];
Assuming that $email always contains #. You should assure that beforehand, otherwise end(...) would give you unexpected results too.