У меня есть следующий класс в 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();
}
}
То, что вы хотите, называется аспектно-ориентированным программированием. Он позволяет определять совет до вызова метода, доступа к ресурсу, инициализации класса и т.д.
Однако этот метод широко не используется в 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(), который перехвачен)
Это немного поздно, чтобы ответить на вопрос, но вот метод, который я использую:
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 как общий класс.
Наверное, вы можете использовать магический метод __callStatic() для достижения.
public static function __callStatic($name, $arguments)
{
// pre logic here
switch($name)
{
case 'a':
// do something
break;
case 'b':
// do something
break;
}
}
__callStatic()
вызывается ТОЛЬКО там, где нет статического соответствующего метода, определенного в классе.
Основной ответ: нет, в простой PHP нет такой вещи.
Однако вы можете попробовать несколько вариантов:
Вы можете назвать ваши методы, как aSomeSuffix
, bSomeSuffix
и т.д., и вызвать их с помощью __callStatic
методы вычислений, суффикс имени на лета.
Плюсы:
Минусы:
Вы можете попробовать библиотеку Go, которая вводит аспектно-ориентированное программирование в PHP, утверждает, что сможет перехватывать статические вызовы. Я никогда не использовал его (хотя я слышал много хороших отзывов об этом) и ничего не знаю о снижении производительности и/или оговорках, использующих его, но, похоже, это соответствует вашему делу. Я думаю, это все равно потребует написать аннотацию для каждого метода, но это приведет к одиночному обработчику.
Метод инициализации вызова в каждом методе. Это то, что вы пытаетесь избежать, а не вариант, я думаю, только потому, что он нарушает DRY.