У меня есть несколько методов «установки» для разных классов, и для удобства я добавил необязательный параметр $previous
, который принимает аргумент по ссылке и заполняет его существующим значением, прежде чем заменить его новым. Например:
public function set_value($key, $value, &$previous = null)
{
$previous = $this->get_value($key);
$this->_values[$key] = $value;
return $this;
}
Это отлично работает; однако в некоторых случаях соответствующий метод «получения» является немного интенсивным процессом, и запуск его безоговорочно является пустой тратой. Я решил, что смогу проверить:
if(null !== $previous)
{
$previous = $this->get_value($key);
}
Однако это не работает, так как часто переменная, передаваемая в качестве аргумента для $previous
, ранее не определялась в своей области видимости, и в любом случае по умолчанию имеет значение null. Единственное решение, которое я взломал:
public function set_value($key, $value, &$previous = null)
{
$args = func_get_args();
if(isset($args[2])
{
$previous = $this->get_value($key);
}
$this->_values[$key] = $value;
return $this;
}
Или в одну строку:
if(array_key_exists(2, func_get_args()))
{
// ...
}
Мне не нравится, когда тело метода полагается на индексы аргументов (, когда кажется, что это не нужно) ) Есть ли более чистый способ достичь того, чего я добиваюсь здесь?
Я пробовал:
if(isset($previous)){}
if(!empty($previous)){}
if(null !== $previous){}
Ни одна из работ.
Возможные решения на данный момент:
if(func_num_args() == $num_params){}
if(array_key_exists($param_index, func_get_args())){}
// 5.4
if(isset(func_get_args()[$param_index])){}
// 5.4
if(func_num_args() == (new \ReflectionMethod(__CLASS__, __FUNCTION__))
->getNumberOfParameters()){}
@ DaveRandom - Итак, что-то в области:
define('_NOPARAM', '_NOPARAM' . hash('sha4096', microtime()));
function foo($bar = _NOPARAM)
{
// ...
}
@ hoppa - Вариант использования:
$obj->set_something('some_key', $some_value, $previous) // set
->do_something_that_uses_some_key()
->set_something('some_key', $previous) // and reset
->do_something_that_uses_some_key()
-> ...
Вместо:
$previous = $obj->get_something('some_key'); // get
$obj->set_something('some_key', $some_value) // set
->do_something_that_uses_some_key();
->set_something($previous) // and reset
->do_something_that_uses_some_key();
-> ...