class — PHP: Работа с функцией без учета регистра

У меня есть ситуация, когда есть похожие функции в разных классах, давайте назовем их «Выполнить» и «Выполнить».

class oldVersion {
public function Execute($x){
echo 'This does the same thing as newVersion->execute(1)';
echo 'but the class contains a lot of garbage that PHP7 doesn\'t like.';
echo 'and the app dies if it\'s included';
}
}

class newVersion {
public function execute($x, $y = 0, $z = 0){
if($y == 1){
echo 'do thing one';
} else {
echo 'do thing zero';
}
return 'bar';
}
}
$obj1 = new oldVersion();
$obj1->Execute('foo');

$obj2 = new newVersion();
$obj2->execute('bar', 1);

Класс oldVersion имеет много неправильных вещей и не будет работать вообще под PHP7, так что я бы очень хотел иметь возможность сделать это, перевести Execute в newVersion и сделать это:

class oldVersion_deprecated {
// no longer included so PHP7 doesn't break
}

class newVersion {
public function Execute($x){
return $this->execute($x, 1);
}
public function execute($x, $y = 0, $z = 0){
if($y == 1){
echo 'do thing one';
} else {
echo 'do thing two';
}
return 'bar';
}
}

$obj1 = new newVersion();
$obj1->Execute('foo');

$obj2 = new newVersion();
$obj2->execute('bar', 1);

Но естественно получаю

FATAL ERROR: cannot redefine execute

Есть ли причудливый обходной путь, или я застрял, находя и переписывая каждый звонок?

1

Решение

Это немного грязно, и я бы не рекомендовал это делать, но вы можете моделировать чувствительные к регистру методы с помощью «волшебства» PHP __call метод. Это вызывается всякий раз, когда метод не может быть найден в данном классе. Затем вы можете проверить предоставленное имя метода и запустить любую подходящую логику.

class Foo
{
public function __call($name, $args)
{
switch ($name) {
case 'Execute':
return $this->oldExecute(...$args);
case 'execute':
return $this->newExecute(...$args);
}
}

private function oldExecute($x)
{
echo 'Running old function with arg: ', $x, PHP_EOL;
}

private function newExecute($x, $y, $z)
{
echo 'Running new function with args: ', implode(',', [$x, $y, $z]), PHP_EOL;
}
}

Увидеть https://eval.in/926262

1

Другие решения

Просто удалите первую функцию выполнения, которая вызывает «настоящую». Функции не чувствительны к регистру, поэтому вам не нужно иметь два

class newVersion {
public function execute($x, $y = 0, $z = 0){
if($y == 1){
echo 'do thing one';
} else {
echo 'do thing two';
}
return 'bar';
}
}
/* All the same */
echo newv->Execute('foo');
echo newv->ExEcUTe('foo');
echo newv->execute('bar', 1);
1

По вопросам рекламы [email protected]