Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP run static method before each static function

Tags:

php

I want to be able to call a function automatically before any function is invoked. The problem with __callStatic is that it only runs if the method does not exist.

See the code below.

I want to make always_run() run before any function that was called in the static class.

class Test {

    public static function __callStatic($method, $parameters){
        echo __CLASS__ . "::" . $method;
        if (method_exists(__CLASS__, $method)) {
            self::always_run();
            forward_static_call_array(array(__CLASS__,$method),$args);
        }
    }

    public static function always_run() {
        echo "always_run";
    }

    public static function my_func() {
        echo "myfunc was called";
    }

}

Test::my_func();
// OUTPUT: always_run myfunc wascalled
like image 863
user2867106 Avatar asked Jun 03 '15 22:06

user2867106


2 Answers

Creating static classes such as this that have a global state is always bad design. You should really just be creating object, then you can run any sort of set up code you need in the constructor.

class Test
{
    public function __construct()
    {
        // Code run only once when the object is constructed.
    }
}

Static state makes such classes difficult to test and maintain. Static classes cannot be mocked, so code that depends on the class cannot be independently tested.

Here's an article to help you out: https://r.je/static-methods-bad-practice.html

like image 141
Trowski Avatar answered Sep 19 '22 01:09

Trowski


You can make the methods private:

class Test {

    public static function __callStatic($method, $parameters){
        echo __CLASS__ . "::" . $method;
        if (method_exists(__CLASS__, $method)) {
            self::always_run();
            forward_static_call_array(array(__CLASS__,$method),$parameters);
        }
    }

    private static function always_run() {
        echo "always_run";
    }

    private static function my_func() {
        echo "myfunc was called";
    }

}

Test::my_func();

A bit of a hack really, but this isnt really an ideal situation

like image 34
Steve Avatar answered Sep 18 '22 01:09

Steve