11/08/2018, 20:57

Tích hợp Laravel Eloquent vào bất kỳ project nào

Nhiều khi chúng ta cần một start một project nhỏ gọn, không cần phải quá cầu kỳ, nhưng lại quá quen thuộc với Eloquent của Laravel. Vậy làm sao để sử dụng được Eloquent mà không cần phải dùng cả Framework Laravel đồ sộ. Trong bài này mình sẽ hướng dẫn các bạn cách để có thể sử dụng được tính ...

Nhiều khi chúng ta cần một start một project nhỏ gọn, không cần phải quá cầu kỳ, nhưng lại quá quen thuộc với Eloquent của Laravel. Vậy làm sao để sử dụng được Eloquent mà không cần phải dùng cả Framework Laravel đồ sộ.

Trong bài này mình sẽ hướng dẫn các bạn cách để có thể sử dụng được tính năng Eloquent và Database của Laravel cho bất kỳ Framework nào, thậm chí là một yourself Framework.

Trong bài này mình sử dụng Slim Framework làm demo:

Đây là một Framework cực kỳ nhỏ. Thích hợp cho viết Restful API.

OK. Let begin.

Đầu tiên mình tạo một folder mới lấy tên là slim-eloquent

mkdir slim-eloquent

cd slim-eloquent

Sau đó mình tiến hành cài đặt Slim

composer require --prefer-dist slim/slim

Mình tạo thư mục public và thêm file index.php với nội dung như bên dưới vào trong file mới được tạo ra.

<?php

require_once __DIR__ . '/../vendor/autoload.php';

$slim = new SlimApp();

$slim->get('/', function ($request, $response) {
    $response->write('Hey! Slim started.');
});

$slim->run();

OK. Việc tiến hành cài đặt Slim đã xong, giờ chúng ta kiểm tra lại nhé. Để cho nhanh mình sẽ dùng php build-in server thay vì Apache hay Nginx.

php -S localhost:8000 -t public

alt text

Tiếp theo chúng ta sẽ thực hiện tích hợp Eloquent của Laravel vào trong Project vừa tạo ra. Mình dùng composer để tải package illuminate/database vào trong project.

composer require --update-no-dev illuminate/database illuminate/config

Trước khi tiếp tục mình sẽ bật dịch vụ mysql và tạo database và một schema đơn giản để test.

CREATE TABLE `users` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `name` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
 `email` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
 `role` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
 `is_enabled` TINYINT(1) NULL DEFAULT '0',
 `created_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
 `updated_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

Chèn dữ liệu mẫu

INSERT INTO `users` (`name`, `email`, `role`, `is_enabled`, `created_at`, `updated_at`) VALUES
('Alice ', 'alice@example.com', 'user', 1, '2016-12-05 21:10:33', '2016-12-05 21:10:33'),
('Bob', 'bob@example.com', 'super_user', 1, '2016-12-05 21:10:48', '2016-12-05 21:10:48'),
('Candy', 'candy@example.com', 'user', 1, '2016-12-05 21:11:18', '2016-12-05 21:11:18'),
('David', 'david@example.com', 'user', 1, '2016-12-05 21:11:51', '2016-12-05 21:11:51'),
('Elly', 'elly@example.com', 'supper_user', 1, '2016-12-05 21:12:35', '2016-12-05 21:12:35');

Mình tạo folder config ngang hàng với thư mụcvendor để chứa cấu hình kết nối của database, nội dung của file config này hoàn toàn giống với file config của laravel.

<?php

return [
    'default' => 'mysql',
    'fetch' => PDO::FETCH_CLASS,
    'connections' => [
        'mysql' => [
            'driver' => 'mysql',
            'host' => 'localhost',
            'port' => '3306',
            'database' => 'slim_eloquent',
            'username' => 'root',
            'password' => ',
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => ',
            'strict' => true,
            'engine' => null,
        ],
    ],
];

Tiếp theo bạn sửa file index.php thành

<?php

require_once __DIR__ . '/../vendor/autoload.php';

$slim = new SlimApp();

$illuminateContainer = new IlluminateContainerContainer();
// Load config
$config = new IlluminateConfigRepository();
$config->set('database', require __DIR__ . '/../config/database.php');
$illuminateContainer->instance('config', $config);

// Register database service
$service = new IlluminateDatabaseDatabaseServiceProvider($illuminateContainer);
$service->register();

// Register Database Service
$slim->getContainer()['database'] = $illuminateContainer['db'];

