ОО Проблемы в PHP (или любой непостоянной среде) - PullRequest
2 голосов
/ 13 января 2011

Если вы не считали QBASIC назад, когда я был ребенком, я научился программировать в объектно-ориентированной парадигме полвека назад в университете, поэтому я понимаю, как он работает.Однако мне трудно реализовать его в моих больших PHP-приложениях, управляемых базой данных, потому что все переинициализируется при каждой загрузке страницы.Единственное истинное постоянство - это база данных, но извлечение всех данных из базы данных и восстановление всех объектов на каждой загрузке страницы звучит как огромные накладные расходы без особой пользы, так как мне просто придется сделать это снова в следующемзагрузка страницы.

Кроме того, я сталкиваюсь с такими проблемами, когда пытаюсь повторно преобразовать приложение (третья попытка) в OO:


Существует класс с именем Person, ион содержит множество свойств.Одно из расширений этого класса, «Player», содержит свойство «parent» типа «Player».Первоначально ни один из игроков не начинается с родителей, поэтому все они будут инициализированы с этим полем как NULL.Однако со временем родители будут добавлены в свойства Players и будут ссылаться на другие объекты Player, которые уже существуют.

В PHP, однако, неизбежно, что мне придется перестраивать структуру классов с уже имеющимися Player.родители.В таком случае, если я создаю экземпляр Player, у которого в качестве родителя есть Player, который еще не был создан, у меня возникает проблема.


Нужно ли уменьшать объем OO-программирования, когдаимеем дело с PHP?

Ответы [ 4 ]

2 голосов
/ 13 января 2011

Вы путаете понятия ООП с понятиями об HTTP и постоянстве.

Ваш вопрос на самом деле не об ООП, а о сохранении данных ООП в нескольких HTTP-запросах.

PHP не сохраняет автоматически объекты в HTTP-запросах - вам остается позаботиться об этом (в вашем случае, делать так, как вы сказали: «извлечение всех данных из базы данных и восстановление всех объектов на каждом загрузка страницы ").

2 голосов
/ 13 января 2011

Необходимо ли уменьшить объем ОО-программирования при работе с PHP?

Нет. Вам просто нужно использовать ленивая загрузка для создания экземпляра родительского игрока, только если это становится необходимым.

Class Player {

    protected $id;
    protected $name;
    protected $parentId;

    protected $parent;

    public static function getById($id) {
        // fetch row from db where primary key = $id
        // instantiate Player populated with data returned from db
    }

    public function getParentPlayer() {
        if ($this->parentId) {
            $this->parent or $this->parent = Player::getById($this->parentId);
            return $this->parent;
        }
        return new Player(); // or null if you will
    }

}

Таким образом, если вы вводите идентификатор игрока 40:

$john = Player::getById(40);

У него нет заполненного свойства $ parent. Только после вызова getParentPlayer () он загружается и сохраняется в этом свойстве.

$joe = $john->getParentPlayer();

Это, конечно, только если $ parentId указывает на ненулевое значение.

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

    protected static $cache = array();

    public static function getById($id) {
        if (array_key_exists($id, self::$cache)) {
            return self::$cache[$id];
        }
        // fetch row from db where primary key = $id
        // instantiate Player populated with data returned from db
        self::$cache[$id] = ... // newly created instance
        // return instance
    }

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

1 голос
/ 14 января 2011

ООП-программирование в PHP - это для меня больше способ иметь хорошую ремонтопригодность и хорошую архитектуру (состав, фабрики, программирование на основе компонентов и т. Д.).

Наверняка вам потребуется переосмыслить некоторый дизайнШаблоны, используемые в устойчивых условиях.Пулы объектов и т. Д. И, конечно, некоторые паттерны проектирования, которые все еще вполне хороши в PHP, используются в краткосрочных модулях в apache: Singleton, Factory, Adapter, Interfaces, Ленивая загрузка и т. Д.

О проблеме устойчивости есть несколько решений.Конечно база данных хранилище.Но у вас также есть сеанс хранилище и приложение кэши (например, memcached или apc).Вы можете хранить сериализованные объекты в таких кешах.Вам просто понадобится хороший автозагрузчик для загрузки классов (и хороший код операции, чтобы избежать повторной интерпретации источников при каждом запросе).

Некоторые объекты действительно тяжелы для загрузки и сборки мы можем подумать, например, об объекте ACL, загрузке ролей, ресурсах, политике по умолчанию, правилах исключений, возможно, даже о выполнении некоторых из этих правил.Как только вы получите его, будет ужасно восстанавливать этот объект при каждом запросе.Вы должны действительно изучить способ хранения / загрузки этого готового объекта где-нибудь, чтобы ограничить его время загрузки (избегая запросов SQL и времени сборки). После создания это, безусловно, объект, который может иметь длительный срок службы, например, 1 час.

Единственные объекты, которые вы не можете сохранить как сериализованные строки, на самом деле - это те, от которых зависит в скором времени отобновление данных по параллельным запросам .Некоторым веб-сайтам даже не нужно заботиться об этом, точность данных не одинакова в общедоступном веб-сайте, публикующем новости, и в приложении для финансового учета.Если ваше приложение может обрабатывать предварительно созданные сериализованные объекты, вы можете увидеть serialize-storage-load-unserialize как простую служебную нагрузку в рамках :-) Но эффективно, ничего не разделяют , ни один объект не прослушивает все одновременные запросы, нет операции записи на объекте, совместно используемом с параллельным запросом, пока этот объект (или связанные данные) не будет где-то сохранен (и прочитан). Прими это как вызов!

1 голос
/ 13 января 2011

Предметы, которые не создаются с помощью родителей, на самом деле сложно. Вы могли бы сделать что-то вроде ссылки на ID и создать PlayerManager, который сделает ссылку для вас. С помощью RUID (уникальных идентификаторов времени выполнения). Но, конечно, вы хотели бы, чтобы родители были созданы первыми.

Так что, когда вы создаете что-то вроде ОО-структуры вашей базы данных, я бы рекомендовал, если вы захотите сделать с ней некоторые дополнительные манипуляции, помимо печати. Можно создать игрока из вашей БД, а затем, если у него есть родитель, создать родителя, как вы это обычно делаете. При достижении родителя в вашем цикле while. Вы можете просто сказать, нет, это уже создано. Для этого используйте класс Player-manager, который содержит ваших игроков. Таким образом, он может проверить, есть ли игроки (и, следовательно, родители).

Таким образом, вы получаете немного другой способ пройтись по вашей БД, вместо того, чтобы просто делать это линейно.

Что касается: нужно ли это делать. Я на самом деле не так уж много знаю об этом. Кажется, насколько я видел в Интернете, PHP-классы в основном используются для создания одного объекта, который может делать умные вещи (например, DOMDocument).

Но вам действительно нужно преобразовывать таблицу БД в объекты? Это зависит от вашего типа приложения. Если печать - то, что вы хотите, это не кажется логичным. Если произойдут какие-то большие манипуляции с большим количеством обращений к объектам (или обычно к таблице), я, возможно, хотел бы увидеть хорошую запрограммированную ОО-структуру.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...