Доступ к MySQL-базе данных из PHP кажется несколькими способами:
Sprinkle the code with raw SQL-statements
Use the VO-pattern from Java (e.g. 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.






"По-разному"
Для своих собственных проектов я обычно использую какой-то фреймворк, который включает уровень абстракции. Для небольших проектов, которые не подходят для фреймворка, я просто вставляю SQL прямо в скрипт (потому что он маленький). В последний раз, когда я делал крупное приложение без фреймворка, я использовал PDO для поддержки легко подготовленных операторов и т. д. Это довольно простой в освоении уровень абстракции. Я бы, вероятно, использовал его снова, если бы по какой-то причине решил не использовать фреймворк.
По крайней мере, используйте PDO. Он предоставляет общий интерфейс для большинства платформ баз данных, упрощая переключение решений баз данных, если вы когда-нибудь захотите.
Мне нравится использовать объектно-реляционный сопоставитель (ORM), например propel: http://propel.phpdb.org/trac/
Это отображает ваши объекты прямо в схему базы данных - SQL не требуется. Сопоставление происходит в файле XML, запросы выполняются через объекты критериев. Можно реконструировать классы PHP из базы данных или сгенерировать базу данных из XML-схемы.
Для получения дополнительной информации об ORM в целом см. http://en.wikipedia.org/wiki/Object-relational_mapping.
What other patterns are there?
ActiveRecord - вы можете увидеть пример этого в CakePHP.
Я думаю, это сильно зависит от ваших потребностей - если вы создаете небольшое приложение, вероятно, быстрее создать уровень базы данных DIY.
Если вы создаете большое приложение с большим количеством таблиц и взаимосвязей, использование чего-то вроде функции ActiveRecord CakePHP, вероятно, будет быстрее и проще.
Я еще не использовал слой абстракции PEAR, но он тоже неплохо выглядит. Zend также имеет библиотеку базы данных в Zend framework.
Используйте структуру MVC и уровень абстракции базы данных. Таким образом, вы можете перейти в одно место, чтобы полностью переработать внутреннее устройство класса доступа к данным, сохраняя при этом постоянный общедоступный интерфейс.
Необработанный SQL во всем коде будет практически невозможно масштабировать.
Apart from this I have also read about LINQ in .NET but have not seen it implemented in PHP.
Что-то вроде Linq пока не может быть реализовано в PHP, потому что в языке отсутствуют необходимые конструкции. Это своего рода «поддельный linq» был создан, но он использует только строки и не является «настоящим» linq. И даже если бы это было так, это фактически просто эквивалент Linq для объектов, и нет ничего лучше Linq to SQL.
Я бы выбрал Уровень абстракции базы данных MDB2 из PEAR - он предоставляет красивый абстрактный метод работы с базой данных. Я рекомендую его, так как он позволяет писать переносимый код, который можно переносить на другой сервер базы данных без особых изменений (для базового сценария, вероятно, будет достаточно просто изменить вызов подключения). Это слияние старых уровней абстракции DB и Metabase (DB все еще поддерживается для исправления ошибок, но был заменен MDB2).
Он предлагает такие функции, как эмуляция подготовки + выполнения для баз данных, которые не поддерживают его должным образом, и позволяет использовать заполнители, что является хорошей практикой, чтобы избежать проблем с внедрением SQL.
Он будет работать с: mysql / mysqli, pgsql (PostgreSQL), oci8 (Oracle), sqllite, msql, mssql (Microsoft SQL Server), sybase, informix, fbsql, ibase, odbc.
Взгляните на Документация MDB2, чтобы увидеть, как это работает.
Я только что обновился до php7, и MDB2 перестал работать, так что да. Что сказал обман. Выкл, чтобы найти последний лучший пакет абстракции базы данных PHP (ну да ладно, Perl просто придерживался DBD все эти годы, и он все еще просто работает).
Для выполнения команды я бы использовал функции для часто выполняемых команд SQL. Затем эти функции можно использовать для создания чего-то более конкретного, например get_users ().
а) Создайте функцию для каждого запроса, который вы, возможно, захотите сделать, например в качестве
db_select($opts)
где $ opts - массив хешей с ключами:
['table_name', 'selection', 'condition', 'group_by', 'order_by', 'limit']
б) Если вы интенсивно использовали SQL, у меня может возникнуть соблазн создать построитель команд SQL, который принимает хеш-массив и возвращает команду. Что-то вроде:
db_builder(array('select'=>array('customers','from'=>'bar','where'=>'foo=10')))
Вышеупомянутые функции будут использовать это в своих реализациях, как и вы, если вам нужен полностью случайный оператор, и, надеюсь, все это будет надежно, если повсюду повторно использовать код построителя команд.
Я использую двухуровневый подход с ручным кодированием:
Первый уровень - это простой набор функций:
после этого я пишу свой модельный слой со специфическими функциями для всех операций с данными. обычно один файл с разделами для каждого концептуального объекта. параметры привязаны к абстрактным данным, а не к структуре SQL. весь SQL находится в этом слое.
Если вам нужен объектно-ориентированный подход, вот каким был мой подход в последнее время.
Я делю вещи на два класса,
Во-первых, класс DatabaseTable - принимает имя таблицы, строку, которая является ключом этой таблицы. Во-вторых, я создаю класс DatabaseObject, представляющий строку в DatabaseTable. DatabaseObject имеет две процедуры: setFromRow и getAsRow. SetFromRow настроит объект из ассоциативного массива пар col => value, а get as row по существу сериализует объект как пары col => value.
DatabaseTable использует setFromRow для создания объектов DatabaseObject, когда для таблицы вызывается метод 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) с какой объектно-ориентированностью, непросто, поэтому мой метод, я знаю, имеет свои недостатки, и вы, вероятно, получите много разных ответов, каждый со своими недостатками.
Вам нужна объектно-реляционная модель (ORM). Там есть пара разных:
Если ORM слишком много для вашего проекта, вы просто должны вернуться к общему интерфейсу БД, например PDO, и вручную создать подготовленные операторы.
+1 для Doctrine, это многофункциональный слой ORM, который «просто работает». Недавно я использовал это в существующей устаревшей базе данных и был очень впечатлен.
Вы также можете рассмотреть возможность использования CodeIgniter, небольшого красивого фреймворка MVC для PHP. Он имеет как реализацию ActiveRecord, так и разумный набор объектов базы данных (включая связанные переменные). Я считаю, что его классы БД намного лучше, чем стандартные PHP MySQL API, и немного проще, чем PDO (определенно проще в установке).
Любой способ хорош, если вы минимизируете количество точек, в которых вам нужно изменить свой код при изменении схемы вашей базы данных (ввод, фильтрация, проверка, создание формы и т. д.).
Мне нравится упрощать работу с помощью PDO, параметризованный SQL и классы, которые абстрагируют возвращаемый набор данных (::getActiveUsers(), ::getUserPersonalData() и т. д.).
Вы можете использовать ORM, например Doctrine.
Поскольку эта вещь не обновлялась с 2012 года, я думаю, что пришло время проголосовать против этого ответа (также отличный пример того, почему в настоящее время мы избегаем рекомендаций по программному обеспечению).