Let's say we have a method signature like
public static function explodeDn($dn, array &$keys = null, array &$vals = null,
$caseFold = self::ATTR_CASEFOLD_NONE)
we can easily call the method by omitting all parameters after $dn
:
$dn=Zend_Ldap_Dn::explodeDn('CN=Alice Baker,CN=Users,DC=example,DC=com');
We can also call the method with 3 parameters:
$dn=Zend_Ldap_Dn::explodeDn('CN=Alice Baker,CN=Users,DC=example,DC=com', $k, $v);
and with 4 parameters:
$dn=Zend_Ldap_Dn::explodeDn('CN=Alice Baker,CN=Users,DC=example,DC=com', $k, $v,
Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER);
But why is it impossible to call the method with the following parameter combination for example:
$dn=Zend_Ldap_Dn::explodeDn('CN=Alice Baker,CN=Users,DC=example,DC=com', $k, null,
Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER);
$dn=Zend_Ldap_Dn::explodeDn('CN=Alice Baker,CN=Users,DC=example,DC=com', null, $v);
What's the difference between passing null
to the method and relying on the default value? Is this constraint written in the manual? Can it be circumvented?
It's because you can't have a reference to null.
You can have a reference to a variable that contains null - that is exactly what the default value does. Or you can pass in null as a literal value - but since you want an out parameter this is not possible here.
While you must create a dummy variable for by-ref arguments if you want to pass NULL explicitly, you don't have to create that variable on a separate line. You can use an assignment expression like $dummy=NULL directly as a function argument:
function foo (&$ref = NULL) {
if (is_null($ref)) $ref="bar";
echo "$ref\n";
}
foo($dummy = NULL); //this works!
@ Tomalak
Actually, the default value creates a variable without any reference involved. Which is something you simply cannot kick off when you pass something.
What i find to illustrate the reasons is the following example (which i did not test):
function foo (&$ref = NULL) {
$args = func_get_args();
echo var_export($ref, TRUE).' - '.var_export($args, TRUE);
}
$bar = NULL;
foo(); // NULL - array()
foo($bar); // NULL - array(0 => NULL)
In my opinion, PHP should offer a way to NOT pass certain parameters, like withfoo($p1, , , $p4);
or similar syntax instead of passing NULL.
But it doesn't, so you have to use dummy variables.
I just found out this myself, and I'm quite in shock o_O!
This is what the PHP documentation says:
function makecoffee($type = "cappuccino")
{
return "Making a cup of $type.\n";
}
echo makecoffee(); // returns "Making a cup of cappuccino."
echo makecoffee(null); // returns "Making a cup of ."
echo makecoffee("espresso"); // returns "Making a cup of espresso."
I would have expected makecoffee(null)
to return "Making a cup of cappuccino.".
One work-around I have used is to check inside the function if the argument is null:
function makecoffee($type = null)
{
if (is_null($type)){
$type = "capuccino";
}
return "Making a cup of $type.\n";
}
Now makecoffee(null)
returns "Making a cup of cappuccino."
(I realize this doesn't actually solve the Zend-related question, but it might be useful to some...)
Just to confirm what Tomalak stated here:
The following works:
$k=array();
$v=null;
$dn=Zend_Ldap_Dn::explodeDn('CN=Alice Baker,CN=Users,DC=example,DC=com', $k, $v,
Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER);
Not nice - but the explanation is clear and comprehensible.
As @aschmecher pointed out in a comment on
@Szczepan's answer here, doing func($var = null)
generates a strict standards notice.
One solution
Here's a method that does not generate any such warnings:
<?php
error_reporting(E_ALL | E_STRICT);
function doIt(&$x = null) {
if($x !== null) echo "x not null: $x\n";
$x = 2;
}
function &dummyRef() {
$dummyRef = null;
return $dummyRef;
}
doIt(dummyRef());
doIt(dummyRef());
Explanation
In place of passing in a variable, we pass in the result of a function returning a reference. The second call to doIt(dummy())
is to verify that the reference $dummy
value is not persisting between calls. This contrasts with creating a variable explicitly, where one needs to remember to clear any accumulated value:
$dummyRef = null;
doIt($dummyRef);
doIt($dummyRef); // second call would print 'x not null: 2'
Application
So in the OP's example, it would be:
$dn = Zend_Ldap_Dn::explodeDn(
'CN=Alice Baker,CN=Users,DC=example,DC=com',
$k,
dummyRef(),
Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER
);
Additional considerations
One thing I might worry is whether this method creates a memory leak. The following test shows that it doesn't:
<?php
function doItObj(&$x = null) {
if(gettype($x) !== "object") echo "x not null: $x\n";
$x = 2;
}
function &dummyObjRef() {
$dummyObjRef = new StdClass();
return $dummyObjRef;
}
echo "memory before: " . memory_get_usage(true) . "\n";
for($i = 0; $i < 1000000; $i++) {
doItObj(dummyObjRef());
}
echo "memory after: " . memory_get_usage(true) . "\n";
echo "\n$i\n";
On my system (using PHP 5.6.4), both calls to memory_get_usage showed ~ 262 KB.
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