gzhegow
@gzhegow
aka "ОбнимиБизнесмена"

Как отследить вызов метода объекта PHP?

Есть магический метод __call который вызывается если метода нету (для статических __callStatic).

А как правильно сделать примерно такую штуку: если я пытаюсь вызвать любой метод объекта, то сначала запустить команду createInstance() - создать синглтон, а уже потом выполнить саму команду. Или это много думаю, все проще?

Неужели единственный способ - это в каждое объявление функции прописывать static::createInstance() ?
  • Вопрос задан
  • 1706 просмотров
Решения вопроса 1
iiifx
@iiifx
PHP, OOP, SOLID, Yii2, Composer, PHPStorm
Можно и так. Статические методы сделайте private/protected. Используя PHPDoc укажите какие именно публичные методы доступны для вызова. Метод __callStatic будет перехватывать попытки вызова закрытых методов, вы сперва проверите наличие этого метода, потом сделаете нужную вам инициализацию и потом лишь передадите управление этому методу.

Вот вам пример. Но я бы не советовал его использовать в реальных приложениях - он плохо пахнет.
/**
 * @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
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
muhammad_97
@muhammad_97
PHP-разработчик
Все делается проще: есть свойство instance, которое изначально равно null. При вызове метода getInstance() проверяем, равно ли instance null (self::$instance === null), если да - создаем объект, сохраняем в instance и возвращаем его, иначе просто возщвращаем 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;
    }
}
Ответ написан
ruFelix
@ruFelix
Предсказание будущего по руке, таро, кофе.
Неужели единственный способ - это в каждое объявление функции прописывать static::createInstance()

Можно написать класс обёртку, но зачем?
Если вам для двух статичных методов нужен одинаковый конструктор, то вывод напрашивается сам собой, вам не нужны статичные методы.

Кроме синглтона посмотрите другие порождающие шаблоны проектирования, среди них наверняка найдётся тот который решит вашу исходную задачу.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы