При доступе к базе данных MySQL из PHP существует несколько способов:
Sprinkle the code with raw SQL-statements Use the VO-pattern from Java (eg DB_DataObjects from PEAR) DIY and write a script that auto-generates one PHP class per database
Помимо этого, я также читал о LINQ in .NET
но не видел его реализованного в PHP.
Какие еще шаблоны существуют?
Если сегодня вы начали создавать сайт с нуля, какой из них вы бы выбрали?
Уточнение: речь идет не о слоях абстракции БД (PDO, MDB2). Образец, обсуждаемый здесь, – это то, что вы строите на PDO или MDB2.
Я бы выбрал уровень абстракции базы данных MDB2 из PEAR – он обеспечивает хороший абстрактный метод для работы с базой данных. Я рекомендую его, так как он позволяет вам писать переносимый код, который можно портировать на другой сервер базы данных без необходимости внесения необходимых изменений (для базового скрипта, скорее всего, достаточно будет изменить соединение). Это слияние старых уровней абстракции БД и Метабазы (БД по-прежнему поддерживается для исправлений, но была заменена MDB2).
Он предлагает такие функции, как подготовка + выполнить эмуляцию для DB, которые не поддерживают ее должным образом, и позволяет использовать заполнители, что является хорошей практикой, чтобы избежать проблем с SQL-инъекциями.
Он будет работать с: mysql / mysqli, pgsql (PostgreSQL), oci8 (Oracle), sqllite, msql, mssql (Microsoft SQL Server), sybase, informix, fbsql, ibase, odbc.
Взгляните на документацию MDB2, чтобы увидеть, как она работает.
То, что вы ищете, это объектно-реляционная модель (ORM). Там есть пара разных:
Если ORM слишком много для вашего проекта, вы просто вернетесь к общему интерфейсу DB, например PDO, и создадите подготовленные инструкции вручную.
Какие еще шаблоны существуют?
ActiveRecord – вы можете увидеть пример этого в CakePHP .
Я думаю, что это сильно зависит от ваших потребностей – если вы создаете небольшое приложение, вероятно, быстрее создать слой базы данных DIY.
Если вы создаете большое приложение с большим количеством таблиц и отношений, использование чего-то вроде функции CakePHP ActiveRecord, вероятно, будет быстрее и проще.
Я еще не использовал слой абстракции PEAR, но он также выглядит хорошо. Zend также имеет библиотеку базы данных в рамках Zend .
"Это зависит"
Для моих собственных проектов я склонен использовать какую-то структуру, которая включает в себя слой абстракции. Для небольших проектов, которые не подходят для framewok, я просто поместил SQL в скрипт (потому что он маленький). В прошлый раз, когда я сделал значительное приложение без рамки, я использовал PDO для упрощенной поддержки инструкций и т. Д. Это довольно простой в освоении уровень абстракции. Я бы, вероятно, использовал его снова, если бы я решил не использовать фреймворк по какой-то причине.
Помимо этого, я также читал о LINQ в .NET, но не видел его реализованного в PHP.
Что-то вроде Linq еще не может быть реализовано на PHP, потому что язык не имеет необходимых конструкций. Был создан «поддельный linq», но это просто использует строки и не является «реальным» linq. И даже если бы это было так, это просто эквивалент Linq объектам, и нет ничего такого, как Linq to SQL.
Если вы хотите объектно-ориентированный подход, вот что мой подход был недавно.
Я разделяю вещи на два класса,
Во-первых, класс DatabaseTable – принимает имя таблицы, строку, которая является ключом этой таблицы. Во-вторых, я создаю класс DatabaseObject, который представляет строку в DatabaseTable. В DatabaseObject есть две подпрограммы setFromRow и getAsRow. SetFromRow будет настраивать объект из ассоциативного массива пар col>> value и получать, поскольку строка по существу сериализует объект как пары col => value.
DatabaseTable использует setFromRow для создания DatabaseObjects, когда метод select вызывается в таблице. И наоборот, когда ему говорят обновлять или вставлять данные в свою таблицу, DatabsaeTable будет сериализовать DatabaseObject с помощью getAsRow.
Обычно происходит то, что один наследует от DatabaseObject для своего собственного объекта, определяет setFromRow и getAsRow, а в DatabaseTable указывается имя объекта DatabaseObject для создания экземпляра.
Так что вы в конечном итоге пишете, код мудрый что-то вроде этого
$dbTable = new DatabaseTable('tableName', 'uniqueid', 'InstanceType') // dbTable manufactures an InstanceType for our use based on the select below $dbRow = $dbTable->selectUsingId(15); print_r($dbRow); // Dumps the InstanceTypeObject
Это отделяет представление данных (DatabaseObject) в моем приложении от управления таблицами базы данных (DatabaseTable). Поэтому мой DatabaseObject может быть, в терминологии C ++, обычным-старым-данным.
Конечно, вы можете пойти еще дальше, как я, путем создания связей между таблицами и создания большего количества способов выбора и т. Д.
Я должен добавить, что интеграция того, что по существу является процедурным языком (SQL), с какой объектно-ориентированной задачей непросто, поэтому мой метод, я знаю, имеет свои недостатки, и вы, вероятно, получите множество разных ответов, каждый из которых имеет свои недостатки.
Вы также можете рассмотреть возможность использования CodeIgniter , красивой структуры MVC для PHP. Он имеет как реализацию ActiveRecord, так и разумный набор объектов базы данных (включая связанные переменные). Я нахожу его классы DB намного лучше, чем стандартные PHP MySQL API, и немного проще, чем PDO (что, конечно, проще для установки).
Это определенно будет зависеть от того, насколько большой веб-приложение вы пишете. Я добавлю свои большие пальцы в Doctrine (при правильном использовании). Если это очень маленький, быстрый n-грязный проект, возможно, вам просто удастся использовать PDO .
По крайней мере, используйте PDO. Он обеспечивает общий интерфейс для большинства платформ баз данных, что упрощает переключение решений для баз данных, если вы когда-либо захотите.
Мне нравится использовать объект Relational Mapper (ORM), например propel: http://propel.phpdb.org/trac/
Это отображает ваши объекты прямо в схему базы данных – не требуется SQL. Сопоставление происходит в XML-файле, запрос выполняется через объекты Criteria. Можно перепроектировать PHP-классы из базы данных или создать базу данных из схемы xml.
Для получения дополнительной информации об ORM в целом см. http://en.wikipedia.org/wiki/Object-relational_mapping
Для выполнения команды я бы использовал функции для обычно исполняемых команд SQL. Эти функции затем могут быть использованы для создания чего-то более конкретного типа get_users ()
a) Сделайте функцию для каждого из запросов, которые вы, возможно, захотите сделать, например
db_select($opts)
где $ opts – хэш-массив с ключами:
['table_name', 'selection', 'condition', 'group_by', 'order_by', 'limit']
b) Если вы сильно использовали SQL, у меня возникло бы желание создать SQL-компилятор, который принимает хэш-массив и возвращает команду. Что-то вроде:
db_builder(array('select'=>array('customers','from'=>'bar','where'=>'foo=10')))
Вышеупомянутые функции будут использовать это в своих реализациях, и вам бы хотелось, если бы вам понадобилось совершенно случайное утверждение, и, надеюсь, все это было бы потрясающе, повторно используя код построителя команд повсюду.
Используйте структуру MVC и уровень абстракции базы данных. Таким образом, вы можете перейти в одно место, чтобы полностью переработать внутренности класса доступа к данным, сохраняя постоянный публичный интерфейс.
Необработанный SQL во всем кодексе будет близок к невозможности масштабирования.
Я выполняю двухуровневый подход в ручном режиме:
первый уровень – это простой набор функций:
после этого я пишу свой модельный слой со специальными функциями для всех операций с данными. обычно один файл с разделами для каждого концептуального объекта. параметры привязаны к абстрактным данным, а не к структуре SQL. все SQL находится в этом слое.
Читайте, что сам г-н Лердорф должен сказать о «Добавление структуры» на сайт PHP.
http://www.oracle.com/technology/pub/articles/php_experts/rasmus_php.html
Вы можете использовать ORM, как Doctrine.
Любой способ хорош, если вы минимизируете моменты, когда вам нужно изменить код при изменении схемы базы данных (ввод, фильтрация, валидация, создание формы и т. Д.).
Мне нравится держать его простым с PDO , параметризованным SQL и классами, которые абстрагируют возвращаемый набор данных ( ::getActiveUsers()
, ::getUserPersonalData()
и т. Д.).