19

In PHP, if I have a function written like this

function example($argument1, $argument2="", $argument3="")

And I can call this function in other place like this

example($argument1)

But if I want to give some value to the thrid argument, Should I do this

example($argument1, "", "test");

Or

 example($argument1, NULL, "test");

I think both will work but what is the better way? Because in future if the value for the $argument2 is changed in the main function and if I have "", then will there be any problem? Or NULL is the best option?

Thanks

JDesigns
  • 2,284
  • 7
  • 25
  • 39
  • 1
    Your last two code blocks should be `example($argument1, "", "test");` and `example($argument1, NULL, "test");` – thetaiko May 11 '11 at 18:44

4 Answers4

16

Passing null or "" for a parameter you don't want to specify still results in those nulls and empty strings being passed to the function.

The only time the default value for a parameter is used is if the parameter is NOT SET ALL in the calling code. example('a') will let args #2 and #3 get the default values, but if you do example('a', null, "") then arg #3 is null and arg #3 is an empty string in the function, NOT the default values.

Ideally, PHP would support something like example('a', , "") to allow the default value to be used for arg #2, but this is just a syntax error.

If you need to leave off arguments in the middle of a function call but specify values for later arguments, you'll have to explicitly check for some sentinel value in the function itself and set defaults yourself.


Here's some sample code:

<?php

function example($a = 'a', $b = 'b', $c = 'c') {
        var_dump($a);
        var_dump($b);
        var_dump($c);
}

and for various inputs:

example():
string(1) "a"
string(1) "b"
string(1) "c"

example('z'):
string(1) "z"
string(1) "b"
string(1) "c"

example('y', null):
string(1) "y"
NULL
string(1) "c"

example('x', "", null):
string(1) "x"
string(0) ""
NULL

Note that as soon you specify ANYTHING for the argument in the function call, that value is passed in to the function and overrides the default that was set in the function definition.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • but if you do example('a', null, "") then arg #3 is null and arg #3 is an empty string in the function, NOT the default values - so you are saying if the actual function changes to have a different value, then the caller needs to be changed also. In this case , NULL in the caller helps? – JDesigns May 11 '11 at 19:04
  • i see the answer for this in your different comment. so i cannot use NULL – JDesigns May 11 '11 at 19:06
  • 1
    Yes, you could simply pass in the default value in the call, but then if you need to change the default value, you'd have to change the function call everywhere you're using it. You're most likely better off using Fanis' answer below, which uses an array to specify arguments. – Marc B May 11 '11 at 19:11
  • thanks. I will not be able to use the array method now as it involves several changes..so i am guessing that I will just give the default value for $argument2 as "" for now assuming the the default value for $argument 2 in the main function doesn't change. – JDesigns May 11 '11 at 19:34
11

You can use either:

example($argument1, '', 'test');

Or

example($argument1, NULL, 'test');

You can always check for NULL using instead of empty string:

if ($argument === NULL) {
    //
}

I think it all depends on what happens inside the function with the args.

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
  • MarcB's answer is much more appropriate than this one. You can't just use them like this and get the expected result. – Octopus Sep 08 '14 at 22:28
  • @Octopus Why won't OP be able to use this? I do the same as MarcB? "you'll have to explicitly check for some sentinel value in the function itself" – PeeHaa Sep 09 '14 at 08:09
  • The thing that makes this answer misleading is the "can"; in fact, if you want `null` to be treated the same as `''`, you **must** add something to the function definition. Importantly, that means that when calling an existing function you **can not** freely choose between the two, because you have to know that the function in question handles them as expected. – IMSoP Jul 11 '22 at 17:10
1

I think you will be better served if you define the optional parameters as null in the function definition and keep it that way, thus calling them as example($argument1, NULL, $argument="test"). Just be sure of how you use the null'd parameters in the function itself to not raise any warnings. You can use false too as long as you're certain of how you use that parameter in the function itself.

If you seem to get this issue alot, a better way may be to use a single associative array for the variable options:

function example($optionsIn = array()) {

    $options = array(
        'var1' => null,
        'var2' => 'something',
        'var3' => 'else'
    ) ;

    $options = array_merge($options, $optionsIn) ;
}


$options = array(
    'var2' => 'different'
) ;

example($options) ;

That way you can pass in any function parameters you wish, leaving any others out and making sure there are the appropriate defaults defined within the function.

The only drawback is that the expected parameters are hidden from the function signature but you can document them in the function's docblock.

Fanis Hatzidakis
  • 5,282
  • 1
  • 33
  • 36
  • Using an associative array might seems a good idea, but you must be careful not to over use it because it obfuscate the parameters you are sending/receiving in a function. You could also rely on `setters` for optional parameters. – JF Dion May 11 '11 at 19:48
  • @Jeff absolutely. Typos are also an issue, which I've been defending against by defining constants, eg for core functions that will be used by others: It may be ugly but it's foolproof to type `$options[OPT_URL]`, plus you get autocomplete help from modern IDEs. – Fanis Hatzidakis May 11 '11 at 20:25
0

It depends on spesification of function.

function a($b=true,$c=false){
 echo $b?'true':'false';
 }

executing

 a(NULL, 1);

results : false. but simply a() results : true

That means you want default argument, then you should use as default:

 a(true, 1);
nerkn
  • 1,867
  • 1
  • 20
  • 36