Слой базы данных CodeIgniter 4

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


Коротко о главном


На данный момент уже есть все то, с помощью чего мы можем совершать подключение к базе данных и производить запросы, использовать Query Builder — класс построения запросов. Пока что ведется работа над Query Caching — классом кэширования запросов, а также Database Forge — вспомогательным классом работы с базой данных и ее таблицами.

Несмотря на достаточно большие количество изменений, использование будет достаточно знакомым и удобным.
Теперь в именах методов вместо змеиного стиля используется верблюжий стиль. Конструктор запросов будет работать в привычном режиме, изучить придется только новые функции. Это очень хорошо, ведь не придется переучиваться и привыкать к новому синтаксису. Но рассмотрим пример изменений.

Конфигурация


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

class Database extends \CodeIgniter\Database\Config
{
    /**
     * Lets you choose which connection group to
     * use if no other is specified.
     *
     * @var string
     */
    public $defaultGroup = 'default';

    /**
     * The default database connection.
     *
     * @var array
     */
    public $default = [
        'dsn'          => '',
        'hostname'     => 'localhost',
        'username'     => '',
        'password'     => '',
        'database'     => '',
        'dbdriver'     => 'MySQLi',
        'dbprefix'     => '',
        'pconnect'     => false,
        'db_debug'     => (ENVIRONMENT !== 'production'),
        'cache_on'     => false,
        'cachedir'     => '',
        'charset'      => 'utf8',
        'dbcollat'     => 'utf8_general_ci',
        'swapPre'      => '',
        'encrypt'      => false,
        'compress'     => false,
        'stricton'     => false,
        'failover'     => [],
        'saveQueries' => true,
    ];

    //--------------------------------------------------------------------
}


Чистые запросы


Создание чистых запросов без использования инструмента Query Builder прост. Нужно получить экземпляр базы данных, запустить query () метод и получить требуемый результат.

// Connects to the default connection, 'default' in this example.
$db = Config\Database::connect();

$query = $db->query('SELECT * FROM users');

// Get results as arrays
$results = $query->getResultArray();

// Get results as objects.
$results = $query->getResultObject();
// Get result as custom class instances
$result = $query->getResult('\My\Class');


Здесь нужно упомянуть, что функция num_rows () была удалена.

Ранее она не была поощрена к использования из-за имеющейся ужасной производительностью и проблемы с памятью при ее использовании.
Вместо этого все result * () методы возвращают пустые массивы, если нет результатов, в то время как все row * () методы не возвращают нуль.

Пример с параметром связывания запроса:
$query = $db->query('SELECT * FROM users WHERE id > ? AND role = ?', [3, 'Admin']);


Параметр связывания получил новый трюк, с именованными параметрами:
$query = $db->query('SELECT * FROM users WHERE id > :id AND role = :role',
    [ 'id'   => 3,
      'role' => Admin'
    ]
);



Все значения автоматически экранируются. Поэтому все запросы безопасны.


Сохраненные запросы


Одним из самых больших изменений в слое базы данных является то, что все запросы сохраняются в истории как объекты запроса, вместо строк в массиве. Это частично очистит код, позволит более гибко кэшировать запрос и т.п.
Например, если нужно получить $ db-> getLastQuery() то в результате вы получите объект запроса, а не строку.

Query Builder


Конструктор запросов работает так, как все привыкли, с одним большим изменением. Query Builder стал собственным классом, а не частью файлов драйвера.

$db = Config\Database::connect();

$result = $db->table('users')
             ->select('id, role')
             ->where('active', 1)
             ->get();


Что еще будет?



Новые методы QueryBuilder — будет добавлены, после того, как Лонни разведает другие фреймворки :) Это позволит увидеть какие полезные функции можно было бы внедрить.

Ниже краткий список новых функций:
  • first() — метод для получения первого результатапредставляет собой удобный метод для получения самого первого результата.
  • increment() и decrement() методы
  • chunk() — метод цикла по всем результатам запроса. Позволит обрабатывать огромное количество строк не убивая сервер и не делая проблемы с памятью.


