Laravel : PHP Framework
Glossary | Github | Git | Docker | Heroku | Javascript | Composer | Laravel | Bootstrap | JSLibrary | คำสำคัญ (Key)
ความรู้เบื้องต้นเกี่ยวกับ Laravel
# ความหมาย Laravel
- **Laravel** คือ เฟรมเวิร์คภาษาพีเอชพี (PHP Framework) ในแบบ MVC (Model, Views, Controller) ช่วยในการพัฒนาระบบได้อย่างรวดเร็ว แทนการพัฒนาตามหลักโปรแกรมโครงสร้าง หรือหลักการโปรแกรมเชิงวัตถุ
- นิยามในภาษาอังกฤษจาก wikipedia.org : Laravel is a free, open-source PHP web framework, created by **Taylor Otwell** and intended for the development of web applications following the model–view–controller (MVC)
- [อ่านเพิ่ม https://en.wikipedia.org/wiki/Laravel](https://en.wikipedia.org/wiki/Laravel)

# โปรแกรมสนับสนุนการใช้งาน Laravel
- **XAMPP** หรือ Appserv หรือ Webserver ที่บริการ Apache + PHP + MySQL
- **Composer** คือ เครื่องมือจัดการแพกเกจ หรือไลบรารี่ (Composer Library Mangement) ของภาษาพีเอชพี (PHP Language) ช่วยให้ค้นหา จัดการ
และติดตั้งแพกเกจ หรือไลบรารี่ได้อย่างเป็นระเบียบได้ง่ายขึ้น ซึ่งเดิมจะต้องค้นหา (Search) ดาวน์โหลด (Download) แตกซิปไฟล์ทีละแฟ้ม (Unzip) และปรับคอนฟิก (Config)
แต่การมีคำสั่ง อาทิ composer -h หรือ composer list หรือ composer search blog หรือ composer install ที่กำหนดใน composer.json ทำให้การจัดการแพกเกจง่ายขึ้น
- **Node.js** หรือ Node คือ โปรแกรมสำหรับสั่งให้โปรแกรมภาษา Javascript ที่เขียนขึ้นทำงาน เช่น DOS> node hello.js
ส่วน Node Package Manager (NPM for Node.js packages) คือ โปรแกรมจัดการ Node ซึ่งมี Package ให้จัดการเรียกใช้ได้จำนวนมาก เช่น DOS> npm i react และ npm i react-dom และ npm list สำหรับจัดการ React Library เพื่อเรียกใช้งานได้
ส่วน NPX นั้นมาพร้อมกับ npm รุ่น 5.2 ขึ้นไป ใช้ npx -h พบว่าโปรแกรมนี้คือ Execute binaries from npm packages
เช่น npx create-react-app hello (ระหว่างติดตั้งจะมีการติดตั้ง react, react-dom และ react-scripts เพิ่มด้วย)
- **AdminLTE** คือ เทมเพจที่สวยงามและนำมาใช้ได้ฟรี ทำงานด้วย Bootstrap ที่ถูกพัฒนาโดย Almsaeed Studio [Adminlte-3.0.4](https://adminlte.io/themes/v3/index.html)
เฟรมเวิร์ค และแพลตฟอร์ม ฟรมเวิร์ค (Framework) คือ ชุดคำสั่ง เครื่องมือ โครงสร้าง ต้นแบบพื้นฐาน ที่ถูกสร้างมารองรับการทำงาน เพื่ออำนวยความสะดวกแก่ผู้ใช้งาน แทนที่จะสร้างเองก็มีเครื่องมือที่พร้อมใช้ ช่วยให้พัฒนาระบบได้เร็ว และง่ายขึ้น แต่ขนาดโปรแกรมจะมีขนาดใหญ่ ต้องศึกษาฟังก์ชัน และใช้คุณสมบัติได้เท่าที่มี อาทิ Laravel เป็น Web application framework ส่วน Angular และ React Native เป็น Framework แบบ Cross Platform Technology
พลตฟอร์ม (Platform) คือ การทํางานร่วมกันของฮาร์ดแวร์ หรือซอฟต์แวร์ อาจเป็นระบบปฏิบัติการ สถาปัตยกรรมคอมพิวเตอร์ เช่น ไมโครซอฟท์วินโดวส์ แมคโอเอสเอ็กซ์ หรือแอนดรอย ครอสแพลตฟอร์ม (Cross Platform) คือ การรองรับให้โปรแกรมคอมพิวเตอร์ ภาษาโปรแกรม ระบบปฏิบัติการ หรือ ซอฟต์แวร์ สามารถทำงานได้บนหลายแพลตฟอร์ม เช่น บนไมโครซอฟท์วินโดวส์ บนแมคโอเอสเอ็กซ์ บนลีนุกซ์ บนแอนดรอย และบนเพาเวอร์พีซี
Top 20 Front-end ได้แก่ 1) React Native 2) Framework7 3) Flutter 4) NativeScript 5) Meteor 6) JQuery 7) CocoaTouch 8) Xamarin 9) Swiftic 10) Ionic 11) Sencha Ext JS 12) Apache Cordova 13) Onsen UI 14) Corona SDK 15) Monaca 16) Mobile Angular UI 17) Appcelerator Titanium 18) Uno 19) Ktor 20) Aurelia Top 10 Web Frameworks ได้แก่ 1) Ruby on Rails (Ruby) 2) Laravel (PHP) 3) Django (Python) 4) ASP.NET (C#) 5) Express (JavaScript) 6) Spring (Java) 7) Angular (JavaScript) 8) Ember (JavaScript) 9) Meteor (JavaScript) 10) Vue (JavaScript)
รู้จัก Node.js
# ทดสอบตัวอย่างการใช้ Node.js เบื้องต้น
- DOS> npx create-react-app hello 
- DOS> cd hello 
- DOS> npm start 
- DOS> explorer http://localhost:3000
- ซึ่งทั้ง NPM และ NPX มาพร้อมการติดตั้ง Node.JS ที่ download ได้จาก https://nodejs.org/en/download/
- [อ่านเพิ่ม w3schools.com](https://www.w3schools.com/nodejs/nodejs_get_started.asp)

# การเรียกใช้ Node.js URL Module
- อ่านจาก https://www.w3schools.com/nodejs/nodejs_url.asp
- สร้าง demo.js ที่มีคำสั่งเปิดบริการรองรับ URL Module
- สร้าง summer.html และ winter.html
- DOS> node demo.js
- DOS> explorer http://localhost:8080/ (404 Not Found)
- DOS> explorer http://localhost:8080/summer.html (ok)
```
<!DOCTYPE html><html><body>

Summer

I love the sun!

</body></html> <!DOCTYPE html><html><body>

Winter

I love the snow!

</body></html> ``` # code ใน demo.js ``` var http = require('http'); var url = require('url'); var fs = require('fs'); http.createServer(function (req, res) { var q = url.parse(req.url, true); var filename = "." + q.pathname; fs.readFile(filename, function(err, data) { if (err) { res.writeHead(404, {'Content-Type': 'text/html'}); return res.end("404 Not Found"); } res.writeHead(200, {'Content-Type': 'text/html'}); res.write(data); return res.end(); }); }).listen(8080); ```

Download : PDF
ReactNativeBook [pdf]
ReactJSBook [pdf]
รู้จัก Composer
# รู้จักกับ composer เพิ่มขึ้น
- composer -h แสดงรายการ Options ให้เลือกใช้งาน
- composer -V (1.9.1 2019-11-01 17:20:17)
- composer list หรือ composer แสดงรายการคำสั่งที่จะใช้งานได้ about หรือ list หรือ install 
- composer search [คำที่ต้องการค้น] เช่น composer search blog ก็จะพบ package ให้เลือก เช่น johnpbloch/wordpress หรือ monolog/monolog
- ต้องการดาวน์โหลด johnpbloch/wordpress โดยสร้างแฟ้ม composer.json ให้มี { "require": { "johnpbloch/wordpress": "*" } }
- composer install เพื่อติดตั้ง package ที่กำหนดไว้ใน composer.json

# การติดตั้ง monolog ด้วย composer
- DOS> cd c:\xampp\htdocs\test 
- ต้องการดาวน์โหลด monolog/monolog โดยสร้างแฟ้ม composer.json 
- สร้างแฟ้ม composer.json ด้วย editor มีโค้ด { "require": { "monolog/monolog": ">=1" }, "require-dev": { } }
- DOS> echo  { "require": { "monolog/monolog": "*" } } >composer.json ขนาดแฟ้ม คือ 45 bytes
- DOS> composer install
```
xampp\htdocs\test\composer.json (45 bytes)
xampp\htdocs\test\composer.lock (5699 bytes)
xampp\htdocs\test\vender (138 Files, 18 Folders, 457123 bytes)
xampp\htdocs\test\vender\composer
xampp\htdocs\test\vender\monolog
xampp\htdocs\test\vender\psr
xampp\htdocs\test\vender\autoload.php
```
- [ดู code เป็นเลขฐาน16 ด้วย https://hexed.it/](https://hexed.it/)

# การใช้งาน monolog 
- ถ้ามีปัญหากับ composer.lock ที่เคยมีการติดตั้ง ก็ให้ลบแฟ้ม .lock เพื่อเริ่มต้นติดตั้งใหม่
- หลังติดตั้ง พบรายการ Folder ใน /vender ได้แก่ /composer  /monolog  /psr และแฟ้ม autoload.php 
- [รหัสต้นฉบับที่ github.com/Seldaek/monolog](https://github.com/Seldaek/monolog)
- เรียกใช้เว็บเพจ http://localhost/testmytest.php ด้วย Browser
- ผลลัพธ์แสดงใน c:\xampp\htdocs\test\mytest.log 
```
[2020-03-03 15:10:32] name.WARNING: Foo [] [] 
[2020-03-03 15:10:32] name.ERROR: Bar [] []
```

# โปรแกรมเรียกใช้ monolog
```
require __DIR__ . '/vendor/autoload.php'; 
use Monolog\Logger; 
use Monolog\Handler\StreamHandler; 
// create a log channel 
$log = new Logger('name'); 
$log->pushHandler(new StreamHandler('mytest.log', Logger::WARNING)); 
// add records to the log 
$log->warning('Foo'); 
$log->error('Bar'); 
```
การติดตั้ง Composer ด้วย Laravel
# การติดตั้ง Composer บน Windows
- ติดตั้ง XAMPP7 หรือ PHP7 ตรวจสอบด้วย DOS> php -v
- ติดตั้ง https://getcomposer.org/Composer-Setup.exe ซึ่งต้องระบุตำแหน่งของ php.exe
- ตรวจสอบรุ่นด้วย DOS> composer -V พบรุ่น 1.9.1
- [อ่าน Composer เพิ่มที่ thaiall.com/php/php7.htm](http://www.thaiall.com/php/php7.htm)
- ติดตั้ง Node.js จาก https://nodejs.org/en/download/ (ให้เลือก Installer .msi)
- [อ่าน Node.js เพิ่มที่ thaiall.com/reactnative](http://www.thaiall.com/reactnative/index.html)
```
DOS>node -v (v10.15.3)
DOS>npm -v (6.4.1)
DOS>npx -v (6.4.1)
```

# ติดตั้ง Laravel ด้วย Composer
- DOS> composer create-project --prefer-dist laravel/laravel ex1
- DOS> xcopy ex1 ex1b /e (เพื่อสำรองก่อนปรับปรุง หรือหลังผ่านการทดสอบ)
- DOS> cd ex1 
- DOS> php artisan -V (Laravel Framework 7.9.2)
- DOS> php artisan serve
>    Laravel development server started: http://127.0.0.1:8000 (Ctrl+C)
```
[Folder] (8,596 Files, 1,542 Folders, 36.6MB)
    app
    bootstrap
    config
    database
    public
    resources
    routes
    storage
    tests
    vendor
```
Laravel
# **โฟลเดอร์และไฟล์**
- app เก็บแฟ้มเกี่ยวกับ Model หรือ Controller ที่ใช้ในการประมวลผล และติดต่อกับฐานข้อมูล
- database เก็บแฟ้มเกี่ยวกับ Migrations และ Seeding เพื่อใช้ในการสร้าง Table หรือใส่ข้อมูลผ่าน artisan
- public เก็บแฟ้มเกี่ยวกับ Javascript, CSS, index และ .htaccess 
- resources เก็บแฟ้มเกี่ยวกับ Views
- routes เก็บแฟ้มเกี่ยวกับ Url 
- storage เก็บแฟ้มเกี่ยวกับ Sessions, cache 
- tests เก็บแฟ้มเกี่ยวกับ automated tests
- แฟ้ม .env เก็บค่า config ของ database

# **จุดเด่นของ Laravel**
- มีส่วนขยายให้ใช้จำนวนมาก ผ่านคำสั่ง DOS> php artisan
- เรียกใช้ Class ได้ง่าย และสั้น
- สร้าง Unit test มาทดสอบได้ง่าย
- มี Eloquent ORM เป็นชุดคำสั่งทำ Query ข้อมูลได้ง่าย
- มี Routing ช่วยกำหนด Url ไป View หรือ Controller ได้ง่าย
- มี Restful Controller จัดการทำร้องจากฟอร์มได้ง่าย
- มี View Composer หรือ HTML ที่จัดการง่าย แบ่งเป็น header, container, footer 
- [อ่านเพิ่ม](https://medium.com/@yodsawatse/ทำความรู้จักกับ-laravel-framework-กัน-34e8d39cb254)
- [อ่านเพิ่ม](https://seenual.com/laravel-ติดตั้ง-config-ใช้งาน-authentication-ใช้กั/)

# Blade
- Blade แปลตรงตัว คือใบมีด หรือใบพัด ที่ช่วยเคลื่อนเรือไปข้างหน้า
- Blade ใน Laravel คือ แฟ้มที่เรียกใช้งาน Html template ที่สร้างไว้ แล้วเลือกนำมาประกอบกันขึ้น
มักประกอบด้วย header, footer, menu และ content เพื่อให้ได้หน้าเว็บเพจตามแบบ (Layout) ที่ต้องการ
มีตัวอย่างชื่อแฟ้ม คือ example.blade.php เก็บในโฟรเดอร์รวมเลเอาท์ที่ resources/views
- [อ่านเพิ่ม การใช้ Blade Template](https://www.itoffside.com/laravel-ep10-blade-template/)

# การใช้งาน Blade 
- สร้าง example.blade.php ใน views
- blade อื่่นอาจเรียกใช้ด้วย @extends('example.app')
- controller อาจเรียกใช้ด้วย return view('example');
- route อาจเรียกใช้ด้วย Route::get('example', 'xxxController@example');
การติดตั้ง User authentication
# ติดตั้งระบบ User authentication ใน Laravel
- DOS> cd ex1 
- DOS> composer require laravel/ui
- DOS> php artisan ui vue --auth
- DOS> npm install && npm run dev
- DOS> php artisan serve (มี Login กับ Register)
- เรียกใช้โฮมเพจ http://127.0.0.1:8000 (Ctrl+C)

# แก้ไขแฟ้ม httpd.conf ใน xampp/apache/conf
```
จาก DocumentRoot "C:/xampp7/htdocs/"
เป็น DocumentRoot "C:/xampp7/htdocs/ex1/public"
จาก Directory "C:/xampp7/htdocs/"
เป็น Directory "C:/xampp7/htdocs/ex1/public"
```
- แล้วสั่ง apache_start.bat
- เรียกใช้โฮมเพจ http://localhost (มี Login กับ Register)
- หรือ http://localhost/login หรือ http://localhost/register

# แก้ไขแฟ้ม .env
```
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=
---
- DOS> php artisan migrate (Migration table created successfully)
- DOS> cd c:\xampp7\mysql\bin
- DOS> mysql -u root
```
use test;

# แสดง columns ในตาราง users และ password_resets
```
show columns from users;
Field          | Type             
id             | int(10) unsigned 
name           | varchar(255)     
email          | varchar(255)     
password       | varchar(255)     
remember_token | varchar(100)     
created_at     | timestamp        
updated_at     | timestamp        
show columns from password_resets;
| Field      | Type               
| email      | varchar(255)
| token      | varchar(255)
```

# เรียกใช้โฮมเพจ register
```
http://localhost/ex1/public/register
- name = localhost
- email = localhost@localhost.com
- password = localhost
select * from users;
| id | name      | email                   | password
|  1 | localhost | localhost@localhost.com | $2y$10...adsf
http://localhost/ex1/public/login
```
ทบทวน
# ทบทวน
- DOS> cd c:\xampp7\htdocs\ex1 (unzip ex1:7.8MB)
- DOS> php artisan -V
- DOS> php artisan serve --port=80 (เปิด http://localhost ได้)
- DOS> php artisan serve --host=127.0.0.2 (เปิด127.0.0.1:8000 หรือ localhost:8000 ไม่ได้)
- ปรับแฟ้ม httpd.conf แก้ไข documentroot กับ directory ชี้ไป C:/xampp7/htdocs/ex1/public"
- สั่ง c:\xampp7\apache_start.bat แล้วเปิด http://localhost พบหน้าแรกของ laravel

# สร้าง aboutme
- สร้างแฟ้ม aboutme.blade.php ใน ex1/resource/views แล้วพิมพ์ 
- เปิด routes.php ใน ex1/app/Http มาแก้ไข
- เพิ่มบรรทัด Route::get('/aboutme', function () { return view('aboutme'); }); เป็นบรรทัดสุดท้าย
- เปิดเว็บเพจ http://localhost/aboutme เพื่อดูผล พบผลของ phpinfo();
- เปิด welcome.blade.php ใน ex1/resources/views มาแก้ไข
- เพิ่มบรรทัด 
aboutme ต่อจากข้อความ Your app... - เปิด app.blade.php ใน ex1/resource/views/layouts มาแก้ไข - เพิ่ม
  • Aboutme
  • ต่อลิงค์ของ home
    select ข้อมูลจากตาราง user
    # สร้างข้อมูลรองรับระบบ user authentication
    - สั่ง c:\xampp7\mysql_start.bat และปรับใน .env ให้ติดต่อ mysql แล้ว
    - DOS> cd c:\xampp7\mysql\bin
    - DOS> mysql -u root
    - MariaDB [test]> show columns from users; ไม่พบตาราง test.users
    - DOS> php artisan make:migration create_users_table เพื่อเตรียมสร้างตารางใน MariaDB
    - ตรวจพบแฟ้ม ex1/app/user.php พบ   protected $fillable = ['name', 'email', 'password',];
    - ตรวจพบแฟ้ม create_users_table.php และ create_password_resets_table.php ใน ex1/database/migrations
    - สร้างตารางด้วย DOS> php artisan migrate ใน ex1
    - แต่ select * from user; แล้วว่างเปล่า
    - อ่านเพิ่ม https://laravel.com/docs/5.0/migrations
    
    # เพิ่มระเบียนใน users ด้วย /register
    - เปิดเว็บเพจ http://localhost/register
    - สร้างผู้ใช้ localhost และรหัสผ่าน localost สั่ง Logout 
    - เปิดเว็บเพจ http://localhost/login ได้ 
    - พบว่ามีข้อมูลในตาราง  Users
    
    # สร้าง members สำหรับผู้ที่ login เข้าระบบ
    - เปิด routes.php ใน ex1/app/Http มาแก้ไข
    - เพิ่มบรรทัด Route::get('/members', 'HomeController@members'); ต่อท้าย
    - เปิด HomeController.php ใน ex1/app/Http/Controllers
    - เพิ่มบรรทัด public function members(){return view('members');}
    - สร้างแฟ้ม members.blade.php ใน ex1/resource/views แล้วพิมพ์ Hello World
    - เปิดเว็บเพจ http://localhost/members แล้วเด้งเข้า http://localhost/login
    - ถ้ากรอกรหัสผ่านถูกจะพบ Hello World
    - คัดลอก welcome.blade.php เป็น members.blade.php 
    - แล้วเปลี่ยนข้อความใน 
    เป็น Hello World เพื่อแสดงว่าถูกหน้าแล้ว
    model
    # การแสดงรายการ users ใน members
    - DOS> php artisan make:model mgmtusers เตรียมจัดการข้อมูล
    - เปิด mgmtusers.php ใน ex1/app มาแก้ไข แล้วเพิ่ม
    	protected $table = 'users'; 
    	protected $fillable = [ 'name', 'email','password' ];
    - เปิด HomeController.php ใน ex1/app/Http/Controllers
    - เปลี่ยน function members เป็น
    	$userlist = \App\mgmtusers::all();
        return view('members', ['allusers' => $userlist]);
    - เพิ่ม 3 บรรทัดข้างล่าง แทน Hello World
    	@foreach ($allusers as $u) {{ $u->name }} {{ $u->email }} 
    @endforeach
    insert
    # สร้างฟอร์ม adduser
    - คัดลอก welcome.blade.php เป็น adduser.blade.php
    - เปิด routes.php ใน ex1/app/Http มาแก้ไข 
    - เพิ่มบรรทัด 
    Route::get('/addu',  'HomeController@addu');
    Route::post('/addu',  'HomeController@store');
    -  เปิด HomeController.php ใน ex1/app/Http/Controllers เพิ่ม public function addu(){ return view('adduser'); }
    - เพิ่ม บรรทัดต่อไปนี้ ใน adduser.blade.php
    	
    @csrf
    - เปิด HomeController.php เพิ่ม public function store(Request $request) { \App\mgmtusers::create([ 'name' => $request->get('name'), 'email' => $request->get('email'), 'password' => $request->get('password'), ]); return redirect('/members'); } - DOS> php artisan cache:clear
    delete ข้อมูลจากตาราง user
    # ฟอร์มลบข้อมูล  deluser
    - คัดลอก welcome.blade.php เป็น deluser.blade.php
    - เปิด web.php ใน ex1/routes มาแก้ไข 
    - เพิ่มบรรทัด 
    	Route::get('/delu',  'HomeController@delu');
    	Route::post('/delu',  'HomeController@delbyid');
    -  เปิด HomeController.php ใน ex1/app/Http/Controllers เพิ่ม public function delu(){ return view('deluser'); }
    - เพิ่ม บรรทัดต่อไปนี้ ใน deluser.blade.php
    	
    @csrf
    - DOS> php artisan make:model mgmtusers (ไม่มีโมเดลต่างเครื่อง) - แก้ไข mgmtusers.php ใน ex1/app เพิ่ม protected $table = 'users'; ถ้าไม่เพิ่มจะมีค่าปริยายเป็น "mgmtusers" - เปิด HomeController.php ใน ex1/app/Http/Controllers เพิ่ม public function delbyid(Request $request) { $myname = $request->name; $usr = \App\mgmtusers::where('name',$myname)->first(); $usr->delete(); return redirect('/welcome'); }
    Model
    https://blog.pusher.com/laravel-mvc-use/
    How Laravel implements MVC and how to use it effectively
    DOS> php artisan make:model Product
    	Model created successfully
    DOS>editplus app/Product.php
    ใน class Product
    เพิ่ม protected $fillable = [
               'name',
               'count',
               'price',
               'description',
            ];
    DOS> php artisan make:migration create_product_table
    DOS> editplus database/migrations/2020_05_04_155300_create_product_table.php
    ใน public function up() แทนที่ Schema ด้วยชุดใหม่
    	Schema::create('product', function (Blueprint $table) {
    		$table->increments('id');
    		$table->string('name');
    		$table->text('description');
    		$table->integer('count');
    		$table->integer('price');
    		$table->softDeletes();
    		$table->timestamps();
    	});
    DOS> editplus .env 
    	เปลี่ยน บรรทัดที่ 12 ค่าของ DB_DATABASE=laravel เป็น test
    DOS> php artisan migrate
    	พบ Illuminate\Database\QueryException และ SQLSTATE[HY000] [2002] No connection could be made
    DOS> ..\..\mysql_start.bat
    DOS> php artisan migrate
    DOS> ..\..\mysql\bin\mysql -u root -p
    	use test;
    	select database();
    	show tables;
    	describe product;
    	drop table product;
    	show tables;
    DOS> php artisan migrate:fresh สร้างตารางใหม่ แต่จะล้างตารางในฐานข้อมูลออกหมด
    
    Controller
    php artisan make:controller test1controller
    editplus.exe app/Http/Controllers/test1controller.php
    	public function delete() { return view('deletetest1'); }
    	public function create() { return view('createtest1'); }
    	public function store(Request $request)	{		
    			\App\test1::create([ 'name' => $request->get('name'), 'salary' => $request->get('salary'), ]);
    			return redirect('/test1');
    		}
    	public function index()	{
    			$test1 = \App\test1::all();
    			return view('viewtest1', ['alltest1' => $test1]);
    		}
    php artisan route:list
    
    View
    editplus.exe resources/views/welcome.blade.php
    	<div class="flex-center position-ref full-height">
    	<div class="content">
    	<div class="title m-b-md">Test1 Store</div>
    	<div class="links">
    	<a href="{{ config('app.url')}}/test1/create">Create test1</a>
    	<a href="{{ config('app.url')}}/test1">View test1</a>
    	</div>
    	</div>
    	</div>
    editplus.exe resources/views/createtest1.blade.php
    	<!doctype html><html lang="{{ app()->getLocale() }}">
    	<head><title>Create Test1 | Test1 Store</title></head><body>
    	<div class="flex-center position-ref full-height">
    	<div class="content">
    	<form method="POST" action="{{ config('app.url')}}/test1">
    	@csrf
    	<h1> Enter Details to create a test1</h1>
    	<div class="form-input"><label>Name</label><input type="text" name="name"></div>
    	<div class="form-input"><label>Salary</label><input type="text" name="salary"></div>
    	<button type="submit">Submit</button>
    	</form>
    	</div></div></body></html>
    editplus.exe resources/views/viewtest1.blade.php
    	<!doctype html><html lang="{{ app()->getLocale() }}"><head><title>View Test1 | Test1 Store</title></head>
    	<body><div class="flex-center position-ref full-height">
    	<div class="content"><h1>Here's a list of available test1</h1>
    	<table><thead><td>Name</td><td>Salary</td></thead>
    	<tbody>
    	@foreach ($alltest1 as $test1)
    	<tr><td>{{ $test1->name }}</td><td class="inner-table">{{ $test1->salary }}</td></tr>
    	@endforeach
    	</tbody>
    	</table></div></div></body>
    	</html>
    editplus.exe c:/xampp/apache/conf/httpd.conf
    	DocumentRoot "C:/xampp7/htdocs/mytest/public"
    	<Directory "C:/xampp7/htdocs/mytest/public">
    http://localhost/test1/create
    	พบ 419 Page Expired
    	php artisan cache:clear
    คัดลอกแฟ้มในห้อง AdminLTE-3.0.4 ไปไว้ใน /mytest/public
    editplus.exe resources/views/viewtest1.blade.php
    นำ http://localhost/AdminLTE-3.0.4/pages/tables/data.html มาปรับเป็น viewtest1.blade.php
    http://localhost/test1 (view bootstrap)
    	<div class="card-body">
    	<div class="flex-center position-ref full-height"><div class="content">
    	<h1>Here's a list of available test1</h1>
    	<table><thead><td>Name</td><td>Salary</td></thead>
    	<tbody>
    	@foreach ($alltest1 as $test1)
    	<tr><td>{{ $test1->name }}</td><td class="inner-table">{{ $test1->salary }}</td></tr>
    	@endforeach
    	</tbody></table></div></div></div>
    	<!-- /.card-body -->
    
    CRUD
    รัช (CRUD) มาจากคำว่า Create , Read , Update, Delete คือ ความสามารถพื้นฐานในการกระทำกับข้อมูล ซึ่งประกอบด้วย สร้าง อ่าน ปรับปรุง และลบ ในมุมมองของระบบฐานข้อมูล (Database System) จะมีฟังก์ชันพื้นฐานได้แก่ insert, select, update และ delete สำหรับระบบเว็บมีกลุ่มการจัดการข้อมูลที่เรียกว่า put/post (ทุกเขตข้อมูล), put/patch (บางเขตข้อมูล), get และ delete
    C RUD เป็นความสามารถพื้นฐานของระบบฐานข้อมูลที่ Framework ต่าง ๆ ให้การสนับสนุน เช่น Laravel Framework มี package ชื่อ appzcoder/crud-generator ที่ช่วยสร้าง CRUD, API, Controller, Model, Migration, View แบบอัตโนมัติ สั่งติดตั้งด้วย composer require appzcoder/crud-generator --dev แล้วดึง assets ขึ้นมาใช้งาน ด้วย php artisan vendor:publish --provider="Appzcoder\CrudGenerator\CrudGeneratorServiceProvider" หรืออีกเฟรมเวิร์คที่ได้รับความนิยม Codeigniter Framework ที่ @vitsavavit เขียนบล็อกไว้บน medium.com ซึ่งมีตัวอย่างการสร้าง CRUD ขึ้นมาเอง อธิบายตั้งแต่ขั้นตอนแรกบน Codeigniter ที่แสดงให้เห็นการทำงานร่วมกับ AdminLTE
    CRUD generator package
    https://medium.com/ideagital/มาใช้งาน-laravel-crud-generator-ตัวช่วยสร้าง-crud-สำเร็จรูป-c465ffe8f074
    DOS> php artisan -V
    Laravel Framework 7.16.1
    - โหลด appzcoder/crud-generator
    DOS> composer require appzcoder/crud-generator --dev
    ดึง assets ขึ้นมาใช้งาน
    DOS> php artisan vendor:publish --provider="Appzcoder\CrudGenerator\CrudGeneratorServiceProvider"
    เริ่มสร้าง crud
    http://www.thaiall.com/project/projectdbnwind.htm
    DOS> php artisan crud:generate Categories --fields="categoryid#integer; categoryname#string; description#text" --view-path=northwind --controller-namespace=northwind --route-group=northwind --form-helper=html
    พบแฟ้ม 
    ex1/database/migrations/2020_06_23_120044_create_categories_table.php
    ex1/app/Category.php
    ex1/app/Http/Controllers/Northwind/CategoriesController.php
    ex1/resources/views/northwind/categories
    - create.blade.php
    - edit.blade.php
    - form.blade.php
    - index.blade.php
    - show.blade.php
    DOS> php artisan route:list มีให้เรียกใช้เยอะเลย
    Route Name
    categories.store
    categories.index
    categories.create
    categories.update
    categories.show
    categories.destroy
    categories.edit
    mysql_start.bat
    DOS> php artisan migrate
    DOS> php artisan serve
    127.0.0.1/northwind/categories
    127.0.0.1:8000/northwind/categories
    
    # สร้าง Products
    http://www.thaiall.com/project/projectdbnwind.htm
    Products
    productid	รหัสสินค้า
    productname	ชื่อสินค้า
    supplierid	รหัสผู้จำหน่าย
    categoryid	รหัสกลุ่มสินค้า
    unitsinstock	ปริมาณในคลัง
    unitprice	ราคาต่อหน่วย
    
    # สร้างแฟ้ม products.json ใน ex1
    {
        "fields": [
            {
                "name": "productid",
                "type": "integer"
            },
            {
                "name": "productname",
                "type": "string"
            },
            {
                "name": "supplierid",
                "type": "integer"
            },
            {
                "name": "categoryid",
                "type": "integer"
            },
            {
                "name": "unitsinstock",
                "type": "integer"
            },
            {
                "name": "unitprice",
                "type": "double"
            }
        ]
    }
    
    # สั่ง generate
    DOS> php artisan crud:generate Products 
    --fields_from_file="products.json" --view-path=northwind --controller-namespace=Northwind --route-group=northwind --form-helper=html
    DOS> php artisan migrate
    cd ../../mysql/bin
    mysql -u root
    use test;
    show tables;
    show columns from products;
    drop table products;
    exit;
    DOS> cd ../../htdocs/ex1
    DOS> php artisan serve
    127.0.0.1:8000/northwind/products
    127.0.0.1:8000/northwind/categories
    
    # ติดตั้ง laravel admin ***
    https://laravel-admin.org/docs/#/
    DOS> php artisan -V
    Laravel Framework 7.16.1
    DOS> composer require encore/laravel-admin
    DOS> php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider"
    open ex1/config/admin.php
    DOS> php artisan admin:install
    DOS> php artisan serve
    http://localhost:8000/admin (user: admin password:admin)
    
    รายชื่อ Fields ที่ใช้งานได้ทั้งหมด
    # Form Field
    	text
    	textarea
    	password
    	email
    	number
    	date
    	datetime
    	time
    	radio
    	select
    	file
    
    # Migration Field
    	string
    	char
    	varchar
    	date
    	datetime
    	time
    	timestamp
    	text
    	mediumtext
    	longtext
    	json
    	jsonb
    	binary
    	integer
    	bigint
    	mediumint
    	tinyint
    	smallint
    	boolean
    	decimal
    	double
    	float
    	enum
    
    Model สร้างตารางใหม่ ชื่อ Products ผ่าน Laravel
    # แก้ไขแฟ้ม c:\xampp\htdocs\la1\.env
    ```
    DB_DATABASE=test (DB_DATABASE=laravel)
    DB_USERNAME=root
    DB_PASSWORD=
    ```
    
    # สร้างแฟ้ม 2020_06_30_000000_create_products_table.php ใน  ex4/database/migrations/
    &?php
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    class CreateProductsTable extends Migration {
    public function up()  {
    Schema::create('products', function (Blueprint $table) {
    $table->increments('productid');
    $table->string('productname')->nullable();
    $table->integer('supplierid');
    $table->integer('categoryid');
    $table->double('quantityperunit');
    $table->double('unitprice');
    $table->integer('unitsinstock');
    $table->integer('unitsonorder');
    $table->integer('reorderlevel');
    $table->integer('discontinued');    
    $table->timestamps();
    });
    }
    public function down()  {  Schema::drop('products');  }
    } 
    
    # สั่ง migration จากแฟ้าในห้อง database/migrations
    DOS> php artisan migrate
    ใช้ ..\..\mysql\bin\mysql -u root เข้าไปตรวจด้วย use test; และ show tables; จะพบตาราง products
    และใช้ show columns from products;
    
    Controller สร้างคลาสชื่อ Products แบบ fillable รองรับ addproducts และ delbyid
    # สร้างแฟ้ม Products.php ใน la1/app 
    <?php
    namespace App;
    use Illuminate\Database\Eloquent\Model;
    class Products extends Model {
    protected $table = 'products';
    protected $primaryKey = 'productid';
    protected $fillable = ['productid',
    'productname',
    'supplierid',
    'categoryid',
    'quantityperunit',
    'unitprice',
    'unitsinstock',
    'unitsonorder',
    'reorderlevel',
    'discontinued'];    
    }
    
    # สร้างแฟ้ม ProducstController.php ใน la1/app/Http/Controllers
    <?php
    namespace App\Http\Controllers;
    use Illuminate\Http\Request;
    class ProductsController extends Controller {
    public function __construct() { $this->middleware('auth'); }
    public function index() { return view('home'); }
    public function store(Request $request) {       
    \App\Products::create([
    'productname' => $request->get('productname'),
    'supplierid' => $request->get('supplierid'),
    'categoryid' => $request->get('categoryid'),
    'quantityperunit' => $request->get('quantityperunit'),
    'unitprice' => $request->get('unitprice'),
    'unitsinstock' => $request->get('unitsinstock'),
    'unitsonorder' => $request->get('unitsonorder'),
    'reorderlevel' => $request->get('reorderlevel'),
    'discontinued' => $request->get('discontinued'),
    ]);
    return redirect('/');
    }
    }
    
    # เปิดแฟ้ม la1/app/Http/routes.php หรือ la1/routes/web.php (7.17.1) เพิ่มเส้นทาง
    DOS> php artisan -V (Laravel Framework 7.17.1)
    เพื่อสร้าง route เพื่อให้ create record ถูกเรียกมาทำงาน
    Route::get('/addproducts',  'ProductsController@store');
    สั่งตาม Route - http://localhost/addproducts (ติด auth email:one@hotmail.com p:11111111)
    และ SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'supplierid' cannot be null ..
    http://localhost/addproducts?productname=coke&supplierid=1&categoryid=1&quantityperunit=1&unitprice=1&unitsinstock=1&unitsonorder=1&reorderlevel=1&discontinued=1
    http://localhost/addproducts?productname=pepsi&supplierid=1&categoryid=1&quantityperunit=1&unitprice=1&unitsinstock=1&unitsonorder=1&reorderlevel=1&discontinued=1
    
    # แสดงระเบียนข้อมูลพบ 2 ระเบียน
    - select * from products; พบว่า coke กับ pepsi
    
    # เพิ่มฟังก์ชันลบข้อมูลใน ProducstController.php ใน la1/app/Http/Controllers
    ```
    public function delbyid(Request $request)    {
    $proid = $request->productid;        
    $pro = \App\products::where('productid',$proid)->first();       
    $pro->delete();
    return redirect('/');
    }
    ```
    
    # เพิ่มเส้นทางใน la1/routes/web.php เพื่อลบข้อมูล
    - Route::get('/delbyid',  'ProductsController@delbyid');
    - แล้วสั่ง http://localhost/delbyid?productid=1
    - select * from products; พบว่า ข้อมูลหายไป 1 ระเบียน
    
    ติดตั้ง laravel admin
    ทบทวน แล้วติดตั้ง laravel-admin
    https://laravel-admin.org/docs/#/
    ติดตั้ง xampp php7
    php -v (PHP 7.2.26)
    composer -V (1.9.1 2019-11-01 17:20:17)
    php artisan -V (Laravel Framework 7.16.1)
    DOS>node -v (v10.15.3)
    DOS>npm -v (6.4.1)
    DOS>npx -v (6.4.1)
    mysql_start.bat
    cd c:\xampp\mysql\bin
    mysql -u root
    use test;
    drop table categories;
    drop table a,b,c;
    ลบทุกตารางที่ไม่ได้ใช้
    show tables;
    exit;
    composer create-project --prefer-dist laravel/laravel la1 (8,001 Files, 1,470 Folders, 36.2 MB)
    cd la1
    php artisan -V (Laravel Framework 7.17.1)
    php artisan serve (no login)
    composer require laravel/ui (8,050 Files, 1,487 Folders, 36.3 MB)
    php artisan ui vue --auth
    npm install && npm run dev (22,827 Files, 4,122 Folders, 139 MB)
    # แก้ไขแฟ้ม c:\xampp\htdocs\la1\.env
    ```
    DB_DATABASE=test (DB_DATABASE=laravel)
    DB_USERNAME=root
    DB_PASSWORD=
    ```
    php artisan migrate (ถ้าไม่เปลี่ยนใน .env จาก laravel เป็น test จะ error : Illuminate\Database\QueryException)
    Migration table created successfully.
    Migrating: 2014_10_12_000000_create_users_table
    Migrated:  2014_10_12_000000_create_users_table (0.45 seconds)
    Migrating: 2014_10_12_100000_create_password_resets_table
    Migrated:  2014_10_12_100000_create_password_resets_table (0.31 seconds)
    Migrating: 2019_08_19_000000_create_failed_jobs_table
    Migrated:  2019_08_19_000000_create_failed_jobs_table (0.23 seconds)
    c:\xampp\mysql\bin\mysql -u root
    use test;
    show tables; (failed_jobs, migrations, password_resets, users)
    php artisan serve (Login + Register)
    register ด้วย one@hotmail.com 11111111 พบว่า ลงทะเบียน ออกระบบ เข้าระบบ ได้
    http://127.0.0.1:8000 (Ctrl+C)
    
    composer require encore/laravel-admin (23,996 Files, 4,333 Folders, 146 MB)
    php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider"
    notepad la1/config/admin.php (ดูเฉย ๆ ไม่ได้แก้ไขอะไร)
    php artisan admin:install (24,303 Files, 4,426 Folders, 150 MB)
    in mysql : show tables; (admin_menu, admin_operation_log, admin_permissions, admin_role_menu, admin_role_permissions, admin_role_users, admin_roles, admin_user_permissions, admin_users)
    php artisan serve
    http://localhost:8000/ (ok not change)
    http://localhost:8000/admin (user: admin password:admin)
    http://localhost:8000/admin/auth/users (new nation:nation administrator)
    logout + login by nation (new burin:burin administrator)
    ---
    composer require appzcoder/crud-generator --dev (24,414 Files, 4,448 Folders, 150 MB)
    # https://libraries.io/github/ChangePlaces/crud-generator
    php artisan vendor:publish --provider="Appzcoder\CrudGenerator\CrudGeneratorServiceProvider"
    # http://www.thaiall.com/project/projectdbnwind.htm
    php artisan crud:generate Categories --fields="categoryid#integer; categoryname#string; description#text" --view-path=northwind --controller-namespace=northwind --route-group=northwind --form-helper=html
    Controller created successfully.
    Model created successfully.
    Migration created successfully.
    View created successfully.
    Crud/Resource route added to C:\xampp7\htdocs\la1\routes/web.php
    
    DOS> php artisan route:list มีให้เรียกใช้เยอะเลย
    
    DOS> php artisan migrate 
    DOS> php artisan serve
    http://127.0.0.1:8000/northwind/categories
    apache_start.bat (แก้ไข DocumentRoot กับ Directory ใน httpd.conf ไปที่ la1/public)
    http://127.0.0.1/northwind/categories
    เพิ่ม food, drink, dessert ไปแล้ว
    ปรับ welcome.blade.php in la1/resources/views/ เพิ่มลิงค์ Categories กับ  Admin page และใน "top-right links"
    ปรับ app.blade.php in la1/resources/views/layouts/ เพิ่มลิงค์ thaiall.com หน้าแรก
    ---
    la1_7.17.1_auth_crud_cat.rar (44 MB)
    https://drive.google.com/file/d/1HfQU7JOY8FOrusjwobnKvChI5wfGshPO/view?usp=sharing
    
    การย้าย la1 ไปติดตั้งไซต์ใหม่
    เริ่มจาก .. การแตกแฟ้ม la1_7.17.1_auth_crud_cat.rar (43M) ลงใน htdocs จนได้ห้อง la1 ได้เข้าไปในห้อง la1 ที่มี laravel admin อยู่ ได้สั่ง mysql_start.bat เพื่อเปิดบริการระบบฐานข้อมูล แล้วสั่ง php artisan migrate สั่งสร้างตารางที่เกี่ยวข้อง แล้วใช้ show tables; ใน database : test พบตารางต่าง ๆ พร้อมให้ถูกเรียกใช้ จึงได้สั่ง php artisan serve พบว่าทั้ง 1) categories ที่สร้างจาก crud generate 2) laravel admin (admin:admin) และ 3) user authentication ทำงานได้ปกติ เมื่อนำ laravel ไปใช้ยังต่างเครื่อง
    พบปัญหา user:admin เข้าไม่ได้
    พบ These credentials do not match our records เมื่อสั่ง DOS> php artisan admin:install ในไซต์ใหม่อีกครั้ง พบข้อความ Database seeding completed successfully สรุปว่าข้อมูลผู้ใช้ชื่อ admin ถูก insert เข้าตาราง admin_users ตรวจสอบด้วย select * from admin_users; ได้ครับ
    เปลี่ยนรหัสผ่าน และภาพ
    ต้องเข้า setting จากคลิ๊กภาพ admin มุมบนขวา จะเปลี่ยนภาพและรหัสผ่านได้ แต่ต้องตั้งค่าใน la1/config/filesystems.php โดยเพิ่มข้อกำหนดให้กับ admin ดังนี้ 'admin' => [ 'driver' => 'local', 'root' => public_path('uploads'), 'visibility' => 'public', 'url' => 'http://localhost:8000/uploads/', ],
    การติดตั้ง Laravel ecommerce ใช้ db=test
    E-commerce ด้วย laravel ทดสอบ 24 มิถุนายน 2563
    https://github.com/avored/laravel-ecommerce (lastest version)
    https://github.com/avored/laravel-ecommerce/issues
    https://github.com/avored/laravel-ecommerce/issues/436
    https://www.avored.com/docs/user/installation
    ถ้าลงอีกรอบใหม่ ต้องลบห้องเดิมออกก่อน
    DOS> composer create-project --prefer-dist avored/laravel-ecommerce
    ---
    xampp/apache/conf/httpd.conf 
    เปลี่ยนการชี้ documentroot + directory ไปที่ htdocs/laravel-ecommerce/public
    ถ้าชี้ไปที่ ๆ ไม่มี จะสั่ง apache_start.bat ไม่ขึ้น
    DOS> mysql_start.bat
    DOS> edit laravel-ecommerce/.env 
    DB_DATABASE=test (avored)
    DB_USERNAME=root (root)
    DB_PASSWORD=	(secret)
    DOS> php artisan avored:install
    Would you like to install Dummy Data? (yes/no) [no]: yes
    What is your First Name?: dummy
    What is your last Name?: demo
    What is your Email Address?: usr@usr.com
    What is your Password?: avored
    DOS> php artisan avored:admin:make (admin@admin.com)
    localhost/admin ok
    localhost (ต้องการ spatie)
    ? Class 'Spatie\ViewModels\ViewModel' not found (View: C:\xampp7\htdocs\laravel-ecommerce\resources\views\home.blade.php)
    ? DOS> composer require spatie/laravel-view-models (ติดตั้งเพิ่ม)
    ? คัดลอก new version ทับเข้าไป ที่ download จาก github.com
    php artisan avored:install (ติดตั้งอีกครั้ง)
    
    Avored 101 MB
    การติดตั้ง ecommerce ของ bagisto สมบูรณ์กว่า avored
    # laravel-ecommerce อีกครั้งกับ teste
    apache_start.bat และ mysql_start.bat
    เข้า /public/laravel-ecommerce แล้วแก้ไข db จาก test เป็น teste ใน .env
    create database teste;
    http://localhost/
    พบ SQLSTATE[42S02]: Base table or view not found: 1146 Table 'teste.currencies' doesn't exist (SQL: select * from `currencies`)
    อ่านเพิ่ม https://laravel.com/docs/7.x/migrations
    migrate:refresh จะ roll back แล้วเริ่ม migrate ใหม่
    // Refresh the database and run all database seeds...
    php artisan migrate:refresh --seed
    เปิด localhost ได้ แต่ว่างเปล่า เพราะไม่มีตัวอย่างข้อมูลถูกติดตั้ง
    เปิด localhost/admin ได้ แต่ไม่มีบัญชีเข้า
    ต้อง migrate ผ่านคำสั่งด้านล่างนี้แทน เพื่อตอบคำถามตามสคลิ๊ป
    เช่น Dummy Data? = yes
    php artisan avored:install
    php artisan avored:admin:make
    
    # bagisto - ecommerce
    php artisan route:list
    เปิด https://github.com/drehimself/laravel-ecommerce-example/tree/master/resources/views/auth
    อ่านเพิ่ม https://bagisto.com/en/download/
    https://github.com/bagisto/bagisto
    bagisto-bagisto-v1.1.2-0-gc88ca31.zip (9,597 Files, 2,115 Folders, 72.7 MB)
    - notepad เปิด php.ini มาเปิดบริการ extension=intl ; requred
    - composer create-project bagisto/bagisto-standard
    - เปิด .env มาแก้ไขให้ DB_DATABASE=test และ DB_USERNAME=root
    - php artisan bagisto:install (migration เข้า db)
    - php artisan serve
    http://127.0.0.1:8000/ ยังไม่มีข้อมูลสินค้า
    http://127.0.0.1:8000/admin/login
    email:admin@example.com password:admin123
    http://127.0.0.1:8000/customer/register
    
    bagisto 39 MB
    MVC (Model Views Controller)
    M VC มาจากคำว่า M=Model , V=View , C=Controller คือ สถาปัตยกรรมซอฟต์แวร์ชนิดหนึ่ง ออกแบบมาโดยแยกส่วนตรรกะเนื้อหา (Logic) และส่วนการป้อนข้อมูลและแสดงผล (GUI) ออกจากกัน จึงสามารถแยกการพัฒนา การทดสอบ และการดูแลรักษาได้ โดย โมเดล (Model) หมายถึง ส่วนที่ใช้ในการแปลการทำงานของระบบที่ส่งผลต่อโครงสร้างข้อมูล และปฏิสัมพันธ์กับระบบฐานข้อมูล วิว (View) หมายถึง มุมมองผลลัพธ์ที่ส่งผ่านโมเดลส่งออกไปแสดงผลในรูปแบบที่เหมาะสมกับส่วนประสานปฏิสัมพันธ์กับผู้ใช้ คอนโทรลเลอร์ (Controller) หมายถึง ปฏิบัติการในการควบคุมข้อมูล และการประมวลผลของโปรแกรม และดำเนินการกับระบบฐานข้อมูล
    CRUD
    มาจากคำว่า Create , Read , Update, Delete คือ ความสามารถพื้นฐานในการกระทำกับข้อมูลบนฐานข้อมูล
    Model
    หมายถึง ส่วนที่ใช้ในการแปลการทำงานของระบบที่ส่งผลต่อโครงสร้างข้อมูล และปฏิสัมพันธ์กับระบบฐานข้อมูล
    View
    หมายถึง มุมมองผลลัพธ์ที่ส่งผ่านโมเดลส่งออกไปแสดงผลในรูปแบบที่เหมาะสมกับส่วนประสานปฏิสัมพันธ์กับผู้ใช้
    Controller
    หมายถึง ปฏิบัติการในการควบคุมข้อมูล และการประมวลผลของโปรแกรม และดำเนินการกับระบบฐานข้อมูล
    MODEL
    cd htdocs
    composer create-project --prefer-dist laravel/laravel mytest
    cd mytest
    php artisan make:migration create_test1_table
    // php artisan make:model test1 --migration
    // php artisan make:model test1 --migration --controller --resource
    // php artisan make:model test1 -mcr
    editplus.exe database/migrations/2020_04_27_131703_create_test1_table.php
    เดิมมี $table->id(); เพิ่ม $table->string('name',100)->charset('utf8')->default(0); $table->integer('salary'); ในบรรทัดที่ 17
    เดิมมี Schema::create('test1', function (Blueprint $table) { } เพิ่ม test2
    เปิดแฟ้ม mytest/.env เปลี่ยน DB_DATABASE=laravel เป็น test
    xampp/mysql_start.bat
    cd mytest
    php artisan migrate (พบว่าตาราง test1 และ test2 ถูกสร้างแล้ว พร้อมกับ fields :created_at และ updated_at)
    ---
    php artisan make:model test1
    editplus.exe app/test1.php 
    เพิ่มใน class test1 extends Model
    	protected $table = 'test1'; // test1s เฉยเลย
    	protected $fillable = [ 'name', 'salary', ];
    ---
    php artisan make:controller test1controller
    editplus.exe app/Http/Controllers/test1controller.php
    	public function delete() { return view('deletetest1'); }
    	public function create() { return view('createtest1'); }
    	public function store(Request $request)	{		
    			\App\test1::create([ 'name' => $request->get('name'), 'salary' => $request->get('salary'), ]);
    			return redirect('/test1');
    		}
    	public function index()	{
    			$test1 = \App\test1::all();
    			return view('viewtest1', ['alltest1' => $test1]);
    		}
    php artisan route:list
    editplus.exe resources/views/welcome.blade.php
    	<div class="flex-center position-ref full-height">
    	<div class="content">
    	<div class="title m-b-md">Test1 Store</div>
    	<div class="links">
    	<a href="{{ config('app.url')}}/test1/create">Create test1</a>
    	<a href="{{ config('app.url')}}/test1">View test1</a>
    	</div>
    	</div>
    	</div>
    editplus.exe resources/views/createtest1.blade.php
    	<!doctype html><html lang="{{ app()->getLocale() }}">
    	<head><title>Create Test1 | Test1 Store</title></head><body>
    	<div class="flex-center position-ref full-height">
    	<div class="content">
    	<form method="POST" action="{{ config('app.url')}}/test1">
    	@csrf
    	<h1> Enter Details to create a test1</h1>
    	<div class="form-input"><label>Name</label><input type="text" name="name"></div>
    	<div class="form-input"><label>Salary</label><input type="text" name="salary"></div>
    	<button type="submit">Submit</button>
    	</form>
    	</div></div></body></html>
    editplus.exe resources/views/viewtest1.blade.php
    	<!doctype html><html lang="{{ app()->getLocale() }}"><head><title>View Test1 | Test1 Store</title></head>
    	<body><div class="flex-center position-ref full-height">
    	<div class="content"><h1>Here's a list of available test1</h1>
    	<table><thead><td>Name</td><td>Salary</td></thead>
    	<tbody>
    	@foreach ($alltest1 as $test1)
    	<tr><td>{{ $test1->name }}</td><td class="inner-table">{{ $test1->salary }}</td></tr>
    	@endforeach
    	</tbody>
    	</table></div></div></body>
    	</html>
    editplus.exe c:/xampp/apache/conf/httpd.conf
    	DocumentRoot "C:/xampp7/htdocs/mytest/public"
    	<Directory "C:/xampp7/htdocs/mytest/public">
    http://localhost/test1/create
    	พบ 419 Page Expired
    	php artisan cache:clear
    คัดลอกแฟ้มในห้อง AdminLTE-3.0.4 ไปไว้ใน /mytest/public
    editplus.exe resources/views/viewtest1.blade.php
    นำ http://localhost/AdminLTE-3.0.4/pages/tables/data.html มาปรับเป็น viewtest1.blade.php
    http://localhost/test1 (view bootstrap)
    	<div class="card-body">
    	<div class="flex-center position-ref full-height"><div class="content">
    	<h1>Here's a list of available test1</h1>
    	<table><thead><td>Name</td><td>Salary</td></thead>
    	<tbody>
    	@foreach ($alltest1 as $test1)
    	<tr><td>{{ $test1->name }}</td><td class="inner-table">{{ $test1->salary }}</td></tr>
    	@endforeach
    	</tbody></table></div></div></div>
    	<!-- /.card-body -->
    
    viewtest11.blade.php
    http://localhost/test11
    เปิด routes/web.php
    	Route::get('/test11', function () { return view('viewtest11'); });
    ---
    <?php
    foreach (\App\test1::all() as $test) { echo $test->name . $test->salary; }
    
    deletetest1.blade.php
    https://www.itsolutionstuff.com/post/laravel-57-crud-create-read-update-delete-tutorial-example-example.html
    https://laravel.com/docs/4.2/eloquent
    http://localhost/test1/delete
    editplus.exe mytest/routes/web.php
    	Route::get('/delete', function () { return view('deletetest1'); });
    	Route::delete('/delete/{id}', 'test1Controller@destroy');
    	Route::post('/delete',  'test1Controller@destroygetid');
    editplus.exe resources/views/deletetest1.blade.php
    	<!doctype html><html><head><title>Delete</title></head><body>
    	<div class="flex-center position-ref full-height">
    	<div class="content">
    	<form method="POST" action="{{ config('app.url')}}/delete">
    	@csrf
    	<h1>Delete</h1>
    	<div class="form-input"><label>ID</label><input type="text" name="id"></div>
    	<button type="submit">Submit</button>
    	</form>
    ---
    	<form action="{{ config('app.url')}}/delete/1" method="post">
    	<input class="btn btn-default" type="submit" value="Delete" />
    	<input type="hidden" name="_method" value="delete" />
    	<input type="hidden" name="_token" value="{{ csrf_token() }}">
    	</form>
    https://github.com/scotch-io/laravel-database-course/blob/master/app/Http/Controllers/UserController.php
    editplus.exe app/Http/Controllers/test1controller.php
    	public function destroy($id)    {
            $test1 = \App\test1::find($id);
            $test1->delete();        
            return redirect('/test1');
        }
    	public function destroygetid(Request $request)    {
    		$myid = $request->id;
            $test1 = \App\test1::find($myid);
            $test1->delete();        
            return redirect('/test1');
        }
    
    abc.blade.php
    php artisan serve
    เปิด routes/web.php
    	Route::get('/abc', 'test1Controller@abc');
    editplus.exe app/Http/Controllers/test1controller.php
    	public function abc()
    	{
    		$test1 = \App\test1::orderByDesc('salary')->get();
    		return view('abc', ['alltest1' => $test1]); // abc.blade.php
    	}
    editplus.exe def.blade.php
    	<?php
    	foreach (\App\test1::orderByDesc('salary')->get() as $test)
    	{
    		 echo $test->name . $test->salary;
    	}
    http://localhost:8000/test2
    https://laravel.com/docs/7.x/eloquent
    https://laravel.com/docs/7.x/validation
    
    changename.blade.php
    http://localhost/test1/changename
    editplus.exe mytest/routes/web.php
    	Route::get('/changename', function () { return view('changename'); });
    	Route::post('/changename',  'test1Controller@changename');
    editplus.exe resources/views/changename.blade.php
    	<!doctype html><html><head><title>Changename</title></head><body>
    	<div class="flex-center position-ref full-height">
    	<div class="content">
    	<form method="POST" action="{{ config('app.url')}}/changename">
    	@csrf
    	<h1>Changename</h1>
    	<div class="form-input"><label>ID</label><input type="text" name="id"></div>
    	<div class="form-input"><label>Name</label><input type="text" name="name"></div>
    	<button type="submit">Submit</button>
    	</form>
    	</div></div></body></html>
    https://github.com/scotch-io/laravel-database-course/blob/master/app/Http/Controllers/UserController.php
    editplus.exe app/Http/Controllers/test1controller.php
    	public function changename(Request $request)    {
    		$myid = $request->id;
    		$myname = $request->name;
    		$chg = \App\test1::find($myid);
    		$chg->name = $myname;
    		$chg->save();
    		// หรือ $affectedRows =  \App\test1::where("id", $myid)->update(["name" => $myname]); 
            return redirect('/test1');
        }
    
    ปรับใช้ Laravel
    หลังติดตั้ง laravel ผ่านคำสั่ง DOS> composer create-project --prefer-dist laravel/laravel ex4
    พบแฟ้มที่ออกแบบตามโครงสร้าง MVC (Model Views Controller) อย่างเป็นระบบ
    1. เปลี่ยนสีพื้นของ index.php
    	แก้ไขแฟ้ม htdocs/ex4/resources/views/welcome.blade.php
    	เปลี่ยนบรรทัดที่ 15 background-color: #fff; เป็น #ffffdd
    2. ลิงค์ต่าง ๆ เช่น Docs ถึง GitHub ก็สามารถแก้ไขในแฟ้ม welcome.blade.php
    3. 19 เมษายน 2563 คำสั่ง php artisan make:auth ใช้ไม่ได้ ต้องใช้
      composer require laravel/ui
      php artisan ui vue --auth
      npm install && npm run dev
    4. สร้าง laravel.blade.php ใน htdocs/ex4/resources/views
    	สั่งแสดง Hello world !
    5. พบการกำหนดเส้นทางใน ex4/routes/web.php
    	ว่า Route::get('/', function () { return view('welcome'); });
    	เปลี่ยนเป็น Route::get('/', function () { return view('laravel'); });
    	เมื่อเรียก http://localhost/ex4/public/ ก็จะพบ Hello world !
    6. เปิดแฟ้ม xampp/apache/conf/httpd.conf
    	มองหา DocumentRoot "C:/xampp7/htdocs" กับ Directory "C:/xampp7/htdocs"
    	แล้วเปลี่ยนเป็น C:/xampp7/htdocs/ex4/public
    	ต่อไปเปิด http://localhost/ ก็จะพบ Hello world !
    7. เพิ่มเส้นทางในแฟ้ม web.php สำหรับ /welcome และ /table/5
    	https://www.cloudways.com/blog/routing-in-laravel/
    	Route::get('/welcome', function () { return view('welcome'); });
    	Route::get('/table/{number}', function ($number) {
    	   for($i =1; $i <= 10 ; $i++){ echo "$i * $number = ". $i* $number ."<br>";  }   
    	});
    	Route::get('/table/{number?}', function ($number = 5) {
    	   for($i =1; $i <= 10 ; $i++){ echo "$i * $number = ". $i* $number ."<br>";  }   
    	});
    8. สร้าง Controller ด้วย DOS> php artisan make:controller MyController
    	จะพบแฟ้ม MyController.php ใน ex4/app/Http/Controllers
    9. เรียก Function name จาก YourController (MyController.php)
    	https://www.itoffside.com/laravel-ep5-routing/
    	กำหนดการเรียกใน MyController ใน web.php
    	Route::get('/hello', 'MyController@helloworld');
    9. เปิด ex4/app/Http/Controllers/MyController.php
    	เพิ่ม 	public function helloworld() { return view('welcome'); } ใน class MyController
    	เปิด localhost/hello ก็พบ view : welcome.blade.php มาทำงาน
    	อ่านเพิ่มเติม
    	บทเรียนแรก https://laravel-news.com/your-first-laravel-application
    	https://laravel-news.com/category/laravel-tutorials
    	https://www.cloudways.com/blog/routing-in-laravel/
    	https://www.w3schools.in/laravel-tutorial/routing/
    	https://www.programmer-books.com/laravel-5-cookbook-pdf/
    	https://www.programmer-books.com/wp-content/uploads/2018/08/laravel_5_cookbook.pdf
    	https://github.com/driade/laravel-book/blob/master/laravel-docs-5.8.pdf
    
    AdminLTE-3.0.4 บน laravel + Modal
    เปิดแฟ้ม xampp/apache/conf/httpd.conf
    มองหา DocumentRoot "C:/xampp7/htdocs" กับ Directory "C:/xampp7/htdocs"
    แล้วเปลี่ยนเป็น C:/xampp7/htdocs/ex4/public
    ---
    ย้าย folder AdminLTE-3.0.4 ลงใน htdocs/ex4/public
    แล้วเรียก http://localhost/AdminLTE-3.0.4/
    พบว่าทำงานปกติ เปิดพบ http://localhost/AdminLTE-3.0.4/pages/tables/data.html
    และ http://localhost/products
    มองหา viewproducts.blade.php ใน ex4/resources/views
    จึงคัดลอก code ใน data.html ไปแทนที่ในแฟ้มนี้
    http://localhost/products พบว่าการอ้างอิงไม่ถูกต้อง
    แก้ไขโดย ย้ายทุกแฟ้มใน AdmitLTE-3.0.4 ไปในห้อง public แล้ว /products จะทำงานปกติ
    ---
    นำข้อมูลตั้งแต่ ใต้ body ทั้งหมด 
    ไปใส่ใน card-body เป็นอันเรียบร้อย
    <div class="card-body">
    <div class="flex-center position-ref full-height">
    <div class="content">
    <h1>Here's a list of available products</h1>
    <table>
    <thead>
    <td>Name</td>
    <td>Description</td>
    <td>Count</td>
    <td>Price</td>
    </thead>
    <tbody>
    @foreach ($allProducts as $product)
    <tr>
    <td>{{ $product->name }}</td>
    <td class="inner-table">{{ $product->description }}</td>
    <td class="inner-table">{{ $product->count }}</td>
    <td class="inner-table">{{ $product->price }}</td>
    </tr>
    @endforeach
    </tbody>
    </table>
    </div>
    </div>
    </div>
    <!-- /.card-body -->
    
    Model
    Models in Laravel
    https://laravel.com/docs/7.x/eloquent#introduction
    https://laravel.com/docs/7.x/migrations
    https://blog.pusher.com/laravel-mvc-use/
    cd htdocs 
    php artisan (Could not open input file: artisan)
    cd ex4
    php artisan (Laravel Framework 7.6.2)
    editplus.exe htdocs/ex4/config/database.php
    'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''),
    'database' => env('DB_DATABASE', 'test'), 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', ''),
    php artisan make:model Flight --migration
    Created Migration: 2020_04_24_140657_create_flights_table
    พบแฟ้มนี้ใน ex4/database/migrations/2020_04_24_140657_create_flights_table.php
    บรรทัดที่ 17 พบ  $table->id();
    เพิ่ม $table->string('name',100)->charset('utf8')->default(0);
    เพิ่ม $table->integer('salary');
    ก่อนบรรทัดนี้	$table->timestamps();
    พบ Flight.php ใน ex4/app
    เปิดแฟ้ม ex4/.env
    เปลี่ยน DB_DATABASE=laravel เป็น test
    php artisan migrate
    สร้างตาราง Flights มาให้
    ---
    xampp/mysql_start.bat
    cd xampp/mysql/bin
    mysql -u root -p (Server version: 10.4.11-MariaDB)
    use test;
    create table books (
     id int(11) NOT NULL,
     name varchar(256) NOT NULL,
     category varchar(256) NOT NULL,
     description text NOT NULL
    );
    
    Create Controller + Model
    https://blog.pusher.com/laravel-mvc-use/
    php artisan make:model Product
    เปิดแฟ้ม ex4/app
    เพิ่มใน class Product
    	protected $fillable = [
               'name',
               'count',
               'price',
               'description',
            ];
    php artisan make:migration create_products_table
    เปิดแฟ้มใน ex4/database/migrations/
    เปลี่ยนในแฟ้ม 
    $table->id();
    $table->timestamps();
    เป็น 
    $table->increments('id');
    	$table->string('name');
    	$table->text('description');
    	$table->integer('count');
    	$table->integer('price');
    	$table->softDeletes();
    	$table->timestamps();
    
    php artisan make:controller ProductController -r
    editplus.exe ex4/routes/web.php
    เพิ่ม Route::resource('/products', 'ProductController');
    php artisan route:list
    จะพบแฟ้ม ProductController.php ใน ex4/app/Http/Controllers
    public function create()
        {
            return view('createproduct'); // เพิ่มมาใหม่
        }
    public function store(Request $request)
        {		
            \App\Product::create([
              'name' => $request->get('name'),
              'description' => $request->get('description'),
              'price' => $request->get('price'),
              'count' => $request->get('count'),
            ]);
            return redirect('/products');
        }
     public function index()
        {
           $products = \App\Product::all();
            return view('viewproducts', ['allProducts' => $products]);
        }
    
    เปิด ex4/resources/views/welcome.blade.php
    
    <div class="flex-center position-ref full-height">
          <div class="content">
            <div class="title m-b-md">Product Store</div>
            <div class="links">
              <a href="{{ config('app.url')}}/products/create">Create Product</a>
              <a href="{{ config('app.url')}}/products">View Products</a>
            </div>
          </div>
        </div>
    
    http://localhost/products/create
    
    สร้างแฟ้ม createproduct.blade.php
    <!doctype html>
        <html lang="{{ app()->getLocale() }}">
        <head>
          <title>Create Product | Product Store</title>
          <!-- styling etc. -->
        </head>
        <body>
            <div class="flex-center position-ref full-height">
                <div class="content">
                    <form method="POST" action="{{ config('app.url')}}/products">
                        <h1> Enter Details to create a product</h1>
                        <div class="form-input">
                            <label>Name</label> <input type="text" name="name">
                        </div>
                        <div class="form-input">
                            <label>Description</label> <input type="text" name="description">
                        </div>
                        <div class="form-input">
                            <label>Count</label> <input type="number" name="count">
                        </div>
                        <div class="form-input">
                            <label>Price</label> <input type="number" name="price">
                        </div>
                        <button type="submit">Submit</button>
                    </form>
                </div>
            </div>
        </body>
        </html>
    
    สร้างแฟ้ม viewproducts.blade.php
    <!doctype html>
        <html lang="{{ app()->getLocale() }}">
        <head>
            <title>View Products | Product Store</title>
            <!-- Styles etc. -->
        </head>
        <body>
            <div class="flex-center position-ref full-height">
                <div class="content">
                    <h1>Here's a list of available products</h1>
                    <table>
                        <thead>
                            <td>Name</td>
                            <td>Description</td>
                            <td>Count</td>
                            <td>Price</td>
                        </thead>
                        <tbody>
                            @foreach ($allProducts as $product)
                                <tr>
                                    <td>{{ $product->name }}</td>
                                    <td class="inner-table">{{ $product->description }}</td>
                                    <td class="inner-table">{{ $product->count }}</td>
                                    <td class="inner-table">{{ $product->price }}</td>
                                </tr>
                            @endforeach
                        </tbody>
                    </table>
                </div>
            </div>
        </body>
        </html>
    
    พบ 419 Page Expired
    php artisan cache:clear
    
    #1 รู้จัก Laravel
    [xampp : php + mysql]
    การใช้ php บน Command line
    https://www.apachefriends.org/download.html
    ใน c:\xampp\php
    set %path% หรือ echo %path%
    php -h แสดงตัวเลือกทั้งหมด
    php -v แสดงรุ่น เช่น !5.6.3 หรือ 7.2.26
    C:\xampp7\mysql\bin>mysql -u root (default is no password)
    - - MariaDB [(none)]>
    [laravel]
    https://laravel.com/docs/6.x
    Server requirement PHP >= 7.2.0
    [composer]
    https://getcomposer.org/
    https://getcomposer.org/Composer-Setup.exe
    composer -V
    Composer version 1.9.1 2019-11-01 17:20:17
    dir C:\ProgramData\ComposerSetup\bin\composer.bat
    [laravel install]
    composer global require laravel/installer
    composer global about
    dir C:/Users/[xxx]/AppData/Roaming/Composer
    dir "C:/Users/[xxx]/AppData/Roaming/Composer/vendor/laravel" /s
    c:\xampp7\apache_start.bat
    c:\xampp7\mysql_start.bat
    cd c:\xampp7\htdocs
    c:\xampp7\htdocs\composer create-project --prefer-dist laravel/laravel ex1
    - - Installing laravel/laravel (v5.2.31)
    http://localhost/ex1/public
    
    #2 authentication
    https://laravel.com/docs/5.7/authentication
    [artisan make:auth]
    cd c:\xampp7\htdocs\ex1\
    c:\xampp7\htdocs\ex1>c:\xampp7\php\php.exe artisan make:auth ใช้ไม่ได้ ต้องใช้
    ------
    https://medium.com/@agavitalis/php-artisan-make-auth-command-is-not-defined-laravel-6-b51adcc6356d
    composer require laravel/ui
    php artisan ui vue --auth
    npm install && npm run dev
    localhost/ex3/public
    มี login กับ register มาให้ใช้แล้ว
    ------
    Created View: C:\xampp7\htdocs\ex1\resources/views/auth/login.blade.php
    Created View: C:\xampp7\htdocs\ex1\resources/views/auth/register.blade.php
    Created View: C:\xampp7\htdocs\ex1\resources/views/auth/passwords/email.blade.php
    Created View: C:\xampp7\htdocs\ex1\resources/views/auth/passwords/reset.blade.php
    Created View: C:\xampp7\htdocs\ex1\resources/views/auth/emails/password.blade.php
    Created View: C:\xampp7\htdocs\ex1\resources/views/layouts/app.blade.php
    Created View: C:\xampp7\htdocs\ex1\resources/views/home.blade.php
    Created View: C:\xampp7\htdocs\ex1\resources/views/welcome.blade.php
    Installed HomeController.
    Updated Routes File.
    Authentication scaffolding generated successfully!
    http://localhost/ex1/public/
    http://localhost/ex1/public/login
    http://localhost/ex1/public/register
    [artisan migrate]
    editplus.exe c:\xampp7\htdocs\ex1\.env
    DB_DATABASE=test
    DB_USERNAME=root
    DB_PASSWORD=
    c:\xampp7\htdocs\ex1>c:\xampp7\php\php.exe artisan migrate
    Migration table created successfully.
    Migrated: 2014_10_12_000000_create_users_table
    Migrated: 2014_10_12_100000_create_password_resets_table
    mysql -u root
    use test;
    show columns from users;
    Field          | Type             
    id             | int(10) unsigned 
    name           | varchar(255)     
    email          | varchar(255)     
    password       | varchar(255)     
    remember_token | varchar(100)     
    created_at     | timestamp        
    updated_at     | timestamp        
    show columns from password_resets;
    | Field      | Type               
    | email      | varchar(255)
    | token      | varchar(255)
    http://localhost/ex1/public/register
    - name = localhost
    - email = localhost@localhost.com
    - password = localhost
    select * from users;
    | id | name      | email                   | password
    |  1 | localhost | localhost@localhost.com | $2y$10...adsf
    http://localhost/ex1/public/login
    
    npm AdminLTE
    Best open source admin dashboard & control panel theme. Built on top of Bootstrap, AdminLTE provides a range of responsive, reusable, and commonly used components.
    https://github.com/ColorlibHQ/AdminLTE
    https://github.com/ColorlibHQ/AdminLTE/releases
    - Download AdminLTE-3.0.4.zip และ unzip here in htdocs
    npm -v (6.4.1)
    
    cd htdocs
    cd AdminLTE-3.0.4
    npm install admin-lte@^3.0 --save (found 0 vulnerabilities)
    npm run dev (Live demo http://localhost:3000)
    npm run production
    startapache.bat
    
    http://localhost/AdminLTE-3.0.4/
    http://localhost/AdminLTE-3.0.4/index2.html
    http://localhost/AdminLTE-3.0.4/index3.html
    ---------------------
    กรณีไม่ใช้ npm ยังมีอีกหลายทางในการติดตั้ง
    https://classic.yarnpkg.com/en/docs/install/#windows-stable
    https://classic.yarnpkg.com/latest.msi
    click and run : yarn-1.22.4.msi
    yarn --version (-v 1.22.4)
    http://www.somkiat.cc/hello-yarn/
    ทำความรู้จัก Yarn สำหรับจัดการ dependency ของ JavaScript
    Yarn คือ dependency management tool หรือ package manager สำหรับ JavaScript
    จากทีมพัฒนาของ facebook ซึ่งบอกว่าเร็ว และ ง่ายต่อการใช้งาน
    และสามารถ share code/package/module ให้คนอื่น ๆ ได้ด้วย ซึ่งมันมีความสามารถเดียวกับ NPM
    ---------------------
    หรือ yarn add admin-lte@^3.0
    หรือ composer require "ColorlibHQ/adminlte=~3.0"
    หรือ git clone https://github.com/ColorlibHQ/AdminLTE.git
    
    laravel bower admin-lte
    https://medium.com/@ezkeromar/the-simple-and-easiest-way-to-integrate-adminlte-package-in-a-laravel-project-4cfc5b00632e
    cd htdocs
    composer create-project --prefer-dist laravel/laravel ex3
    npm install -g bower
    cd ex3\public\
    bower install admin-lte
    apache-start.bat
    localhost/ex3/public (blank)
    localhost/ex3/public/bower_components/admin-lte/
    -------------------
    cd c:\xampp7\htdocs\ex3\
    php artisan --version
    # php artisan make:auth ( Command "make:auth" is not defined.)
    https://medium.com/@agavitalis/php-artisan-make-auth-command-is-not-defined-laravel-6-b51adcc6356d
    composer require laravel/ui
    php artisan ui vue --auth
    npm install && npm run dev
    localhost/ex3/public
    มี login กับ register มาให้ใช้แล้ว
    -------------------
    cd c:\xampp7\htdocs
    editplus.exe ex3\public\bower_components\admin-lte\starter.html
    
    ติดตั้ง Admin-lte ทำได้หลายวิธี
    https://adminlte.io/docs/2.4/installation
    1. ดาวน์โหลดจาก https://github.com/ColorlibHQ/AdminLTE/releases
    2. Node.js 
    	DOS> npm install admin-lte --save
    		node_modules (206MB)
    		node_modules/admin-lte (82MB)
    3. Bower
    	DOS> bower install admin-lte
    4. Composer
    	DOS> composer create-project --prefer-dist laravel/laravel ex5
    	DOS> composer require "ColorlibHQ/adminlte=~3.0"
    5. Git
    	DOS> git clone https://github.com/ColorlibHQ/AdminLTE.git
    [Folder] AdminLTE-3.0.4 (2,180 Files, 219 Folders, 81.1MB)
    	.github
    	build
    	dist
    	docs
    	pages
    	plugins
    
    AdminLTE
    การออกแบบ Webpage โดยใช้ Theme สำเร็จรูป
    ดาวน์โหลดจาก https://github.com/ColorlibHQ/AdminLTE/archive/v3.0.4.zip
    ทดสอบพรีวิวที่ https://adminlte.io/themes/AdminLTE/index2.html
    2,180 Files, 219 Folders, 81.1MB
    เมื่อ unzip here ได้ห้อง AdminLTE-3.0.4
    
    Thaiall.com