Пробуем ORM Illuminate из Laravel вместо xPDO

Наткнулся вчера на довольно старую статью Сергея: modzone.ru/blog/2018/02/07/eloquent-and-modx/, заинтересовало, решил попробовать.

Устанавливаем через composer
composer require illuminate/database
Создаём файл core/eloquent.php
<?php
require_once MODX_CORE_PATH . 'vendor/vendor/autoload.php';
include MODX_CORE_PATH . 'config/config.inc.php';
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Eloquent\Model;


$capsule = new Capsule;
$capsule->addConnection([
    'driver' => $database_type,
    'host' => $database_server,
    'database' => $dbase,
    'username' => $database_user,
    'password' => $database_password,
    'charset' => $database_connection_charset,
    'collation' => 'utf8_unicode_ci',
    'prefix' => $table_prefix,
]);
$capsule->bootEloquent();
$capsule->setAsGlobal();


// Класс ресурсов
class Resource extends Illuminate\Database\Eloquent\Model {
    public $table = 'site_content';
}

// Класс пользователей
class User extends Illuminate\Database\Eloquent\Model {
    // Связь с таблицей профилей
    public function profile() {
        return $this->hasOne('Profile', 'internalKey');
    }
}
// Класс профилей
class Profile extends Illuminate\Database\Eloquent\Model {
    public $table = 'user_attributes';
    // Связь с таблицей пользователей
    public function user(){
        return $this->belongsTo('User', 'internalKey');
    }
}
Теперь можно тестировать в Console. Вот немного примеров и тестов:
<?php
require_once MODX_CORE_PATH . 'eloquent.php';

// выборка из 16000 ресурсов
$resources = Resource::where('id', '>', 1)->get();
// PHP time: 0,3174 s
// Total time: 0,3174 s
// Memory: 48 MB

//$resources = DB::table('site_content')->where('id', '>', 1)->get();
// Почему-то не работает, Class 'DB' not found;, но по идее должно быть быстрее, чем через класс Resource

$resources = $modx->getCollection('modResource', ['id:>' => 1]);
// PHP time: 4,3640 s
// Total time: 4,3640 s
// Memory: 228 MB

$q = $modx->newQuery('modResource');
$q->where(['id:>' => 1]);
$q->prepare();
$q->stmt->execute();
$resources = $q->stmt->fetchAll(\PDO::FETCH_ASSOC);
// PHP time: 0,2040 s
// Total time: 0,2040 s
// Memory: 92,71 MB


// Получаем email пользователя
print_r($users = Profile::select('phone')->whereHas('user', function($q) {
    $q->where('id', '=', 3);
})->pluck('phone')->first());
// PHP time: 0,0285 s
// Total time: 0,0285 s
// Memory: 2 MB

$query1 = $modx->newQuery('modUser', [
    'id' => 3,
]);
$query1->select('id');
$userId = $modx->getValue($query1->prepare());
$query2 = $modx->newQuery('modUserProfile', [
    'internalKey' => $userId,
]);
$query2->select('phone');
$phone = $modx->getValue($query2->prepare());
print_r($phone);
// PHP time: 0,0134 s
// Total time: 0,0140 s
// Memory: 0 MB

Моё мнение: синтаксис гораздо лаконичнее и удобнее, чем в xPDO. Гораздо больше возможностей. Для своих таблиц не нужно создавать кучу файлов в model и писать неудобные схемы. Прироста в скорости нет, скорее наоборот. Но это только тесты, может на реальных проектах и быстрее будет. А что вы думаете?
Лёша
06 октября 2022, 16:56
modx.pro
730
+5

Комментарии: 7

Павел Бигель
06 октября 2022, 17:09
0
Почему-то не работает, Class 'DB' not found;
Потому что фасад DB часть совершенно другого неймспейса и он не идет в составе композер пакета который ты устанавливаешь.

но по идее должно быть быстрее, чем через класс Resource
Уж лучше тогда xPDO)
Разница в скорости между Eloquent и фасадным запросом может быть значительной только на уж слишком большом кол-ве записей.
    Лёша
    08 октября 2022, 03:15
    0
    Думаю попробовать на проекте, если понадобится кастомная таблица и вывод элементов с пагинацией. Пагинацию оттуда пока не пробовал. Очень уж не хочется схемы писать, создавать файлы в model и писать пагинацию)
      Лёша
      12 октября 2022, 00:53
      0
      Не знаешь, можно ли в Eloquent вне Laravel пагинацию закастомить? Там twig шаблон вроде нужен.
      И какие ещё интересные штуки в Laravel есть, которые в MODX можно использовать?
    Роман
    07 октября 2022, 10:15
    +1
    print_r($users = Profile::select('phone')->whereHas('user', function($q) {
        $q->where('id', '=', 3);
    })->pluck('phone')->first());
    Красиво.
      Сергей Шлоков
      08 октября 2022, 05:21
      +1
      // Получаем email пользователя
      print_r($users = Profile::select('phone')->whereHas('user', function($q) {
          $q->where('id', '=', 3);
      })->pluck('phone')->first());
      Когда нужно получить запись по id, то не нужно использовать коллекцию с методом first. Это делается проще
      $phone = Profile::findOrFail(3)->phone;
      П.С. Пишешь, что получаешь email, получаешь phone и присваиваешь переменной users ))
        Роман
        09 октября 2022, 21:07
        0
        В чем различия методов:
        findOrFail и firstOrFail
          Лёша
          12 октября 2022, 00:54
          0
          $phone = Profile::findOrFail(3)->phone;
          Так ведь по id пользователя надо получить. а не по id профиля

          P.S. уже понял, не знаю, как комментарий удалить)
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        7