перенаправление на другие методы при вызове несуществующих методов

#php #class #methods

#php #класс #методы

Вопрос:

Если я вызываю, $object->showSomething() а showSomething метод не существует, я получаю ошибку fata. Все в порядке.

Но у меня есть show() метод, который принимает аргумент. Могу ли я как — то сказать PHP , чтобы он вызывал , show('Something'); когда он сталкивается $object->showSomething() ?

Комментарии:

1. Обходной путь заключается в том, чтобы перехватывать вызовы таких функций через __call и перенаправлять на альтернативную функцию. Если show* это ваш единственный частный случай, то это даже нормально; если вам нужно разделить другие методы / параметры на camelCase, то это менее звездно (нарушило бы семантику языка, потому что идентификаторы PHP на самом деле не чувствительны к регистру).

2. Я вижу. __call() запускается только тогда, когда метод не найден?

3. Да, это работает как запасной вариант. Реальные методы имеют приоритет. Если что-то не найдено, __call обработает это.

Ответ №1:

Попробуйте что-то вроде этого:

 <?php
class Foo {

    public function show($stuff, $extra = '') {
        echo $stuff, $extra;
    }

    public function __call($method, $args) {
        if (preg_match('/^show(. )$/i', $method, $matches)) {
            list(, $stuff) = $matches;
            array_unshift($args, $stuff);
            return call_user_func_array(array($this, 'show'), $args);   
        }
        else {
            trigger_error('Unknown function '.__CLASS__.':'.$method, E_USER_ERROR);
        }
    }
}

$test = new Foo;
$test->showStuff();
$test->showMoreStuff(' and me too');
$test->showEvenMoreStuff();
$test->thisDoesNothing();
  

Вывод:

StuffMoreStuff and me tooEvenMoreStuff

Комментарии:

1. Возможно, потребуется закрыть __call функцию с помощью } else { trigger_error('Unknown function '.__CLASS__.':'.$method, E_USER_ERROR); } , или это может привести к тому, что класс будет очень сложно отлаживать позже…

2. @Wrikken Ты прав, я был немного ленив там. 😉 … обновлен пример кода.

Ответ №2:

Не обязательно только show.... методы, но любой метод, да, используйте __call . Проверьте метод, запрошенный в самой функции.

Ответ №3:

Вы можете использовать функцию method_exists(). Пример:

 class X {
    public function bar(){
        echo "OK";
    }
}
$x = new X();
if(method_exists($x, 'bar'))
    echo 'call bar()';
else
    echo 'call other func';