Правильный способ получения ссылки на другой существующий объект путем вызова метода?

#php #object #methods #reference

#php #объект #методы #ссылка

Вопрос:

Я пытаюсь вызвать объект, используя метод, и я застрял.

Давайте предположим, что у меня есть класс с именем Entity , который использовался для переменной псевдоструктурного типа.

Объект Entity обычно имеет множественную связь между другими Entity экземплярами. Итак, я создаю класс EntityModule для обработки сохранения, загрузки базы данных и, возможно, других удобных методов.

Что я пытаюсь сделать, так это..

Позволяет, если я хочу вставить Entity объект в таблицу. С помощью метода Entity->save() я хочу вызвать EntityModule->saveEntity() метод из уже существующего EntityModule объекта obejct.

Как я должен это получить? Я думаю, просто используя другой созданный объект внутри класса, это очень утомительно.

.. Это очень запутанно для любителя.. Ниже приведен мой пример.

 <?php
class Container
{
    public function __get($varName)
    {
        if(!isset($this->varName)) {
            // Can it be more simpler?
            switch($varName) {
                case 'PDO':
                    $this->PDO('dbdbdb');
                    break;
                case 'SessionStorage':
                    $this->SessionStorage($this->PDO);
                    break;
                default:
                    break;
            }
        }
    }

    // This is weird method.. can it be more simpler?
    public function __call($method, $args) {
        $n = count($args);
        if($n === 0) {
            $this->$method = new $method();
        } elseif($n === 1) {
            $this->$method = new $method($args[0]);
        } elseif($n === 2) {
            $this->$method = new $method($args[0], $args[1]);
        } elseif($n === 3) {
            $this->$method = new $method($args[0], $args[1], $args[2]);
        } elseif($n === 4) {
            $this->$method = new $method($args[0], $args[1], $args[2], $args[3]);
        } elseif($n === 5) {
            $this->$method = new $method($args[0], $args[1], $args[2], $args[3], $args[4]);
        } elseif($n === 6) {
            $this->$method = new $method($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]);
        } elseif($n === 7) {
            $this->$method = new $method($args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6]);
        };
    }
}
?>
  

Используя контейнер, я пытаюсь создать экземпляр объекта динамически.

 class Schema
{
    public $id;
    public $type;
    public $name;
    public $desc;

    public function __construct(int $id = false, $type = 0, $name = 'Temporal schema name', $desc = 'No description.')
    {
        $this->id = $id;
        $this->type = $type;
        $this->name = $name;
        $this->desc = $desc;
        return;
    }

    public function save()
    {
        if(!isset($ctn->SchemaModule)) {
            // This is another weird part.
            // Is this the right way to make a class? Call a random instance inside the class? Doesn't it wierd?????????? ???? ?.??  ??? mentalbreak.
            $ctn->SchemaModule->save($this);
        }
    }
}
  

Комментарии:

1. Есть ли у вас какие-либо (короткие) примеры кода, которые демонстрируют то, что вы пытаетесь, и какие-либо проблемы, с которыми вы сталкиваетесь?

2. Спасибо ChristianF. Я просто редактирую поток.

Ответ №1:

Хотя я не уверен на 100% в том, что вы пытаетесь сделать, я думаю, что вы, возможно, немного усложнили ситуацию. Или, по крайней мере, сделал его чрезмерно абстрактным.

__call() Магический метод, а также другие «перегружающие» магические методы ( __get() amp; __set() ) следует использовать очень экономно. Поскольку они значительно усложняют ситуацию, нарушают поддержку IDE и, как правило, являются громоздким решением.

В этом случае, я думаю, вам лучше всего использовать либо выписывание методов, возможно, после некоторой реструктуризации классов. Так что у вас вся ваша логика написана явно, вместо того, чтобы быть каким-то метаязыком внутри самого PHP.
Либо это, либо использование заводского шаблона для генерации объектов. В котором явно указаны требуемые методы и выполняются операции с этими объектами в контроллере вместо (в контейнере).

Когда дело доходит до второй части, я не совсем понимаю, откуда вы получаете $ctn объект или отношение SchemaModule к нему. Но в вызове других экземпляров из методов нет ничего необычного в ООП, по крайней мере, до тех пор, пока эти экземпляры и зависимости четко обозначены.
Большую часть времени эти зависимости предоставляются (и должны) конструктору, а затем сохраняются в самом классе. Это означает, что контроллер должен знать зависимости классов и предоставлять их при создании объекта. Это снова связано с комментарием, который я сделал выше, о четком изложении вашей логики в коде и избежании всей ситуации с «объектом meta God».

На первый взгляд может показаться, что шаблон factory больше похож на этот шаблон нечеткой логики, поскольку он также генерирует объекты динамически в зависимости от некоторого ввода. Большая разница здесь в том, что все объекты, которые он создает, основаны на классах, которые совместно используют интерфейс, так что вы знаете, что они совместимы и взаимозаменяемы.
По большому счету, это то, чего, я думаю, вам не хватает в вашем коде.

Комментарии:

1. Спасибо ChristianF. Я думаю, что я получил что-то, что пока не могу объяснить. Тот, который, как я понимаю, я пытался получить «объект meta God» без знания и не знал, чего мне следует избегать.

2. @user3477339: Добро пожаловать, и я рад, что смог помочь. Спасибо за голосование и принятие ответа. 🙂 Я также рекомендую www.phptherightway.com для дальнейшего чтения, поскольку это даст вам много действительно хорошей информации о том, как использовать PHP наилучшим возможным способом.