Нужна простая ORM или DBAL для существующего приложения PHP - PullRequest
6 голосов
/ 18 января 2011

Я работаю над расширением существующего PHP-приложения.К сожалению для меня, существующее приложение - беспорядок.Это весь код спагетти с необработанными вызовами mysql_ *.Стон.Я никоим образом не собираюсь делать это в частях, которые я расширяю.

Итак, я ищу простой ORM DBAL, который я мог бы легко подключить и начать использовать.Желаемые функции:

  • Должно работать в существующей схеме базы данных.Желательно с минимальной или без дополнительной конфигурации.Существующая схема базы данных имеет то же качество, что и существующий код PHP (без разумных соглашений об именах, без нормализации и т. Д.).Я не хочу тратить дни на то, чтобы вручную преобразовать схему базы данных в аннотированные свойства объекта в духе Doctrine 2.
  • Он должен работать вместе с существующими необработанными запросами mysql_ *.Я понятия не имею, как ведут себя гидратирующие ORM, такие как Doctrine 2 или Propel, когда скрипты вручную манипулируют данными в базе данных за их спинами, но я предполагаю, что это не красиво.
  • Он должен работать на PHP 5.2.x.Я бы любил использовать PHP 5.3, но я не заинтересован в том, чтобы просматривать существующие 125К строк беспорядочного кода спагетти, чтобы убедиться, что он работает на PHP 5.3.
  • Отношения не требуются.В тех немногих местах, где мне нужно добраться до реляционных данных, я буду рад вызвать дополнительные find() или query() или что-нибудь еще.
  • Бонусные баллы, если есть поддержка триггера (например, beforeSave, afterSave).Не обязательно, но просто приятно иметь.

Редактировать : Кто-то избавил меня от моих страданий.Я только что узнал, что 125К строк кода спагетти также изменяет схему базы данных.Например, добавьте дополнительную опцию куда-нибудь, и целый ряд операторов ALTER TABLE начнет летать.Я мог бы, вероятно, заполнить годовой объем TheDailyWTF с помощью этой кодовой базы.Итак, еще одно требование:

  • Должен быть в состоянии автоматически справляться с изменяющейся схемой базы данных (например, добавляя столбцы).

Я искал несколько решений,но я не уверен, насколько хорошо они будут работать с учетом требований.Doctrine 2, RedBeanPhp и тому подобное все требуют PHP 5.3, поэтому они отсутствуют.Существует устаревшая версия RedBeanPhp для PHP 5.2.x, но я не знаю, будет ли она работать с грязной, существующей схемой базы данных.NotORM выглядит нормально для вывода данных, но я не знаю, можно ли его настроить для существующей схемы базы данных, и как вы можете легко поместить данные обратно в базу данных.

В идеале мне хотелось бы чего-то простого.Например:

$user = User::find($id);
$user->name = 'John Woo';
$user->save();

Или:

$articles = ORM::find('article')->where('date' => '2010-01-01');
foreach ($articles as $article) {
    echo $article->name;
}

Любые советы или даже альтернативные решения приветствуются!

Ответы [ 2 ]

11 голосов
/ 18 января 2011

Я использую ... http://github.com/j4mie/idiorm/

он также имеет активную реализацию записи в виде Парижа.

Что касается вашего редактирования. Идиорм отлично справляется с изменением схем, и синтаксис почти точно соответствует типу, который вы хотите задать в своем вопросе.

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

Насколько хорошо вы изучали Учение?Я использую Doctrine 1.2 для подобных вещей.Довольно прост в настройке, позволяет начать с существующей схемы.Он автоматически вычисляет отношения между таблицами, имеющими ограничения внешнего ключа.

Он имеет обширную поддержку триггеров и поведения, поэтому бонусные баллы можно также тратить, а также имеет реляционную поддержку, поэтому ваши дополнительные запросыне нужны.Он имеет красивую ленивую загрузку и поставляется с гибким языком запросов (называемым DQL), который позволяет вам выполнять почти те же действия, что и в SQL, всего лишь за небольшую часть усилий.

Ваш примербудет выглядеть так:

/* To just find one user */
$user = Doctrine::getTable('User')->findOneById($id);

/* Alternative - illustrating DQL */
$user = Doctrine_Query::create()
    ->from('User u')
    ->where('u.id = ?',array($id))
    ->fetchOne();

$user->name = 'John Woo';
$user->save();

Он должен быть в состоянии работать вместе с существующими необработанными запросами mysql_ *.Я понятия не имею, как ведут себя гидратирующие ORM, такие как Doctrine 2 или Propel, когда скрипты вручную манипулируют данными в базе данных за их спинами, но я предполагаю, что это не красиво.

Ну, это технически невозможноавтоматическое управление;база данных SQL просто не отправляет данные обратно в ORM, поэтому для обновления содержимого, которое было изменено в фоновом режиме, необходимо выполнить дополнительный запрос тем или иным способом.К счастью, Doctrine делает это очень простым для вас:

/* @var User $user */
/* Change a user using some raw mysql queries in my spaghetti function */
$this->feedSpaghetti($user->id);

/* Reload changes from database */
$user->refresh();
...