Статьи

Начало работы с FluentPDO

Вы знаете историю: написание SQL-запросов так скучно. Особенно, когда у тебя нет времени на это. Если вы чувствуете себя как я, сегодня мы увидим что-то действительно классное: Свободный PDO . Если термин «PDO» звучит для вас новым, не волнуйтесь. Это действительно простая концепция: в мире PHP PDO расшифровывается как Persistent Data Object и помогает вам абстрагироваться от некоторых основных операций, связанных с базой данных (таких как вставка, обновление, удаление и т. Д.). Это слой между вами и базой данных.

Результат? Нет больше запросов SQL. Может быть, это не первый, который вы видели: есть много подобных проектов, и у каждого есть свои ключевые особенности. Основной особенностью Fluent является отличный JOIN Query Builder.

Наш тестовый проект FluentPDO

Прежде всего, нам понадобится пример проекта для работы. Давайте подумаем … а как насчет простого многопользовательского списка пожеланий?

Будет много пользователей, и у каждого будут свои любимые продукты. Для каждого пользователя мы будем хранить имя, фамилию и дату регистрации. Для каждого элемента мы будем хранить название, марку, цену и идентификатор соответствующего пользователя.

Я собираюсь использовать простую базу данных MySQL. Вот структура наших данных:

Sample Project Schema

… И вот дамп SQL (с некоторыми фиктивными данными).

