Нужна простая ORM или DBAL для существующего приложения PHP

Я работаю над расширением существующего приложения 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 ответа

Решение

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

у него также есть активная реализация записи в форме Парижа.

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

Насколько хорошо вы изучали Учение? Я использую 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();
Другие вопросы по тегам