// Routes
$slim->get('/', function ($request, $response) {
    $response->write('Hey! Slim started.');
});

$slim->get('/users', function ($request, $response) {
    $users = $this['database']->table('users')->get();
    return $response->withJson([
        'users' => $users
    ]);
});

$slim->run();

Sau đó chúng ta tiến hành truy cập vào địa chỉ trình duyệt http://localhost:8000/users để kiểm tra lại xem đã sử dụng được Laravel Database chưa.

alt text

Qua các bước trên là bạn đã hoàn toàn sử dụng được package Database của Laravel trong project của mình.

Để sử dụng được ORM Eloquent chúng ta sẽ phải cấu hình thêm một chút, ở đây mình tạo folder app/Models và tạo một class User trong đó, đây là cấu trúc folder.

alt text

<?php
// file app/Modes/User.php
namespace AppModels;

use IlluminateDatabaseEloquentModel;

class User extends Model
{
}

Tiến hành đăng ký autoload cho các class vừa tạo ra, mình sử dụng PSR-4 nên mình sẽ thêm folder app vào trong composer.json với chế độ autoload là PSR-4

"autoload": {
    "psr-4": {
        "App": "app"
    }
}

toàn bộ file composer.json của mình trông sẽ như này.

{
    "require": {
        "slim/slim": "^3.6",
        "illuminate/database": "^5.3",
        "illuminate/config": "^5.3"
    },
    "autoload": {
        "psr-4": {
            "App": "app"
        }
    }
}

sau khi update xong file composer.json chúng ta sẽ tiến hành dump file autoload để composer update lại cấu hình vừa chỉnh sửa.

composer dump-autoload

Bạn thêm dòng dưới đây để tiến hành đăng ký connection cho model.

// Set default connection for models.
IlluminateDatabaseEloquentModel::setConnectionResolver($illuminateContainer['db']);

Mình thêm vào dưới đoạn

// Register database service
$service = new IlluminateDatabaseDatabaseServiceProvider($illuminateContainer);
$service->register();

Thêm route để test

$slim->get('/users/{userId}', function ($request, $response) {
    $id = $request->getAttribute('userId');
    $user = AppModelsUser::find($id);
    return $response->withJson($user);
});

Toàn bộ file index.php của mình trông như này

<?php

require_once __DIR__ . '/../vendor/autoload.php';

$slim = new SlimApp();

$illuminateContainer = new IlluminateContainerContainer();
// Load config
$config = new IlluminateConfigRepository();
$config->set('database', require __DIR__ . '/../config/database.php');
$illuminateContainer->instance('config', $config);

// Register database service
$service = new IlluminateDatabaseDatabaseServiceProvider($illuminateContainer);
$service->register();
// Set default connection for models.
IlluminateDatabaseEloquentModel::setConnectionResolver($illuminateContainer['db']);

// Register Database Service
$slim->getContainer()['database'] = $illuminateContainer['db'];

// Routes
$slim->get('/', function ($request, $response) {
    $response->write('Hey! Slim started.');
});

$slim->get('/users', function ($request, $response) {
    $users = $this['database']->table('users')->get();
    return $response->withJson([
        'users' => $users
    ]);
});

$slim->get('/users/{userId}', function ($request, $response) {
    $id = $request->getAttribute('userId');
    $user = AppModelsUser::find($id);
    return $response->withJson($user);
});

$slim->run();

Bạn truy cập vào địa chỉ http://localhost:8000/users/1

alt text

Bạn đã vừa hoàn thành việc tích hợp package Database của Laravel vào Slim Framework, cách này hoàn toàn áp dụng được cho bất kỳ Framework, hay cả PHP thuần túy.

Trên đây là những chia sẻ nhanh giúp bạn có thể tích hợp một cách nhanh chóng bộ Eloquent với rất nhiều tính năng vào Framework khác hoặc code của chính bạn. Tuy nhiên để bạn sử dụng được trong thực tế thì mình khuyên bạn nên refactor lại để code trong sáng hơn, dễ mở rộng hơn.

Mình sẽ tiến hành refactor lại code trên repo: https://github.com/dotuancd/slim-eloquent

CHÚ Ý: Những bước trên vẫn chưa kích hoạt được hệ thống Events và Paginator của Eloquent. Nếu bạn muốn sử dụng những tính năng này thì tiến hành require thêm package tương ứng là illuminate/events hoặc illuminate/pagination rồi dùng EventServiceProvider và PaginationServiceProvider của package để đăng ký với Laravel Container là các bạn có thể sử dụng ngay được.

0