php, как установить значение по умолчанию в качестве объекта?

Функция (фактически конструктор другого класса) нуждается в объекте class temp в качестве аргумента. Поэтому я определяю interface itemp и включаю itemp $obj в качестве аргумента функции. Это нормально, я должен передать class temp объекта в свою функцию. Но теперь я хочу установить значение по умолчанию для этого аргумента itemp $obj. Как это сделать? Или это невозможно?
Приведу тестовый код для уточнения:

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

person Sudhi    schedule 15.08.2011    source источник
comment
Вы можете использовать мою крошечную библиотеку ValueResolver в этом случае, проверьте мой ответ, пожалуйста   -  person Victor Bocharsky    schedule 09.07.2015


Ответы (5)


Вы не можете. Но вы можете легко сделать это:

function func2(itemp $obj = null)
    if ($obj === null) {
        $obj = new temp('Default');
    }
    // ....
}
person Arnaud Le Blanc    schedule 15.08.2011
comment
спасибо нашел это после поиска значений метода php по умолчанию, не думал, что я могу сравнивать объект с нулями. - person Sudhi; 15.08.2011

Возможная проблема с ответом arnaud576875 заключается в том, что в некоторых случаях вы можете разрешить NULL в качестве указанного параметра, например. вы можете пожелать, чтобы следующее обрабатывалось по-другому:

func2();
func2(NULL);

Если это так, лучшим решением будет:

function func2(itemp $obj = NULL)
{

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

  // ...

}
person MichaelRushton    schedule 04.12.2014
comment
Имеет ли это смысл? Единственными допустимыми значениями параметров являются null и реализации itemp. Нет (или, по крайней мере, должно быть с точки зрения API) никакой поведенческой разницы при передаче маркера для отсутствующего значения (null) и вообще никакого значения. Я согласен, если параметр не будет типизирован, в некоторых случаях это действительно полезно. - person Rangad; 04.12.2014
comment
Если вы не передаете параметр, то вы делаете это намеренно, и поэтому вы можете захотеть, чтобы он выполнял какое-то поведение по умолчанию. Если вы передаете параметр NULL, то, скорее всего, ожидается реализация itemp, и поэтому вы можете захотеть, чтобы он регистрировал ошибку и/или выдавал исключение. - person MichaelRushton; 04.12.2014
comment
подлый, таким образом вы немного перегружаете php. Мне это нравится. Не уверен, что поддержал бы его, но кого это волнует... :) - person VolkerK; 28.02.2015

начиная с php 5.5 вы можно просто использовать ::class для передачи класса в качестве параметра следующим образом:

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
person hassan    schedule 15.07.2017
comment
Спасибо! К сожалению, это не работает вместе с подсказкой типа: функция func2(SomeInterface $class = SomeObject::class) выдает Fatal: значение по умолчанию для параметров с типом класса может быть только NULL (протестировано с PHP 7.2) - person Den; 26.01.2020

Update PHP 8.1

Начиная с PHP 8.1 вы сможете определить новый экземпляр объекта как значение аргумента функции по умолчанию без ошибок, однако с некоторыми ограничениями.

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

Документация: https://wiki.php.net/rfc/new_in_initializers

person Jsowa    schedule 14.07.2021

В этом случае вы можете использовать мою крошечную библиотеку ValueResolver, например:

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

и не забудьте использовать пространство имен use LapaLabs\ValueResolver\Resolver\ValueResolver;

Также есть возможность приведения типов, например, если значение вашей переменной должно быть integer, используйте это:

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

Дополнительные примеры см. в документах.

person Victor Bocharsky    schedule 09.07.2015