PHP-класс со статическими методами, перед хуком

0

У меня есть следующий класс в PHP со всеми статическими методами:

class Foo {
    public static function a {
    }

    public static function b {
    }

    public static function c {
    }

    public static function d {
    }

    public static function e {
    }
}

Есть ли способ создать крюк для стрельбы, прежде чем вызывать какие-либо методы в классе Foo т. Foo Как до крючка? Мне нужна логика, и я не хочу добавлять эту логику к каждой статической функции, например:

class Foo {
    private static function init() {
        // pre logic here
    }

    public static function a {
        Foo::init();
    }

    public static function b {
        Foo::init();
    }

    public static function c {
        Foo::init();
    }

    public static function d {
        Foo::init();
    }

    public static function e {
        Foo::init();
    }
}
Теги:
class
static
hook

4 ответа

3
Лучший ответ

То, что вы хотите, называется аспектно-ориентированным программированием. Он позволяет определять совет до вызова метода, доступа к ресурсу, инициализации класса и т.д.

Однако этот метод широко не используется в PHP из-за его сложности. Я могу предложить вам пример с Go! AOP Framework.

class AutoInitializationAspect implements Aspect
{

    /**
     * This advice intercepts an execution of static methods
     *
     * We use "Before" type of advice to initialize the state
     *
     * @param MethodInvocation $invocation Invocation
     *
     * @Before("execution(public Foo::*(*))", scope="target")
     */
    public function beforeMethodExecution(MethodInvocation $invocation)
    {
        $class = $invocation->getThis(); // will be the class name
        $class::init(); // access to the private scope of class
    }
}

Посетите http://demo.aopphp.com/?showcase=loggable для демонстрации (см. Метод LoggingDemo :: runByName(), который перехвачен)

0

Это немного поздно, чтобы ответить на вопрос, но вот метод, который я использую:

class Wrapper {
    public static function __callStatic($name, $arguments) {
        //DoSomethingBeforeFunctionCall();
        call_user_func_array([static::class, $name], $args);
        //DoSomethingAfterFunctionCall();
    }
}

class Foo extends Wrapper{
    protected static function a() {
       //DoSomething();
    }

    protected static function b() {
       //DoSomething();
    }

    protected static function c() {
        //DoSomething();
    }

    protected static function d() {
        //DoSomething();
    }

    protected static function e() {
        //DoSomething();
    }
}

Теперь, если вы попробуете что-то вроде Foo::a() так как a защищен __callStatic, вы вызываете, и вы можете предоставить туда крючки. Также обратите внимание, что использование static::class позволяет использовать Wrapper как общий класс.

0

Наверное, вы можете использовать магический метод __callStatic() для достижения.

public static function __callStatic($name, $arguments)
{
   // pre logic here 
   switch($name)
   { 
       case 'a':
       // do something
       break;

       case 'b':
       // do something
       break;
   }
}
  • 1
    Я думал, что __callStatic() вызывается ТОЛЬКО там, где нет статического соответствующего метода, определенного в классе.
  • 0
    извините :) Спасибо, что научили меня :)
0

Основной ответ: нет, в простой PHP нет такой вещи.

Однако вы можете попробовать несколько вариантов:

  1. Вы можете назвать ваши методы, как aSomeSuffix, bSomeSuffix и т.д., и вызвать их с помощью __callStatic методы вычислений, суффикс имени на лета.
    Плюсы:

    • Одиночный обработчик

    Минусы:

    • Ваша IDE не увидит эти методы, пока вы явно не напишете их через phpDoc
    • Дополнительная работа и большая куча мест для совершения ошибки (аргументы, передаваемые по ссылке, отсутствие обработки метода и т.д.),
  2. Вы можете попробовать библиотеку Go, которая вводит аспектно-ориентированное программирование в PHP, утверждает, что сможет перехватывать статические вызовы. Я никогда не использовал его (хотя я слышал много хороших отзывов об этом) и ничего не знаю о снижении производительности и/или оговорках, использующих его, но, похоже, это соответствует вашему делу. Я думаю, это все равно потребует написать аннотацию для каждого метода, но это приведет к одиночному обработчику.

  3. Метод инициализации вызова в каждом методе. Это то, что вы пытаетесь избежать, а не вариант, я думаю, только потому, что он нарушает DRY.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню