Declaring an optional array argument - php

I was wondering if there is any difference when setting default array value to be an empty array or NULL.
For example:
function arrayTest(array $array = array()) {
if(!empty($array)) {
// Do something
}
}
or
function arrayTest(array $array = NULL) {
if(!empty($array)) {
// Do something
}
}
What I noticed is that first example doesn't allow NULL values to be passed and the second example does because of type casting.
Any other differences? Which one should be used?

The other difference is that if you don't pass an argument , it will default to array() or null, which are two very distinct values. You can check for that of course, but you will need to take it into account. empty will work for both, but a foreach loop over null won't work that well, and various array functions will also fail.
What you noticed is correct: Passing null for a typehinted argument only works if you add = null to the declaration. This is not only true for arrays but for objects as well. In PHP there is no way in PHP to make a typehinted argument that is mandatory but can be null. As soon as you add =null to the declaration, you can pass null but you can also omit the parameter.
If to you there is no logical difference between an empty array or null, I would choose the first method of defaulting to an empty array. Then at least you'll know that the input is always an array. I think that add clarity to both the implementer of the function and the programmer(s) who use it. But I guess that's just an opinion and not even a strong one.
My main advice would be to not make the argument optional at all. In my experience this will make the usage of such functions unclear, especially as the code grows and more arguments are added.

Related

PHP optional parameter

