หลังจากเรียนรู้วิธีการใช้ Model เพิ่ม อ่าน แก้ไข และลบข้อมูลลงบนฐานข้อมูลโดยผ่านการใช้ tinker
ได้แล้ว ในตอนนี้ลองมาสร้างเว็บฟอร์ม เพื่อใช้กรอกข้อมูลผ่านหน้าเว็บแล้วไปเรียกใช้ Model เพื่อบันทึกลงบนฐานข้อมูลกัน
เพื่อให้ผู้อ่านเข้าใจกระบวนการของ Laravel จะขอเพิ่มโปรแกรมทีละส่วน แล้วดู error ที่เกิดขึ้น พร้อมอธิบายการแก้ไข โดยจะใช้รูปแบบการกำหนด url การสร้างไฟล์ ตั้งชื่อคลาส หรือเมธอด แบบที่ทางเว็บไซต์ Laravel หรือ Laracasts แนะนำ
เริ่มต้นแก้ไขไฟล์ routes/web.php
เพิ่ม url articles/create
สำหรับเพิ่มข้อมูล articles
โดยเมื่อมีการเรียกใช้งาน url นี้ ต้องส่งไปประมวลผลที่คลาส ArticleController
ชื่อเมธอด create
ตัวอย่างการแก้ไขไฟล์ routes/web.php
เพื่อเพิ่ม url articles/create
// routes/web.php
...
Route::get('articles/create', 'ArticleController@create');
รันคำสั่ง artisan
ระบุ make:controller
ตามด้วยชื่อคลาส ArticleController
ที่เราต้องการสร้าง
$ php artisan make:controller ArticleController
Controller created successfully.
แก้ไขไฟล์ ArticleController.php
เพิ่มเมธอด create
โดยจะไปเรียกส่วน view ชื่อไฟล์ articles.create
มาแสดงผล
// app/Http/Controllers/ArticleController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ArticleController extends Controller
{
public function create()
{
return view('articles.create');
}
}
สร้างโฟลเดอร์สำหรับไฟล์ view ต่างๆ ของ articles
$ mkdir resources/views/articles
สร้างไฟล์ resources/views/articles/create.blade.php
เพื่อแสดงเว็บฟอร์มเพิ่มข้อมูล
Article create form
ถ้าสร้างไฟล์ต่างๆ ถูกต้อง ทดลองใช้คำสั่ง curl หรือ browser จะได้ผลลัพธ์ Article create from
$ curl http://blog.test/articles/create
Article create form
ก่อนหน้านี้เราได้สร้างไฟล์ resources/views/app.blade.php
เพื่อเป็นโครงสร้างหลักหน้าเว็บ
<html>
<body>
@yield('content')
</body>
</html>
เราสามารถแก้ไขไฟล์ create.blade.php
เพื่อเรียกใช้ไฟล์โครงสร้างหลักหน้าเว็บ
@extends('app')
@section('content')
Article create form
@endsection
หลังการแก้ไข ทดลองใช้คำสั่ง curl หรือ browser ก็จะได้ผลลัพธ์แบบด้านล่าง
$ curl http://blog.test/articles/create
<html>
<body>
Article create form
</body>
</html>
แก้ไขไฟล์ resources/views/articles/create.blade.php
โดยสร้างเว็บฟอร์ม <form>
รองรับการกรอกข้อมูล title
และ body
และเมื่อกดปุ่ม submit ให้ฟอร์มส่งข้อมูลแบบ POST
ไปที่ /articles
@extends('app')
@section('content')
<strong>Article create form</strong>
<form method="POST" action="/articles">
<label>Title:</title><br>
<input type="text" name="title"><br>
<br>
<label>Body:</title><br>
<textarea name="body"></textarea><br>
<br>
<button type="submit">submit</button>
</form>
@endsection
@endsection
เปิดหน้าเว็บฟอร์ม http://blog.test/articles/create ด้วย browsesr แล้วทดลองกรอกข้อมูลในช่อง title
และ body
แล้วกดปุ่ม submit
หลังจากกดปุ่ม submit จะขึ้น error 404 | Not Found
สาเหตุเป็นเพราะเรายังไม่ได้กำหนด url เพื่อรองรับการ submit form
วิธีการแก้ไขทำได้โดยกำหนด url เพิ่มเติมในไฟล์ routes/web.php
เพื่อรองรับการเรียกใช้ articles
แบบเมธอด POST
โดยจะส่งไปประมวลผลที่คลาส ArticleController
ในเมธอด store
// routes/web.php
...
Route::get('articles/create', 'ArticleController@create');
Route::post('articles', 'ArticleController@store');
เพิ่มเมธอด store()
ในคลาส ArticleController
เพื่อรอรับข้อมูลจากการ submit form
// app/Http/Controllers/ArticleController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ArticleController extends Controller
{
public function create()
{
return view('articles.create');
}
public function store(Request $request)
{
return 'store the form data.';
}
}
สังเกตว่า เราระบุพารามิเตอร์ในเมธอด store()
เพื่อเก็บค่าที่ได้รับจากการ submit form ไว้ในตัวแปรออปเจ็คชื่อ $request
เพื่อความง่าย เริ่มต้นขอกำหนดให้เมธอดนี้ส่งผลลัพธ์ง่ายๆ เป็นประโยคว่า store the form data.
(ยังไม่มีการบันทึกลงฐานข้อมูล)
กลับไปที่ browser กรอกข้อมูลในหน้า http://blog.test/articles/create แล้วกด submit อีกที
หลัง submit หน้าเว็บจะขึ้น error ข้อความ 419 | Page Expired
ซึ่ง error นี้เป็นระบบความปลอดภัย คือฟอร์มที่จะส่งข้อมูลได้ ต้องระบุ CSRF Token ให้ถูกต้อง
วิธีการแก้ไข ต้องไปแก้ไขไฟล์ resources/views/articles/create.blade.php
ระบุ @csrf
ภายใต้ <form>
ตัวอย่างเช่น
@extends('app')
@section('content')
<strong>Article create form</strong>
<form method="POST" action="/articles">
@csrf
<label>Title:</title><br>
<input type="text" name="title"><br>
<br>
<label>Body:</title><br>
<textarea name="body"></textarea><br>
<br>
<button type="submit">submit</button>
</form>
@endsection
หลังการเพิ่ม @csrf
กลับไปที่ browser ลองเปิดหน้า http://blog.test/articles/create แล้วลองคลิกขวาที่หน้าเว็บ เพื่อ View Page Source จะเห็น <input>
ชื่อ token
ถูกเพิ่มขึ้นมาภายใต้ <form>
ทดลองกรอกข้อมูล title
และ body
ในเว็บฟอร์ม แล้วกดปุ่ม submit อีกที
หลังจาก submit หน้าจอจะแสดงข้อความที่ได้จากเมธอด store()
ขั้นต่อไป เราจะแก้ไขไฟล์คลาส ArticleController
ในเมธอด store()
โดยจะเรียกใช้เมธอด all()
ของตัวแปรออปเจ็ค $request
เพื่อแสดงข้อมูลที่ได้รับจากการ submit form
dd()
เป็นฟังก์ชันของ Laravel โดยเมื่อเรียกใช้ฟังก์ชันนี้ โปรแกรมจะแสดงค่าในตัวแปรบนหน้าเว็บในรูปแบบที่อ่านง่าย (dump) แล้วโปรแกรมจะหยุดทำงาน die()
// app/Http/Controllers/ArticleController.php
...
public function store(Request $request)
{
dd($request->all());
}
กลับมาที่ browser ถ้าหน้าเว็บค้างอยู่ที่หน้า store the form data
ให้กดปุ่ม reload หรือ refresh ซึ่งจะทำให้ browser ส่งข้อมูล (submit) ที่เคยกรอกอีกที
ตัวอย่างการแสดงค่าออกหน้าเว็บด้วยฟังก์ชัน dd()
ของการเรียกใช้ $request->all()
จะเห็นว่าเราสามารถเรียกใช้ค่าในตัวแปร ที่กำหนดในเว็บฟอร์ม ผ่านทาง $request->all()
เพื่อความเข้าใจง่าย เราจะเก็บค่านี้ไว้ในตัวแปร $input
และเราจะเรียกใช้คลาสเมธอด Article::create()
เพื่อบันทึกค่า title
และ body
ลงฐานข้อมูล
ตัวอย่างการแก้ไขเมธอด store()
ในไฟล์ ArticleController
โดยจะส่งค่า return
ที่ได้จากการเรียกคลาสเมธอด Article::create()
หมายเหตุ อย่าลืมระบุ use App\Article;
ไว้ด้านบนคลาส เนื่องจากคลาส Model และคลาส Controller อยู่คนละ namespace
กัน
// app/Http/Controllers/ArticleController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Article;
class ArticleController extends Controller
{
public function create()
{
return view('articles.create');
}
public function store(Request $request)
{
$input = $request->all();
return Article::create([
'title' => $input['title'],
'body' => $input['body'],
]);
}
}
กลับไปที่ browser แล้วลองกด refresh อีกที หน้าเว็บจะแสดงข้อมูล article ที่เพิ่มสำเร็จ
ถ้าทดลองใช้ mysql
เพื่อดู articles ในฐานข้อมูล ก็จะเห็นข้อมูลที่เรากรอกผ่านหน้าเว็บ
root@blog> SELECT * FROM articles;
+----+-----------------------+----------------------------+---------------------+---------------------+
| id | title | body | created_at | updated_at |
+----+-----------------------+----------------------------+---------------------+---------------------+
| 1 | The First article | Body of the first article. | 2020-04-11 13:01:53 | 2020-04-11 13:01:53 |
| 3 | Updated third article | The body also updated | 2020-04-11 13:07:35 | 2020-04-12 16:08:46 |
| 4 | test title form | test body form | 2020-04-25 12:55:52 | 2020-04-25 12:55:52 |
+----+-----------------------+----------------------------+---------------------+---------------------+
3 rows in set (0.00 sec)
ในตอนต่อไป ลองมาดูวิธีการอ่านข้อมูล articles เพื่อแสดงผลผ่านหน้าเว็บกัน