CREATE TABLE IF NOT EXISTS items ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, brand varchar(100) NOT NULL, price decimal(10,2) NOT NULL, user_id int(10) unsigned NOT NULL, PRIMARY KEY (id), KEY user_id (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; INSERT INTO items (id, name, brand, price, user_id) VALUES (1, 'Last Awesome Phone', 'Awesome Brand', '550.00', 1), (2, 'Last Awesome TV', 'Awesome Brand', '1200.00', 1), (3, 'Fantastic E-Car', 'E-Cars Inc.', '80000.00', 2), (4, 'Fantastic E-Bike', 'E-Bikes Co. Ltd.', '16000.00', 2); CREATE TABLE IF NOT EXISTS users ( id int(10) unsigned NOT NULL AUTO_INCREMENT, first_name varchar(100) NOT NULL, last_name varchar(100) NOT NULL, signup_date datetime NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3; INSERT INTO users (id, first_name, last_name, signup_date) VALUES (1, 'Francesco', 'Malatesta', '2014-06-29 13:00:00'), (2, 'John', 'Foo Bar', '2014-06-20 11:16:39'); ALTER TABLE items ADD CONSTRAINT items_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id); 

Примечание. Как вы можете легко представить, это не будет «завершенный» проект. Мы просто пробуем FluentPDO, поэтому мы не собираемся охватывать такие вещи, как вход в систему, регистрация или структура приложения.

Установка

Вы устанавливаете Fluent с Composer, включая библиотеку как зависимость:

 "require": { ... "lichtner/fluentpdo": "dev-master" } 

После того, как вы сделали, вам нужно создать экземпляр как это:

 $pdo = new PDO("mysql:dbname=wishlist", "root", "password"); $fpdo = new FluentPDO($pdo); 

Вам нужно будет указать детали вашего соединения в методе конструктора PDO. Введите имя вашей базы данных после dbname= piece в первом параметре, затем введите имя пользователя и пароль в качестве второго и третьего аргументов.

Затем вы передадите объект PDO в качестве параметра для конструктора объекта FluentPDO.

Вот и все, FluentPDO больше ничего не нужно для работы. Никаких дополнительных настроек.

Основные операции выбора

У нас уже есть некоторые фиктивные данные. Давайте начнем с «Hello World» SQL-запросов. Простой выбор с использованием где и id первичного ключа пользователя в качестве параметра для получения основной информации.

 $user_id = 1; $query = $fpdo->from('users')->where('id', $user_id); foreach($query as $row){ echo 'Hello, ' . $row['first_name'] . ' ' . $row['last_name'] . '!'; } 

Здесь нет ничего сложного для понимания. FluentPDO имеет хороший и читаемый синтаксис, поэтому очень легко понять, что мы делаем.

Метод from() используется для установки правильной таблицы. Метод where() используется для фильтрации наших результатов с тем же предложением name. По умолчанию в методе where() нужно просто указать имя поля и значение. «=» Подразумевается. Конечно, вы также можете использовать различные операторы сравнения. В этом случае вы должны будете написать их сразу после имени поля.

 $fpdo->from('items')->where('price >', 1000); 

Получить результаты очень просто: они хранятся в объекте $query мы только что использовали. Вы можете повторить его с циклом foreach, как показано в примере.

В этом конкретном случае (поиск элемента по его первичному идентификатору) мы также можем использовать ярлык в методе from() :

 $query = fpdo->from('users', $user_id); // will be the same thing as... $query = $fpdo->from('users')->where('id', $user_id); 

Давайте посмотрим на что-то более сложное, чем это.

Выберите конкретные поля

Если вы хотите, вы можете выбрать определенные поля, используя метод select() сразу после from() . Все, что вам нужно сделать, это сообщить FluentPDO, какие поля вы хотите собрать с помощью массива.

Вот пример:

 $query = $fpdo->from('users')->select(array('first_name', 'last_name'))->where('id', $user_id); 

Предел и смещение

Установить предельные и смещенные параметры очень просто, чтобы получить только определенное количество строк из базы данных. Вы можете использовать методы limit() и offset() следующим образом.

 // selecting the first ten results... $query = $fpdo->from('users')->where('id', $user_id)->limit(10)->offset(0); 

Единственным параметром для обоих методов является целое число, указывающее желаемое значение (количество элементов для limit() , количество элементов, пропускаемых для offset() ).

Имея, Группировать по и Сортировать по

Существуют также доступные методы для инструкций «HAVING», «GROUP BY» и «ORDER BY».

Давайте посмотрим на них с некоторыми примерами.

Сортировать по

Метод orderBy() используется для упорядочения результатов по определенным критериям. Давайте приведем пример: вот как упорядочить результаты по цене, от самых дешевых до самых дорогих.

 $query = $fpdo->from('items')->orderBy('price'); 

Если вы хотите инвертировать заказ (получая результаты от самых дорогих к более дешевым), вам просто нужно добавить «DESC» после выбранного вами столбца.

 $query = $fpdo->from('items')->orderBy('price DESC'); 

имеющий

Метод having() имеет очень простой синтаксис. В следующем примере мы фильтруем каждый товар по цене ниже 2000 долларов.

 $query = $fpdo->from('items')->having('price < 2000'); 

Довольно просто.

Вы можете использовать любой оператор сравнения, который вам нужен.

Группа по

С помощью groupBy() вы можете группировать результаты, используя определенное поле в качестве критерия. Здесь мы показываем количество товаров для каждой марки.

 $query = $fpdo->from('items')->select('brand, COUNT(*) AS c')->groupBy('brand'); 

Примечание: вы можете указать псевдоним для поля так же, как в классическом SQL.

Методы выборки

получать

Использование foreach — не единственный способ получить результаты. Что если мы хотим получить только первый результат из набора?

Просто используйте метод fetch() :

 $query = $fpdo->from('users'); $row = $query->fetch(); var_dump($row); // will output: // array(4) { ["id"]=> string(1) "1" ["first_name"]=> string(9) "Francesco" ["last_name"]=> string(9) "Malatesta" ["signup_date"]=> string(19) "2014-06-29 13:00:00" } 

Вы также можете выбрать один столбец, указав его имя в качестве параметра.

 $query = $fpdo->from('users'); $firstName = $query->fetch('first_name'); var_dump($firstName); // will output: // string(9) "Francesco" 

FetchPairs

С fetchPairs() вы можете получить результаты в виде ассоциативного массива. Используя такой синтаксис, как:

 fetchPairs($column1, $column2); 

вы получите вывод, как

 // [column1_value] => "column2_value" 

Вот пример, используя уникальный идентификатор пользователя и имя.

 $query = $fpdo->from('users'); $row = $query->fetchPairs('id', 'first_name'); var_dump($row); // will output: // array(2) { [1]=> string(9) "Francesco" [2]=> string(4) "John" } 

FetchAll

Наконец, что не менее fetchAll() , у нас есть метод fetchAll() .

Вот синтаксис:

 fetchAll($index = '', $selectOnly = '') 

С fetchAll() мы имеем полный контроль над тем, что мы получаем из результата. Первый параметр, $index , является полем, используемым в качестве индекса, $selectOnly полезен для указания того, какие поля вы хотите получить.

Вот вам пример:

 $query = $fpdo->from('users'); $row = $query->fetchAll('id', 'first_name, last_name'); var_dump($row); // will output: // array(2) { [1]=> array(3) { ["id"]=> string(1) "1" ["first_name"]=> string(9) "Francesco" ["last_name"]=> string(9) "Malatesta" } [2]=> array(3) { ["id"]=> string(1) "2" ["first_name"]=> string(4) "John" ["last_name"]=> string(7) "Foo Bar" } } 

Примечание: столбец, используемый в качестве индекса (в данном примере id), также включен в окончательный массив.

Хорошо, этого достаточно для операций выбора. Давайте посмотрим на другие операции CRUD.

Вставить, обновить и удалить

FluentPDO — это не только выбор вещей. У него также есть классы для простого управления данными.

Давайте начнем с операции вставки.

Вставить

 $values = array('first_name' => 'Joe', 'last_name' => 'Doe', 'signup_date' => '2014-06-30 11:00:00'); $query = $fpdo->insertInto('users')->values(values); $insert = $query->execute(); var_dump($insert); // will output: // string(1) "3" 

Метод insertInto() используется для указания таблицы, которую вы хотите использовать для операции. Затем вам нужно будет использовать метод values() для назначения желаемых значений (в этом случае они сохраняются в ассоциативном массиве $values ).

Последним шагом будет метод execute() , который вернет первичный ключ новой записи.

Вы также можете использовать этот ярлык, если вы хотите:

 $query = $fpdo->insertInto('users', $values); 

Обновить

Метод обновления действительно похож. Давайте посмотрим на пример.

 $set = array('last_name' => 'Foo Foo Bar'); $query = $fpdo->update('users')->set($set)->where('id', 2); // you can also use this shortcut: $query = $fpdo->update('users', $set, 1); $query->execute(); 

Используя метод set() вы можете указать новые значения для операции обновления.

С помощью метода where() мы фильтруем затронутые строки. Также есть ярлык, как и раньше.

удалять

Операция удаления еще проще. Вот быстрый пример.

 $query = $fpdo->deleteFrom('users')->where('id', 3); // ... or you can use this: $query = $fpdo->deleteFrom('users', 3); $query->execute(); 

Если вы хотите удалить запись, зная ее первичный ключ, вы можете сделать это с помощью deleteFrom() выше.

Примечание. Как видно из приведенных здесь примеров, вы должны использовать метод execute() для запуска запроса на удаление. Если вы этого не сделаете, вы ничего не измените в базе данных. То же самое работает и для вставок и обновлений. Имейте это в виду.

Расширенные возможности

Как я уже говорил, каждый проект такого рода имеет свои уникальные особенности. Для FluentPDO нет исключений: мы собираемся проанализировать две из этих функций: Join Query Builder и Debugger.

Построитель запросов на присоединение

Вероятно, самая важная уникальная особенность FluentPDO. Конструктор действительно полезен, если вы хотите упростить свою работу и написать меньше кода. Давайте посмотрим, как его использовать.

Мы начнем с «классического» запроса на соединение, сделанного с помощью FluentPDO.

Что-то такое:

 $query = $fpdo->from('items')->leftJoin('user ON user.id = items.user_id')->select('user.first_name'); 

Хорошо, мы используем классический синтаксис в специальном методе leftJoin() . Неплохо.

Тем не менее, мы можем сделать что-то лучше. Если вы используете соглашения в своей структуре таблиц, вы можете использовать этот код:

 $query = $fpdo->from('article')->leftJoin('user')->select('user.name'); 

Отлично, а? Ну, быстрый это действительно круто … а как же умный?

Посмотрите здесь:

 $query = $fpdo->from('items')->select('users.first_name'); 

Это становится лучше.

На самом деле FluentPDO понимает, что вы хотите сделать, и автоматически создает запрос, используя данные, предоставленные вами в методе select() , со table.field_name формата table.field_name .

Здесь вы можете прочитать последний построенный запрос для последнего примера:

 SELECT items.*, users.first_name FROM items LEFT JOIN users ON users.id = items.user_id 

Это определенно выглядит хорошо.

Если вы хотите, конечно, вы можете создать псевдонимы для полей:

 $query = $fpdo->from('items')->select('users.first_name AS user_first_name'); 

Отладчик

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

Он работает с простой системой закрытия. Если вы хотите использовать отладку, просто поместите этот код после кода подключения.

 $fpdo->debug = function($BaseQuery) { echo "query: " . $BaseQuery->getQuery(false) . "<br/>"; echo "parameters: " . implode(', ', $BaseQuery->getParameters()) . "<br/>"; echo "rowCount: " . $BaseQuery->getResult()->rowCount() . "<br/>"; }; 

Вы можете настроить замыкание по $BaseQuery , просто запомните объект $BaseQuery в качестве параметра.

Объект $BaseQuery является экземпляром класса BaseQuery .

Вывод

FluentPDO — это небольшой и простой проект. Он абсолютно не подходит для каждого проекта и может быть улучшен — особенно если учесть, что он не используется в течение шести месяцев — но он может быть хорошим выбором для небольших / средних приложений, на тот случай, если вы не хотите привлекать большие рамки в игре. Благодаря некоторым функциям, таким как Join Query Builder, это хороший компромисс.