23

A function (actually the constructor of another class) needs an object of class temp as argument. So I define interface itemp and include itemp $obj as the function argument. This is fine, and I must pass class temp objects to my function. But now I want to set default value to this itemp $obj argument. How can I accomplish this?

Or is it not possible?

The test code to clarify:

interface itemp { public function get(); }

class temp implements itemp
{
    private $_var;
    public function __construct($var = NULL) { $this->_var = $var; }
    public function get() { return $this->_var ; }
}
$defaultTempObj = new temp('Default');

function func1(itemp $obj)
{
    print "Got: " . $obj->get() . " as argument.\n";
}

function func2(itemp $obj = $defaultTempObj) //error : unexpected T_VARIABLE
{
    print "Got: " . $obj->get() . " as argument.\n";
}

$tempObj = new temp('foo');

func1($defaultTempObj); // Got: Default as argument.
func1($tempObj); // Got : foo as argument.
func1(); // "error : argument 1 must implement interface itemp (should print Default)"
//func2(); // Could not test as I can't define it
1
  • You could use my tiny library ValueResolver in this case, check my answer, please Commented Jul 9, 2015 at 11:06

5 Answers 5

32

You can't. But you can easily do that:

function func2(itemp $obj = null)
    if ($obj === null) {
        $obj = new temp('Default');
    }
    // ....
}
Sign up to request clarification or add additional context in comments.

1 Comment

thanks found this after searching for php method defaults, didn't think that I can compare object with nulls.
7

PHP 8.1

Since PHP 8.1 you are able to define a new instance of an object as a default value of the function argument without error, however with some limitations.

function someFunction(Item $obj = new Item('Default'))
{
    ...
}

Documentation: PHP RFC: New in initializers

Comments

4

A possible problem with Arnaud Le Blanc's answer is that in some cases you might wish to allow NULL as a specified parameter, e.g. you might wish for the following to be handled differently:

func2();
func2(NULL);

If so, a better solution would be:

function func2(itemp $obj = NULL)
{

  if (0 === func_num_args())
  {
    $obj = new temp('Default');
  }

  // ...

}

3 Comments

Does this make sense? The only valid parameter values are null and implementations of itemp. There is (or atleast should be from an API perspective) no behavorial difference in passing a marker for an absent value (null) and no value at all. I agree, if the parameter would not be typehinted, this is actually usefull in some cases.
If you're not passing a parameter then you're doing so intentionally, and so you might want it to perform some default behaviour. If you're passing a NULL parameter then it's likely expecting an itemp implementation and so you might want it to log an error and/or throw an exception.
sneaky, that way you're introducing a bit of overloading to php. I like it. Not sure if I'd endorse it, but who cares... :)
2

Since PHP 5.5 you can simply use the ::class to pass a class as a parameter as follow:

function func2($class = SomeObject::class) {
    $object = new $class;
}

func2(); // Will create an instantiation of SomeObject class
func2(AnotherObject::class); // Will create an instantiation of the passed class

1 Comment

Thanks! Sadly it doesn't work together with a type hint: function func2(SomeInterface $class = SomeObject::class) yields a Fatal: "Default value for parameters with a class type can only be NULL" (Tested with PHP 7.2)
0

You could use my tiny library ValueResolver in this case, for example:

function func2(itemp $obj = null)
    $obj = ValueResolver::resolve($obj, new temp('Default'));
    // ....
}

and don't forget to use namespace use LapaLabs\ValueResolver\Resolver\ValueResolver;

There are also ability to typecasting, for example if your variable's value should be integer, so use this:

$id = ValueResolver::toInteger('6 apples', 1); // returns 6
$id = ValueResolver::toInteger('There are no apples', 1); // returns 1 (used default value)

Check the docs for more examples

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.