G
G
Grigory Vasilkov2016-02-01 05:55:08
PHP
Grigory Vasilkov, 2016-02-01 05:55:08

How to trace a method call to a PHP object?

There is a magic method __call which is called if there is no method (for static __callStatic).
And how to do something like this correctly: if I try to call any method of an object, then first run the createInstance () command - create a singleton, and only then execute the command itself. Or is it a lot to think everything is easier?
Is it really the only way to write static::createInstance() in each function declaration?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Vitaly Khomenko, 2016-02-01
@gzhegow

Could be so. Make static methods private/protected. Using PHPDoc, specify which public methods are available for calling. The __callStatic method will intercept attempts to call private methods, you first check for the existence of this method, then do the initialization you need, and then only transfer control to this method.
Here's an example for you. But I would not advise using it in real applications - it smells bad.

/**
 * @method static mixed one()
 * @method static mixed two()
 * @method static mixed three()
 */
class Auto
{
    protected static $instance;

    public static function __callStatic ( $name, $arguments )
    {
        if ( static::$instance === null ) {
            static::$instance = new static();
        }
        $method = "static_{$name}";
        if ( method_exists( static::$instance, $method ) ) {
            return call_user_func_array( [ static::$instance, $method ], $arguments );
        }
        throw new BadMethodCallException( '...' );
    }

    protected function static_one ()
    {
        echo 'Вызов метода ' . __METHOD__ . PHP_EOL;
    }

    protected function static_two ()
    {
        echo 'Вызов метода ' . __METHOD__ . PHP_EOL;
    }

    protected function static_three ()
    {
        echo 'Вызов метода ' . __METHOD__ . PHP_EOL;
    }
}

Auto::one(); # Вызов метода AutoCreate::static_one
Auto::two(); # Вызов метода AutoCreate::static_two
Auto::three(); # Вызов метода AutoCreate::static_three

M
Muhammad, 2016-02-01
@muhammad_97

Everything is made simpler: there is an instance property, which is initially null. When calling the getInstance() method, we check if instance is null (self::$instance === null), if so, we create an object, store it in instance and return it, otherwise we simply return instance:

class Foo 
{
    private static $instance;

    private function __construct()
    {
    }

    public static function getInstance()
    {
        if (self::$insrance === null)
        {
            self::$insrance = new Foo();

            return self::$instance;
        }

        return self::instance;
    }
}

W
Walt Disney, 2016-02-01
@ruFelix

Is the only way is to write static::createInstance() in every function declaration?

You can write a class wrapper, but why?
If you need the same constructor for two static methods, then the conclusion suggests itself, you don't need static methods.
In addition to the singleton, look at other generative design patterns , among them there will surely be one that will solve your original problem.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question