For an arbitrary function declared as follows:
function foo($first, &$second = null) {
// if ($second is assigned) {
// Work with $second
// }
}
How does one determine if $second
is indeed assigned to a variable at call time, eg.:
foo('hello', $second);
vs
foo('hello'); // Notice &$second is unassigned
Tried isset()
, is_null()
but they don't seem to work.
Created a test script here here
Use pass by value when when you are only "using" the parameter for some computation, not changing it for the client program. In pass by reference (also called pass by address), a copy of the address of the actual parameter is stored.
A reference variable is a variable that points to an object of a given class, letting you access the value of an object. An object is a compound data structure that holds values that you can manipulate. A reference variable does not store its own values.
Passing by reference means that the memory address of the variable (a pointer to the memory location) is passed to the function. This is unlike passing by value, where the value of a variable is passed on.
C++ makes both pass by value and pass by reference paradigms possible. You can find two example usages below. Arrays are special constructs, when you pass an array as parameter, a pointer to the address of the first element is passed as value with the type of element in the array.
It's my understanding that you wish to implement a function that implements something like preg_match
, whereby the third argument gets populated with the memory patterns if passed.
Internally, PHP functions use a function called zend_parse_parameters()
; it accepts a format string and a variable number of arguments that will be populated with the meta data of the call parameters. If a parameter is not passed (e.g. when it's optional), the meta data is not available and thus is easy to detect.
Coming back to PHP itself, unfortunately there's no such thing as func_arg_used($var)
that will tell you if $var
was passed as a function argument; perhaps this would be an interesting contribution to the language, but until then you'll have to settle for something more ancient :)
if (func_num_args() > 1) {
// $second was passed and can be used to populate
}
You may have to be careful when changing the signature of the function, especially when you add parameters in front of $second
; however, naturally this shouldn't happen often because it would most definitely break dependent functions. Adding more arguments at the end has no effect on above code.
There are two ways you can go with this:
ReflectionFunction
- the shiny new toy of developers, it allows you to introspect your function and determine whether the signature changed from when it was created. Use it sparingly though, introspection is not cheap, especially considering the alternativey.
The humble code comment - the much understated form of code policing; a simple line that says // IMPORTANT - don't add arguments before $second
You can't (as far as I know) tell the difference between NULL and Undefined using isset. You could set default value of $second to some random value that will never be used otherwise.
define('UNDEFINED', -19181818);
function foo($first, &$second = UNDEFINED)
{
if($second==UNDEFINED)
{
etc..
}
}
Works for me:
<?php
function bool_str($b)
{
return ($b ? "true" : "false");
}
function foo($first, &$second = null)
{
echo bool_str(isset($first)) . " " . bool_str(isset($second)) . " " .
bool_str(is_null($first)) . " " . bool_str(is_null($second)) . "\n";
}
$a = 1;
$b = 2;
foo($a, $b);
foo($a);
?>
Output:
true true false false
true false false true
^^^^^ ^^^^
Which is precisely what I would expect, i.e. you can use both isset
and is_null
here.
I think the suggestion by Jack to use func_num_args() is excellent.
function foo($first, &$second = null) {
if (func_num_args() > 1) {
//$second MUST be assigned
}
}
This properly detects when $second
references a variable which exists in the calling scopes' symbol table, yet it has a variable value of null.
$second = null;
foo('hello', $second);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With