Laravel การเชื่อมต่อกับฐานข้อมูล

หลังจากที่ หัดใช้ Route และ View เบื้องต้น แล้ว ในตอนนี้เรามาดูวิธีเขียน Laravel เพื่อเชื่อมต่อฐานข้อมูลกัน

โดยจะใช้วิธีการทำ migrate หรือ migration ของ Laravel ซึ่งเปรียบเสมือนเป็นการจัดการควบคุมเวอร์ชั่นของฐานข้อมูล (version control ของ database) เพื่อให้ laravel ทราบว่า โครงสร้างตารางที่ใช้นั้นมีการเปลี่ยนแปลงไปอย่างไร และจะสร้าง แก้ไข หรือลบไฟล์ที่เกี่ยวข้องตามโครงสร้างที่เปลี่ยนไปได้โดยอัตโนมัติ

แล้วใช้ Eloquent ORM เพื่อดึงข้อมูลออกมา

คอนฟิกฐานข้อมูล

เริ่มจากการสร้าง database เพื่อใช้ทดสอบ แล้ว GRANT สิทธิ์เพื่อกำหนดชื่อผู้ใช้ (user) และรหัสผ่าน (password) ในการเชื่อมต่อเข้าฐานข้อมูล

mysql> CREATE DATABASE laravel;

mysql> GRANT ALL ON laravel.* TO 'laravel'@'localhost' IDENTIFIED BY 'laravel-password';

หมายเหตุ ชื่อฐานข้อมูลหรือชื่อผู้ใช้ไม่จำเป็นต้องเป็นชื่อ laravel จะเป็นชื่ออะไรก็ได้ แต่ต้องตรงกับไฟล์คอนฟิกที่เราจะแก้ไขต่อไป

cd เข้าไปในไดเร็กทอรีที่สร้างแอพไว้

[alice@cent6-php ~]$ cd /var/www/html/blog/

ไฟล์คอนฟิกในการเชื่อมฐานข้อมูล จะถูกกำหนดอยู่ในไฟล์ app/config/database.php

Laravel รอบรับฐานข้อมูลได้หลายชนิดทั้ง mysql, sqlite, pgsql ในที่นี้จะกำหนดค่า ‘default’ หรือชนิดของฐานข้อมูลที่จะใช้เป็น mysql

ถ้ากำหนดค่าเป็น mysql ก็ต้องแก้ไขค่าตัวแปรที่ใช้เชื่อมฐานข้อมูลใน array [‘connections][‘mysql’] โดยแก้ไขค่าต่างๆ ให้ตรงกับที่ GRANT สิทธิ์ไว้ตอนแรก

ตัวอย่างการแก้ไขไฟล์

[alice@cent6-php blog]$ vi app/config/database.php
...
    /*
    |--------------------------------------------------------------------------
    | Default Database Connection Name
    |--------------------------------------------------------------------------
    |
    | Here you may specify which of the database connections below you wish
    | to use as your default connection for all database work. Of course
    | you may use many connections at once using the Database library.
    |
    */

    'default' => 'mysql',
...
    /*
    |--------------------------------------------------------------------------
    | Database Connections
    |--------------------------------------------------------------------------
    |
    | Here are each of the database connections setup for your application.
    | Of course, examples of configuring each database platform that is
    | supported by Laravel is shown below to make development simple.
    |
    |
    | All database work in Laravel is done through the PHP PDO facilities
    | so make sure you have the driver for your particular database of
    | choice installed on your machine before you begin development.
    |
    */

    'connections' => array(

        'sqlite' => array(
            'driver'   => 'sqlite',
            'database' => __DIR__.'/../database/production.sqlite',
            'prefix'   => '',
        ),

        'mysql' => array(
            'driver'    => 'mysql',
            'host'      => 'localhost',
            'database'  => 'laravel',
            'username'  => 'laravel',
            'password'  => 'laravel-password',
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),

รัน migrate เพื่อแก้ไขโครงสร้างฐานข้อมูล

รัน php artisan โดยเริ่มต้นระบุออปชั่นเป็น migrate:make ตามด้วยชื่ออะไรก็ได้ เพื่อจะสร้างไฟล์คลาส

คำแนะนำ ให้ตั้งชื่อให้สอดคล้องกับสิ่งที่กำลังจะแก้ไขโครงสร้างฐานข้อมูล เพราะชื่อนี้จะนำไปใช้ในการตั้งชื่อคลาสด้วย เข่นในที่นี้เราจะสร้างตาราง users ขึ้นมา เราก็ตั้งเป็น create_users_table

[alice@cent6-php blog]$ php artisan migrate:make create_users_table
Created Migration: 2015_01_08_135602_create_users_table
Generating optimized class loader
Compiling common classes
Compiling views

คำสั่ง  php artisan migrate:make จะสร้างไฟล์ class ขึ้นมาไว้ในไดเร็กทอรี app/database/migrations/

[alice@cent6-php blog]$ ls -l app/database/migrations/
total 4
-rw-r--r--. 1 alice users 326 Jan  8 20:56 2015_01_08_135602_create_users_table.php

ดูไฟล์ class ได้ สังเกตว่า Laravel จะแปลงชื่อที่ตั้งไว้เป็นชื่อคลาส โดยตัดเครื่องหมาย _ ออก พร้อมเปลี่ยนแต่ละคำเป็นตัวอักษรพิมพ์ใหญ่ (CamelCase)

[alice@cent6-php blog]$ cat app/database/migrations/2015_01_08_135602_create_users_table.php
...

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		//
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		//
	}

}

ไฟล์นี้จะเป็นตัวกำหนดโครงสร้างฐานข้อมูลที่เปลี่ยนไป

เมธอด up() ไว้สำหรับการเปลี่ยนแปลงโครงสร้างข้อมูล เข่นเพิ่ม ลบ แก้ ตารางหรือฟิลด์ต่างๆ

เมธอด down() จะยกเลิกการเปลี่ยนแปลง (rollback) สิ่งที่ถูกเปลี่ยนไปโดยเมธอด up()

ตัวอย่างด้านล่าง ในเมธอด up() จะสร้างตารางชื่อ “users” ประกอบด้วยฟิลด์ id, email, name, timestamps()

หมายเหตุ timestamps() จะเป็นการสร้างฟิลด์ชื่อ created_at และ updated_at ชนิด timestamp เพื่อเก็บเวลาที่แต่ละเรคอร์ด (rows) มีการเปลี่ยนแปลง

ส่วนเมธอด down() เราก็กำหนดไว้เป็นยกเลิกการสร้างตาราง หรือ drop ตารางที่สร้างไว้นั่นเอง

[alice@cent6-php blog]$ vi app/database/migrations/2015_01_08_135602_create_users_table.php
...

class CreateUsersTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // create table
        Schema::create('users', function($table)
        {
            $table->increments('id');
            $table->string('email')->unique();
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        // drop table
        Schema::drop('users');
    }
}

หลังจากแก้ไขไฟล์คลาสเรียบร้อยแล้ว รัน php artisan อีกครั้ง แต่ครั้งนี้ระบุแค่ออปชั่น migrate

[alice@cent6-php blog]$ php artisan migrate
**************************************
*     Application In Production!     *
**************************************

Do you really wish to run this command? y
Migration table created successfully.
Migrated: 2015_01_08_135602_create_users_table

ตอบ y เพื่อยืนยัน

ผลลัพธ์ที่ได้ จากการรัน migrate จะมีการเปลี่ยนแปลงโครงสร้างตารางตามที่กำหนดไว้ในเมธอด up()

mysql> SHOW TABLES;
+-------------------+
| Tables_in_laravel |
+-------------------+
| migrations        |
| users             |
+-------------------+
2 rows in set (0.00 sec)

ตาราง migrations เป็นตารางพิเศษ จะเก็บประวัติการรัน migrate เพื่อเวลาย้อนกลับ (rollback) จะได้ทำอย่างถูกต้อง

mysql> SELECT * FROM migrations;
+--------------------------------------+-------+
| migration                            | batch |
+--------------------------------------+-------+
| 2015_01_08_135602_create_users_table |     1 |
+--------------------------------------+-------+
1 row in set (0.00 sec)

ลองดูตาราง users ที่ถูกสร้างขึ้น

mysql> DESCRIBE users;
+------------+------------------+------+-----+---------------------+----------------+
| Field      | Type             | Null | Key | Default             | Extra          |
+------------+------------------+------+-----+---------------------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| email      | varchar(255)     | NO   | UNI | NULL                |                |
| name       | varchar(255)     | NO   |     | NULL                |                |
| created_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+------------+------------------+------+-----+---------------------+----------------+
5 rows in set (0.00 sec)

ตาราง users ยังไม่มีข้อมูลใดๆ

mysql> SELECT * FROM users;
Empty set (0.00 sec)

ถ้าตารางที่สร้างไว้ไม่ถูกต้อง หรือต้องการยกเลิก สามารถรัน rollback เพื่อเรียกเมธอด down() ได้

[alice@cent6-php blog]$ php artisan migrate:rollback
**************************************
*     Application In Production!     *
**************************************

Do you really wish to run this command? y
Rolled back: 2015_01_08_135602_create_users_table

ตาราง users ก็จะถูก drop ไป

mysql> SHOW TABLES;
+-------------------+
| Tables_in_laravel |
+-------------------+
| migrations        |
+-------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM migrations;
Empty set (0.00 sec)

รัน migrate อีกครั้ง เพื่อสร้างตาราง users กลับมา

[alice@cent6-php blog]$ php artisan migrate
**************************************
*     Application In Production!     *
**************************************

Do you really wish to run this command? y
Migrated: 2015_01_08_135602_create_users_table


mysql> SHOW TABLES;
+-------------------+
| Tables_in_laravel |
+-------------------+
| migrations        |
| users             |
+-------------------+
2 rows in set (0.01 sec)

การใช้ Eloquent ORM เพื่อดึงข้อมูล

หลังจากได้ตารางแล้ว เราลองมาเขียน Laravel เพื่อดึงข้อมูลจากฐานข้อมูลกัน

ใน Laravel หรือ MVC ส่วนของโปรแกรมที่จะใช้ในการเชื่อมต่อกับฐานข้อมูลเราจะเรียกว่า Models โดย Laravel จะกำหนดให้สร้างเป็นไฟล์คลาสไว้ในไดเร็กทอรี app/models/

ตัวอย่างเช่น ต้องการเชื่อมกับตาราง users แนะนำให้ตั้งชื่อคลาส User และสร้างไฟล์คลาสชื่อ User.php

ตัวอย่างของไฟล์คลาส User.php ด้านล่างนี้ ติดมาจากการติดตั้ง laravel อยู่แล้ว ไม่ต้องแก้ไขอะไร

[alice@cent6-php blog]$ vi app/models/User.php 
...
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;

class User extends Eloquent implements UserInterface, RemindableInterface {

	use UserTrait, RemindableTrait;

	/**
	 * The database table used by the model.
	 *
	 * @var string
	 */
	protected $table = 'users';

	/**
	 * The attributes excluded from the model's JSON form.
	 *
	 * @var array
	 */
	protected $hidden = array('password', 'remember_token');

}

โดยดีฟอลต์ Laravel จะทำการ map ชื่อคลาสที่ตั้งไว้ใน models กับชื่อตาราง table ในฐานข้อมูลโดยเติมตัว (s) โดยอัตโนมัติ เช่นในที่นี้ชื่อคลาส User จะถูกแปลงเป็นชื่อตาราง users แต่ถ้าไม่ตรงตามรูปแบบนี้เราสามารถกำหนดไว้ในตัวแปรหรือพรอพเพอรตี้ $table ได้

แก้ไขไฟล์ routes.php เพื่อให้เวลาเรียกพาธ /users ให้มาเรียกใช้ models ที่ชื่อว่า User

[alice@cent6-php blog]$ vi app/routes.php 
...
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/

Route::get('/', function()
{
    return View::make('hello');
});

Route::get('users', function()
{
    $users = User::all();

    return View::make('users')->with('users', $users);
});

คำอธิบาย User::all() เป็นการเรียกคลาส User ใน models เมธอด all() จะเป็นการแสดงทุกเรคอร์ดในตาราง users ซึ่ง Laravel จะจัดการให้เองโดยอัตโนมัติ

ส่วน View::make(‘users’)->with(‘users’, $users) จะเป็นการส่งค่าที่เก็บในตัวแปร $users เข้าไปใน views ที่ชื่อ users

จาก หัดใช้ Route และ View เบื้องต้น เราต้องแก้ไขไฟล์ users.blade.php เพิ่มเติม เพื่อให้สามารถวนลูปเรคอร์ดที่ได้จากตาราง users

ตัวอย่างการแก้ไขไฟล์

[alice@cent6-php blog]$ vi app/views/users.blade.php
@extends('layout')

@section('content')
    @foreach($users as $user)
        <p>{{ $user->name }}</p>
    @endforeach
@stop

ส่วนไฟล์ layout.blade.php เหมือนเดิม

ทดลองเปิดบน browser

l-31

 

เนื่องจากตาราง users ยังไม่มีข้อมูลอะไร

ทดลองใส่ข้อมูลเข้าไปในตาราง users

mysql> INSERT INTO users (email, name) VALUES ('alice@example.com', 'alice');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO users (email, name) VALUES ('bob@example.com', 'bob');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO users (email, name) VALUES ('chris@example.com', 'chris');
Query OK, 1 row affected (0.00 sec)

ลองเปิดบน browser อีกครั้ง

l-32

 

ข้อมูลอ้างอิง

Leave a Reply

Your email address will not be published.