0

I have the following class in PHP with all static methods:

class Foo {
    public static function a {
    }

    public static function b {
    }

    public static function c {
    }

    public static function d {
    }

    public static function e {
    }
}

Is there a way to create a hook to fire before calling any of the methods in class Foo i.e. like a before hook? I need some logic, and don't want to have to add that logic to every static function like:

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();
    }
}
Justin
  • 42,716
  • 77
  • 201
  • 296
  • This answer has some interesting ideas: http://stackoverflow.com/questions/5368199/best-practices-for-static-constructors – cyber_rookie Mar 24 '15 at 06:28

3 Answers3

3

What you want is called an Aspect-Oriented Programming. It allows to define an advice before method call, property access, class initialization, etc.

However, this technique is not used widely in PHP due to its complexity. I can suggest your an example with 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
    }
}

Visit http://demo.aopphp.com/?showcase=loggable for demo (see LoggingDemo::runByName() static method intercepted)

lisachenko
  • 5,952
  • 3
  • 31
  • 51
0

I guess you can use __callStatic() magic method to achieve.

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

       case 'b':
       // do something
       break;
   }
}
Raheel
  • 8,716
  • 9
  • 60
  • 102
  • 1
    I thought `__callStatic()` is ONLY called where there is NOT a static corresponding method defined in the class. – Justin Mar 24 '15 at 06:38
0

Basic answer: no, there is no such thing in plain PHP.

However, you can try several options:

  1. You can call your methods like aSomeSuffix, bSomeSuffix, etc., and call them via __callStatic method computing that suffixed name on-the-fly.
    Pros:

    • Single handler

    Cons:

    • Your IDE won't see those methods until you explicitly write them down via phpDoc
    • Extra work and big pile of places to make a mistake (arguments passing by reference, missing method handling, etc.)
  2. You can try Go library that introduces aspect-oriented programming in PHP claims to be able to intercept static calls. I've never used it (though i've heard lots of good responses about it) and don't know anything about performance drops and/or caveats using it, but it seems to be matching your case. I guess, this would still require to write an annotation for every method, but it will result in single handler.

  3. Call initialization method in every method. This is what you're trying to avoid and not an option, i guess, just because it's violates DRY.

Etki
  • 2,042
  • 2
  • 17
  • 40