I'm kinda confused about optional parameters, or setting a parameter within the function in general. So I found this example:
<?php
function makecoffee($type = "cappuccino")
{
return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");
?>
and I don't understand why echo makecoffe("espresso") returns espresso and not cappuccino. Wouldn't espresso be overwritten when calling the method? In my head $type would first be espresso but would then be set to cappuccino since it happens after calling the method. It's kind of hard to explain what I mean, but does $type = "cappuccino" only get called when there's no parameter or why does this happen? Same with
function makecoffee($type = null)
{
}
echo makecoffe("espresso");
why would this return espresso and not null even though type would be set to null when calling the function?
Good example to inform you how exactly the php parameters in functions works, would be the func_get_args() which returns all passed arguments to function.
And this will be our example function.
function foo($example = 'default')
{
print_r(func_get_args());
}
Now we can check if any argument was passed to function.
What happens if we don't pass any argument?
foo();
// Output
Array
(
)
We know that function was called without any argument because output array is empty.
And that is the moment where default value is used for our function parameter. So finally the value for $example parameter will be equal to 'default'
Now we will try to pass 2 arguments to function.
foo('example', 'unnecessary');
// Output
Array
(
[0] => example
[1] => unnecessary
)
From this example we can deduce that we can pass any amount of arguments without seeing an exception. This is one of php features.
But which was passed to $example parameter?
As php docs informs.
The arguments are evaluated from left to right.
The left side for our example is the value from an array with index 0 and the right side is the last element with (actually index 1)
So, under $example we well have 'example' value.
In defaults, the second argument will be ignored because our function doesn't have corresponding second parameter.
What if we pass null as a argument?
This may be tricky because we can imagine that function called with null as a argument will affect on our function as function called without any arguments.
Nothing more wrong.
foo(null);
// Output
Array
(
[0] =>
)
Now you should see that. Despite the fact that our argument was null, value was passed into our function and overwrited default 'example' value for parameter. Finally $example parameter will be equal to null.
That's because the $param = 'value' bit in the function declaration is not executed every time the function is called.
It only comes into play if you don't pass a value for that parameter.
Instead of reading it as a literal assignment PHP does something along the lines of the following under the hood whenever it enters your function.
if true === $param holds no value
$param = 'value'
endif
In other words, $param = 'value' is not a literal expression within the context of the language but rather a language construct to define the desired behaviour of implementing fallback default values.
Edit: Note that the snippet above is deliberately just pseudo code as it's tricky to accurately express what's going using PHP on once PHP has been compiled. See the comments for more info.

How do I tell if a variable is a valid array key?

I want to create a function that won't create errors if it's passed arguments that aren't valid array keys, and successfully check if the argument is set as a key in an array.
static function IsAwesome($name) {
return isset(self::$_awesomeThings[$name]);
}
This creates a lovely message when someone passes, say, an object as $name:
Warning: Illegal offset type in isset or empty in ...
What's the simplest way to avoid this behavior without excluding potentially valid keys, like true, for example? Assume existing code that can't be changed already relies on this behavior.
maybe you need something like:
static function IsAwesome($name) {
return array_key_exists((string)$name, self::$_awesomeThings);
}
http://php.net/manual/ru/function.array-key-exists.php

null does not mean it's not set does it? - PHP objects

I have a php object that has a key=>value with something like [ipAddress] = 'NULL'
and if I do:
if(isset($object->ipAddress)){
echo "I am set!!!";
}
It never echoes. because apparently it's not "Set." I was under them impression that it is set, because oft he word NULL.
Is there a away to get around this to say, you are set? with out actually giving it a value? I ask because I attempted to write a function like this: (Don't mind the debugging, its the debugging that lead me to this question)
private function checkForColumnInModelObject($modelObject, $column, $custom_name){
$relationship = array();
foreach($modelObject as $model){
if(isset($model->$column)){
$value_returned = $model->$column;
var_dump($column);
var_dump($custom_name);
var_dump($value_returned);
//$relationship[$custom_name] = $value_returned;
}
}
//return $this->toObj($relationship);
}
So what I am trying to do here is check for a column in a model object. Now you might be given an array of columns, which we walk through in a function that calls this one, and an array of different model objects. were trying to see if the model object has that column.
So for example:
Does equipmentModel have ipAddress Column? yes? fetch me the value.
and the way we do this is by saying "is the column on this model set". The problem is, we might have columns with NULL value ... hypothetically their set, their value is just null, but PHP's isset() is all like NO, you are not set.
Any ideas on how I could write this to keep the same logic, BUT allow values of null to pass through assuming that model has that particular column?
If you want to know if an object property exists, regardless of its value, you can use property_exists.
if (property_exists($model, $column) {
...
}
isset returns true whenever you do an assignment to some variable. When you do $somevar=NULL; (In this case it is an assignment), if(isset($somevar) { echo "Inside"; } , The "Inside" will never print. Since NULL is never considered a value.

Can we pass the parameter array by reference to call_user_func_array() instead of passing an array of variable references?

I've looked at Is it possible to pass parameters by reference using call_user_func_array()?, and http://php.net/manual/en/function.call-user-func-array.php. The approved technique for passing by reference using call_user_func_array() seems to be by making the parameter array an array of variable references. For example, setting $parameters = array( &$some_variable). My question is, can we instead make the parameter array an array of variables (not references), and pass the whole parameter array as a reference instead? This is illustrated below:
function toBeCalled( &$parameter1, $parameter2 ) {
//...Do Something...
}
$changingVar = 'passThis';
$changingVar2 = 'passThisToo';
$parameters = array( $changingVar, $changingVar2 );
call_user_func_array( 'toBeCalled', &$parameters );
Notice that the function toBeCalled expects the first variable as a reference, and the second as a value. The reason I ask is because the syntax here is convenient, and it seems to work (see this PHP 5.3 patch for the DruTex module for Drupal - http://drupal.org/node/730940#comment-4054054), but I'm just checking what experts think about it.
You can't, because the moment you put things into an array not by reference, they are copied. So no matter what you do with the array afterwards, it will not affect the original variables you put in (if they were even variables to start with).
The thing you linked to doesn't seem to be relevant. It is removing a pointless call-time pass-by-reference.

Function use and omitting arguments - array_slice

Hi I want to get all the elements of an array after a particular point AND maintain the keys.
How do I pass array_slice a null value for the third argument so that I can pass true for the fourth argument? I tried 'null'.
array_splice($array_name,3,null,true)
And/or is there a better way to do this?
Edit: To complete this question: Is there a way to pass a null value for the 3rd parameter. It seems like this is a weakness in this function if you can't pass a null value or 'placeholder'
Just pass the length of the array:
array_slice($array_name, 3, count($array_name)-3, true);
If you dont expect evil big array, you can set PHP_INT_MAX
array_slice($array_name, 3, PHP_INT_MAX, true);

Categories