Нужна простая 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();