Улучшенная модель — в CodeIgniter 3 по прежнему есть класс CI_Model, чтобы обеспечить легкий доступ к остальным частям фреймворка, получить доступ к библиотекам и т.д.
В CodeIgniter 4 не будет ни CI_file ни MY_file.

Страничный вывод — эта идея была взята из Laravel и будет работать вместе с новой моделью, чтобы можно было сделать просто так:
$model->paginate(20)




Ссылки по теме


Источник: First Glimpse at CodeIgniter 4 Database Layer
CodeIgniter Wikipedia: ru.wikipedia.org/wiki/CodeIgniter
Официальный сайт CodeIgniter: www.codeigniter.com
Официальный форум CodeIgniter: forum.codeigniter.com
CodeIgniter 4: https://habrahabr.ru/post/275657/
CI Community Apps: https://habrahabr.ru/post/276375/
Requests и Responses в CodeIgniter 4: https://habrahabr.ru/post/278489/
Внедрение зависимостей в CodeIgniter 4: https://habrahabr.ru/post/278641/
Маршрутизация в CodeIgniter 4: https://habrahabr.ru/post/278873/
Модули/HMVC в CodeIgniter 4: https://habrahabr.ru/post/279415/

Комментарии (9)


  1. Fesor
    04.04.2016 14:47
    +3

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

    А где собственно абстракция? Это просто очередной query builder, коих сотни на packagist. Ну и очередная реализация row data gateway. Круто че.


    1. hOtRush
      04.04.2016 16:33
      -1

      А это разве не абстракция?


      1. Fesor
        04.04.2016 16:46
        +1

        Это абстракция над SQL, но никак не над базой данных. И то я не уверен даже, ибо, например, оно не запрещает нам использовать vendor-specific штуки, просто обертка над PDO.


  1. DCrystal
    04.04.2016 21:23
    +1

    $db = Config\Database::connect();
    Если раньше в файле были просто перечислены элементы массива, то теперь это простой класс с тем же массивом.
    Config\Database? Объект конфигурации, который, внезапно, умеет connect()?


  1. Delphinum
    05.04.2016 00:02
    +2

    Все фреймворки считают своей обязанностью переизобрести PDO?


  1. vladnevlad
    05.04.2016 11:45
    +1

    у вас там ошибка в комментариях
    / Get results as objects.
    $results = $query->getResultArray();
    // Get results as arrays
    $results = $query->getResultObject();


    1. condor-bird
      05.04.2016 11:52

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


  1. IvanPanfilov
    05.04.2016 13:16

    > Ниже краткий список новых функций:
    > first() — метод для получения первого результатапредставляет собой удобный метод для получения самого первого результата.
    > increment() и decrement() методы
    > chunk() — метод цикла по всем результатам запроса. Позволит обрабатывать огромное количество строк не убивая сервер и не делая проблемы с памятью.

    может стоит уже наконец открыть для себя генераторы и итераторы а не клепать эти убогие велосипеды? и это еще позорище смеет называется фрейморк для php7?

    // first()

    print_r($pdo->query(«select * from users»)->current());

    // chunk()

    foreach ($pdo->query(«select * from users») as $user) {
    print_r($user);
    }

    // chunk()

    $withFullInfo = function ($users) {
    foreach ($users as $user) {
    $user[«cap»] = //… build capabilities
    yield $user;
    }
    };

    foreach ($withFullInfo($pdo->query(«select * from users»)) as $user) {
    print_r($user);
    }

    // $results = $query->getResultArray();

    iterator_to_array($pdo->query(«select * from users»));

    // $db = Config\Database::connect();

    $db = require «config/connection.php»;

    в файле config/connection.php:

    return new PDO('mysql:host=localhost;dbname=test', «user», «passw»);


  1. maghamed
    05.04.2016 15:49

    21 век, DDD шагает по планете, а я читаю статью про очередной квери билдер-обертку над ПДО