├── README.md ├── artisan.md ├── cache.md ├── commands.md ├── configuration.md ├── controllers.md ├── database.md ├── eloquent.md ├── errors.md ├── events.md ├── facades.md ├── helpers.md ├── html.md ├── installation.md ├── introduction.md ├── ioc.md ├── lifecycle.md ├── localization.md ├── mail.md ├── migrations.md ├── packages.md ├── pagination.md ├── queries.md ├── queues.md ├── quick.md ├── redis.md ├── requests.md ├── responses.md ├── routing.md ├── schema.md ├── security.md ├── session.md ├── templates.md ├── testing.md └── validation.md /README.md: -------------------------------------------------------------------------------- 1 | laravelthaidocs 2 | =============== 3 | 4 | translate document of laravel 4 to thai langauge 5 | 6 | 7 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/taqmaninw/laravelthaidocs/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 8 | 9 | -------------------------------------------------------------------------------- /artisan.md: -------------------------------------------------------------------------------- 1 | # Artisan CLI 2 | 3 | 4 | 5 | ## Introduction 6 | 7 | `Artisan` คือ ชุดคำสั่งที่ใช้เรียกงานผ่านทาง `command line `เพื่อช่วยให้จัดการงานต่างให้ง่าย รวดเร็วขึ้น ซึ่ง `laravel` นำ `Class console` ของ `symfony` มาปรับใช้ 8 | 9 | 10 | ## การใช้งาน 11 | 12 | ในการเรียกดูคำสั่งทั้งหมดใช้คำสั่ง `list` 13 | 14 | php artisan list 15 | 16 | ทุกคำสั่งจะมีวิธีการใช้ให้เราดู โดยเพิ่ม parameter `help` เข้าไปนะครับ 17 | 18 | **ตัวอย่างการใช้งาน help** 19 | 20 | php artisan help migrate 21 | 22 | เราสามารถเรียก พร้อมกับเปลี่ยนการตั้งค่าโดยรวมของเว็บโดยเพิ่มพารามิเตอร์ `--env` 23 | 24 | **ตัวอย่างนี้เราเรียกในการตั้งค่าแบบ local** 25 | 26 | php artisan migrate --env=local 27 | 28 | **จะเรียกดูรุ่นของ laravel ก็ได้โดยพารามิเตอร์** `--version` 29 | 30 | php artisan --version 31 | 32 | ## การสร้างคำสั่งขึ้นใช้งานเอง ## 33 | 34 | 35 | 36 | เราสามารถสร้างคำสั่ง `artisan` ขึ้นมาใช้ โดยไฟล์จะเก็บที่โฟลเดอร์ `app/commands` ถ้าเราไม่อยากเก็บไว้ตรงนี้ก็ไปตั้งค่าที่ไฟล์ `composer.json` ได้ 37 | 38 | 39 | ## การสร้างคำสั่ง 40 | 41 | ### เริ่มสร้างคลาส 42 | 43 | เราจะใช้คำสั่ง `command:make` ใน `command line` เพื่อสร้าง `class ` ขึ้นมาก่อนครับ 44 | 45 | **ตัวอย่างการใช้ command line สร้างคำสั่ง** 46 | 47 | php artisan command:make FooCommand 48 | 49 | ถ้าเราอยากจะเปลี่ยนที่อยู่ให้กับไฟล์คำสั่งของเรา ก็ใช้คำสั่งนี้ไปเลยครับ 50 | 51 | php artisan command:make FooCommand --path="app/classes" --namespace="Classes" 52 | 53 | ### การตั้งค่าคำสั่ง 54 | 55 | เริ่มต้นโดยการตั้ง `name` และ `description` รวมถึงส่วนประกอบอื่นของคลาส, โดยค่าเหล่านี้จะไปปรากฏตอนคำสั่ง `artisan list` 56 | ฟังก์ชัน `fire` ใช้ในการเรียกฟังก์ชันต่างๆ ที่จะทำงานในคำสั่งนี้ 57 | 58 | 59 | ### การตั้งค่าต่างๆ 60 | 61 | `getArguments` กับ `getOptions` เมทอด เป็นที่ๆ เราะทำการตั้งค่าจะต่างๆ ทั้ง พารามิเตอร์ที่ 1 ที่ 2 การตั้งค่าจะมีลักษณะการส่งค่าลงอาเรย์. 62 | 63 | เมื่อเรา คำสั่งของเรามีการให้ป้อนพารามิเตอร์ ตัวของ array ต้องมีรูปแบบดังนี้ 64 | 65 | array($name, $mode, $description, $defaultValue) 66 | 67 | ตัวแปร `mode` เรากำหนดให้เป็นแบบต้องมี `InputArgument::REQUIRED` หรือไม่มีก็ได้ `InputArgument::OPTIONAL`. 68 | 69 | เมื่อเรากำหนดให้มีการใส่คำสั่งเพิ่มเติม ลักษณะอาเรย์จะเป็นแบบนี้ 70 | 71 | array($name, $shortcut, $mode, $description, $defaultValue) 72 | 73 | ในการกำหนด `mode` ให้เป็นได้หลายๆแบบได้เช่น 74 | 75 | `InputOption::VALUE_REQUIRED`, `InputOption::VALUE_OPTIONAL`, `InputOption::VALUE_IS_ARRAY`, `InputOption::VALUE_NONE`. 76 | 77 | ตัวอย่างรูปแบบค่าที่ต้องป้อนให้เมื่อกำหนด mode เป็น `VALUE_IS_ARRAY` 78 | 79 | php artisan foo --option=bar --option=baz 80 | 81 | 82 | ### การเข้าถึงตัวแปร 83 | 84 | เมื่อคำสั่งทำงาน เราก็ต้องมีตัวจัดการในการ ดึงค่าต่างๆ ในพารามิเตอร์ของการตั้งค่า ที่รับมา 85 | 86 | **การดึงค่าจากพารามิเตอร์เฉพาะตัว** 87 | 88 | $value = $this->argument('name'); 89 | 90 | **การดึงค่าทั้งหมด** 91 | 92 | $arguments = $this->argument(); 93 | 94 | **การรับค่าจากค่าการตั้งค่าแบบเฉพาะตัว** 95 | 96 | $value = $this->option('name'); 97 | 98 | **การรับค่าจากค่าการตั้งค่าแบบทั้งหมด** 99 | 100 | $options = $this->option(); 101 | 102 | ### ส่งผลการทำงาน 103 | 104 | มีประเภทของคำสั่งที่จะแสดงออกทาง commandline 4 ประเภท คือ `info` , `comment` , `question` และ `error` ทั้ง 4 มีรูปบแบบ unicode เป็น ANSI 105 | 106 | **ส่งข้อมูลของคำสั่งออกทางหน้าจอ** 107 | 108 | $this->info('Display this on the screen'); 109 | 110 | **ส่งข้อความออกไปทางหน้าจอ** 111 | 112 | $this->error('Something went wrong!'); 113 | 114 | ### ให้ผู้ใช้งานเลือก 115 | 116 | เราสามารถใช้การถามคำถาม และ ยืนยัน เพื่อความรวดเร็วในการใช้งาน 117 | 118 | **การถามคำถาม** 119 | 120 | $name = $this->ask('What is your name?'); 121 | 122 | **การถามคำถามและค่าที่ป้อนมาเป็นรูปแบบ** 123 | 124 | $password = $this->secret('What is the password?'); 125 | 126 | **ยืนยันการเลือก** 127 | 128 | if ($this->confirm('Do you wish to continue? [yes|no]')) 129 | { 130 | // 131 | } 132 | 133 | เราสามารถกำหนดค่าเริ่มต้นของคำสั่ง `confirm` ให้เป็น`true` หรือ `false` ได้ 134 | 135 | $this->confirm($question, true); 136 | 137 | 138 | ## การลงทะเบียนคำสั่ง 139 | 140 | เมื่อการสร้างคำสั่งเสร็จสิ้น เราต้องนำไปลงทะเบียนที่ไฟล์ `app/start/artisan.php` โดยใช้คำสั่ง `Artisan::add` เพื่อลงทะเบียน 141 | 142 | **ตัวอย่างการใช้งาน** 143 | 144 | Artisan::add(new CustomCommand); 145 | 146 | ถ้าคำสั่งเราใช้ใน [IoC container](/docs/ioc) เราต้องใช้คำสั่ง `Artisan::resolve` เพื่อผูกคำสั่งของเราไปกับ IOC ด้วย 147 | 148 | **ตัวอย่างการใช้งาน** 149 | 150 | Artisan::resolve('binding.name'); 151 | 152 | 153 | ## การเรียกใช้คำสั่งอื่นร่วม 154 | 155 | บางเวลาเราต้องการจะเรียกใช้คำสั่งอื่นๆ สามารถใช้ฟังก์ชัน `call` เรียกได้ 156 | 157 | **ตัวอย่างการใช้งาน** 158 | 159 | $this->call('command.name', array('argument' => 'foo', '--option' => 'bar')); 160 | 161 | -------------------------------------------------------------------------------- /cache.md: -------------------------------------------------------------------------------- 1 | # Cache 2 | 3 | 4 | 5 | ### การตั้งค่า 6 | 7 | Laravel เตรียมรูปแบบของการ ` cache` ไว้ให้เราใช้เเล้วหลายตัวเลยนะครับ . ซึ่งรายชื่อและการตั้งค่าอยู่ที่ `app/config/cache.php`. ในไฟล์เราสามารถตั้งค่าให้กับ cache ที่เราชื่นชอบได้เลย Laravel สนับสนุนทั้ง [Memcached](http://memcached.org) กับ [Redis](http://redis.io) อยู่แล้วครับ. 8 | 9 | ก่อนจะทำการตั้งค่าใดๆ ลองไปศึกษาก่อนนะครับ ตัว laravel ใช้ `file` cache เป็นตัวเริ่มต้นนะครับ ถ้าเว็บไซต์มีขนาดใหญ่ควรเปลี่ยนไปใช้ `Memcached` หรือ `APC` จะดีกว่า 10 | 11 | 12 | 13 | ### การใช้งาน Cache 14 | 15 | ---------- 16 | 17 | **การเก็บค่าลง cache** 18 | 19 | Cache::put('key', 'value', $minutes); 20 | 21 | **เก็บลงในกรณีที่ไม่มีค่านั้นอยู่** 22 | 23 | Cache::add('key', 'value', $minutes); 24 | 25 | **ตรวจว่ามีค่าไหม** 26 | 27 | if (Cache::has('key')) 28 | { 29 | // 30 | } 31 | 32 | **ดึงค่าจากแคช** 33 | 34 | $value = Cache::get('key'); 35 | 36 | **ดึงค่าโดยเรียกค่าเริ่มต้น** 37 | 38 | $value = Cache::get('key', 'default'); 39 | 40 | $value = Cache::get('key', function() { return 'default'; }); 41 | 42 | **กำหนดให้ค่าชนิดนี้ไม่มีวันหมดอายุ** 43 | 44 | Cache::forever('key', 'value'); 45 | 46 | บางเวลาเราต้องการเรียกใช้ค่าจากแคช แต่ไม่มีค่าแล้ว เราสามารถเรียกใช้ `Cache::remember` โดยการดึงค่าจากฐานข้อมูลขึ้นมาเก็บไว้ในแคช 47 | 48 | $value = Cache::remember('users', $minutes, function() 49 | { 50 | return DB::table('users')->get(); 51 | }); 52 | 53 | และยังสามารถผสมคำสั่ง `remember` กับ `forever` 54 | 55 | $value = Cache::rememberForever('users', function() 56 | { 57 | return DB::table('users')->get(); 58 | }); 59 | 60 | เราสามารถเก็บค่าชนิดใดก็ได้เพราะรูปแบบการเก็บค่าใช้แบบ `serialize` 61 | 62 | **การลบค่าออกจากคีย์** 63 | 64 | Cache::forget('key'); 65 | 66 | 67 | ## การเพิ่มและการลดค่า 68 | 69 | แคชทุกชนิดยกเว้น `file` กับ `database` สนับสนุนการทำเพิ่มและลดค่าของแคช 70 | 71 | **การเพิ่มค่า** 72 | 73 | Cache::increment('key'); 74 | 75 | Cache::increment('key', $amount); 76 | 77 | **การลดค่า** 78 | 79 | Cache::decrement('key'); 80 | 81 | Cache::decrement('key', $amount); 82 | 83 | 84 | ## Cache Sections 85 | 86 | > **หมายเหตุ:** Cache sections ไม่สนับสนุนแคชแบบ `file` หรือ `database` 87 | 88 | Cache sections คือการให้เราสามารถจับกลุ่มให้กับแคชที่มีรูปแบบการเก็บค่าที่คล้ายๆ กันโดยใช้คำสั่ง`section` 89 | 90 | **ตัวอย่างการใช้งาน Cache section** 91 | 92 | Cache::section('people')->put('John', $john); 93 | 94 | Cache::section('people')->put('Anne', $anne); 95 | 96 | **การเข้าถึงค่าของแคช** 97 | 98 | $anne = Cache::section('people')->get('Anne'); 99 | 100 | flush คือการลบค่าออก: 101 | 102 | Cache::section('people')->flush(); 103 | 104 | 105 | ## การเก็บแคชไว้ในฐานข้อมูล 106 | 107 | เมื่อเราจะใช้ฐานข้อมูลเก็บค่าแคช เราต้องเพิ่มตารางที่จะใช้เก็บก่อน นี่คือตัวอย่างการสร้างตารางที่ใช้เก็บแคชในรูปแบบ ของ laravel 108 | 109 | Schema::create('cache', function($table) 110 | { 111 | $table->string('key')->unique(); 112 | $table->text('value'); 113 | $table->integer('expiration'); 114 | }); 115 | -------------------------------------------------------------------------------- /commands.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | เราสามารถสร้างคำสั่ง artisan ขึ้นมาใช้โดยไฟล์จะเก็บที่โฟลเดอร์ `app/commands` ถ้าเราไม่อยากเก็บไว้ตรงนี้ก็ไปตั้งค่าที่ไฟล์ `composer.json` ได้ 4 | 5 | 6 | ## การสร้างคำสั่ง 7 | 8 | ### เริ่มสร้างคลาส 9 | 10 | เราใช้คำสั่ง `command:make` ใน command line เพื่อสร้าง class ขึ้นมาก่อนครับ 11 | 12 | **ตัวอย่างการใช้ command line สร้างคำสั่ง** 13 | 14 | php artisan command:make FooCommand 15 | 16 | ถ้าเราอยากจะเปลี่ยนที่อยู่ให้กับไฟล์คำสั่งของเรา ก็ใช้คำสั่งนี้ไปเลยครับ 17 | 18 | php artisan command:make FooCommand --path="app/classes" --namespace="Classes" 19 | 20 | ### เริ่มลงรายละเอียด 21 | 22 | เริ่มต้นโดยการตั้ง `name` และ `description` รวมถึงส่วนประกอบอื่นของคลาส, โดยค่าเหล่านี้จะไปปรากฏตอนคำสั่ง `artisan list`. 23 | ฟังก์ชัน `fire` ใช้ในการเรียกฟังก์ชันต่างๆ ที่จะทำงานในคำสั่งนี้ 24 | ### การตั้งค่าต่างๆ 25 | 26 | `getArguments` กับ `getOptions` เมทอด เป็นที่ๆ เราะทำการตั้งค่าจะต่างๆ ทั้ง พารามิเตอร์ที่ 1 ที่ 2 . การตั้งค่าจะมีลักษณะการส่งค่าลงอาเรย์. 27 | 28 | เมื่อเรา คำสั่งของเรามีการให้ป้อนพารามิเตอร์ array ต้องมีรูปแบบดังนี้ 29 | 30 | array($name, $mode, $description, $defaultValue) 31 | 32 | ตัวแปร mode เรากำหนดให้เป็นแบบต้องมี `InputArgument::REQUIRED` ไม่มีก็ได้ `InputArgument::OPTIONAL`. 33 | 34 | เมื่อเรากำหนดให้มีการใส่คำสั่งเพิ่มเติมลักษณะอาเรย์จะเป็นแบบนี้ 35 | 36 | array($name, $shortcut, $mode, $description, $defaultValue) 37 | 38 | ในการกำหนด `mode` ใหเป็นได้หลายๆแบบได้เช่น: `InputOption::VALUE_REQUIRED`, `InputOption::VALUE_OPTIONAL`, `InputOption::VALUE_IS_ARRAY`, `InputOption::VALUE_NONE`. 39 | 40 | ตัวอย่างรูปแบบค่าที่ต้องป้อนให้เมื่อกำหนด mode เป็น `VALUE_IS_ARRAY` 41 | 42 | php artisan foo --option=bar --option=baz 43 | 44 | 45 | ### การเข้าถึงตัวแปร 46 | 47 | เมื่อคำสั่งทำงาน เราก็ต้องมีตัวจัดการๆ ดึงค่าต่างๆ ในพารามิเตอร์ การตั้งค่า ที่รับมา 48 | 49 | **การดึงค่าจากพารามิเตอร์เฉพาะตัว** 50 | 51 | $value = $this->argument('name'); 52 | 53 | **การดึงค่าทั้งหมด** 54 | 55 | $arguments = $this->argument(); 56 | 57 | **การรับค่าแบบเฉพาะตัว** 58 | 59 | $value = $this->option('name'); 60 | 61 | **การรับค่าแบบทั้งหมด** 62 | 63 | $options = $this->option(); 64 | 65 | ### ส่งผลการทำงาน 66 | 67 | มีประเภทของคำสั่งที่จะแสดงออกทาง commandline 4 ประเภท คือ `info` , `comment` , `question` และ `error` ทั้ง 4 มีรูปบบ unicode เป็น ANSI 68 | 69 | **ส่งข้อมูลของคำสั่งออกทางหน้าจอ** 70 | 71 | $this->info('Display this on the screen'); 72 | 73 | **ส่งเออเรอออกไปทางหน้าจอ** 74 | 75 | $this->error('Something went wrong!'); 76 | 77 | ### ให้ผู้ใช้งานเลือก 78 | 79 | เราสามารถใช้การถามคำถาม และ ยืนยัน เพื่อความรวดเร็วในการใช้งาน 80 | 81 | **การถามคำถาม** 82 | 83 | $name = $this->ask('What is your name?'); 84 | 85 | **การถามคำถามและค่าที่ป้อนมาเป็นรูปแบบ ** ** 86 | 87 | $password = $this->secret('What is the password?'); 88 | 89 | **Asking The User For Confirmation** 90 | 91 | if ($this->confirm('Do you wish to continue? [yes|no]')) 92 | { 93 | // 94 | } 95 | 96 | เราสามารถกำหนดค่าเริ่มต้นให้คำสั่ง `confirm` ให้เป็น`true` หรือ `false` ได้ 97 | 98 | $this->confirm($question, true); 99 | 100 | 101 | ## การลงทะเบียนคำสั่ง 102 | 103 | เมื่อการสร้างคำสั่งเสร็จสิ้น เราต้องนำไปลงทะเบียนที่ไฟล์ `app/start/artisan.php` โดยใช้คำสั่ง `Artisan::add` เพื่อลงทะเบียน 104 | 105 | **ตัวอย่างการใช้งาน** 106 | 107 | Artisan::add(new CustomCommand); 108 | 109 | ถ้าคำสั่งเราใช้ใน [IoC container](/docs/ioc),เราต้องใช้คำสั่ง`Artisan::resolve` เพื่อมัดคำสั่งของเราไปกับ IOC ด้วย 110 | 111 | **ตัวอย่างการใช้งาน** 112 | 113 | Artisan::resolve('binding.name'); 114 | 115 | 116 | ## การเรียกใช้คำสั่งอื่นร่วม 117 | 118 | บางเวลาเราต้องการจะเรียกใช้คำสั่งอื่นๆ สามารถใช้ฟังก์ชัน `call` เรียกได้ 119 | 120 | **ตัวอย่างการใช้งาน** 121 | 122 | $this->call('command.name', array('argument' => 'foo', '--option' => 'bar')); 123 | -------------------------------------------------------------------------------- /configuration.md: -------------------------------------------------------------------------------- 1 | # การดึงค่าของการตั้งค่าหลักมาใช้ 2 | 3 | 4 | ส่วนการตั้งค่าหลักๆ ของเว็บเราจะอยู่ที่โฟลเดอร์ `app/config` ในบทนี้เราจะมาดูว่า laravel เตรียมฟังก์ชันอะไร ให้เราใช้ในการดึงค่าจากไฟล์ทั้งหลายในโฟลเดอร์ config ออกมาใช้ได้บ้าง. 5 | 6 | laravel เตรียม class ที่ชื่อว่า `Config` ไว้ให้เราเเล้วนะครับ 7 | 8 | **ยกตัวอย่างการดึงค่า timezone ออกมา** 9 | 10 | Config::get('app.timezone'); 11 | 12 | เราสามารถกำหนดค่าของตัวแปรนั้นใหม่ได้ กรณีที่รูปแบบไม่เป็นไปตามที่เราต้องการ: 13 | 14 | $timezone = Config::get('app.timezone', 'UTC'); 15 | 16 | สังเกตุว่าถ้าเป็นการเข้าถึงค่าในอาเรย์ของไฟล์ laravel จะใช้เครื่องหมายดอท ในการเข้าถึงนะครับ 17 | 18 | **กำหนดค่าแบบไม่ต้องเข้าไปในไฟล์เลย** 19 | 20 | Config::set('database.default', 'sqlite'); 21 | 22 | การกำหนดค่าแบบนี้จะไม่ไปเขียนทับการตั้งค่าในไฟล์ app.php นะครับ จะเกิดผลเฉพาะตรงที่เราประกาศไว้เท่านั้น. 23 | 24 | 25 | ## การกำหนดชุดรูปแบบของการตั้งค่าพื้นฐาน 26 | 27 | ในการพัฒนาเว็บเรามักจะเปิด การตั้งค่าต่างๆเพื่อที่จะเอื้ออำนวยให้เราทราบข้อมูล ได้มากที่สุด 28 | แต่ในกรณีที่เว็บออนไลน์แล้วการแสดง การแสดงข้อมูลการทำงานผิดพลาด การลืมไปแล้วว่าเคยทิ้งคำสั่ง debug ไว้ตรงไหน 29 | 30 | เริ่มต้นสร้างไฟล์ชุดการตั้งค่าในโฟลเดอร์ `config` ยกตัวอย่างชื่อ `local`.ยกตัวอย่างการตั้งค่าในไฟล์ สมมุติเราต้องการใช้แคชแบบ file ก็ทำแบบตัวอย่างเลยครับ 31 | 32 | 'file', 37 | 38 | ); 39 | 40 | > **Note:** testing เป็นชื่อที่ถูกกำหนด ไว้กับ laravel แล้วว่าถ้าอยู่ในชื่อนี้การตั้งค่าทั้งหมดจะอยู่ในการโหมด unit test ฉะนั้น 41 | เราอย่าไปตั้งทับมันเลยครับ 42 | 43 | ส่วนการตั้งค่าที่เราไม่ได้ตั้งไว้ จะอ้างอิงกลับไปที่ไฟล์หลักนะครับ 44 | 45 | ต่อมาเราต้องไปตั้งค่าให้ตัว laravel รู้ว่าขณะนี้อยู่ในโหมดไหน โดยเข้าไปตั้งค่าที่ `bootstrap/start.php` ตัวโฟลเดอร์จะอยู่ข้างหน้าสุดเลย. เข้าไปค้นหา `$app->detectEnvironment` ตัวฟังชันจะใช้ค้นหารูปแบบการตั้งค่าของเว็บเรา 46 | 47 | detectEnvironment(array( 50 | 51 | 'local' => array('your-machine-name'), 52 | 53 | )); 54 | 55 | เราก็จะเปลี่ยนให้้เป็นเหมือนตัวอย่าง 56 | 57 | $env = $app->detectEnvironment(function() 58 | { 59 | return $_SERVER['MY_LARAVEL_ENV']; 60 | }); 61 | 62 | 63 | **ตัวอย่างการเรียกใช้** 64 | 65 | $environment = App::environment(); 66 | 67 | 68 | ## การปรับปรุงเว็บไซต์ 69 | 70 | เมื่อเราต้องการปิดเว็บเพื่อทำการปรับปรุง เราจะกำหนดเมทอด `App::down` ไว้ที่ `app/start/global.php` ซึ่งจะทำให้ทุกคำร้องถูกพาไปที่หน้า ที่บอกว่าตอนนี้ เว้บกำลังอยู่ในสถานะปรับปรุง. 71 | 72 | ต้องการทำให้รวดเร็วขึ้นก็ใช้ command line ก็ได้ 73 | 74 | php artisan down 75 | 76 | up เป็นคำสั่งให้เว็บกลับไปอยู่ในสถานะออนไลน์อีกครั้ง 77 | 78 | php artisan up 79 | ถ้าต้องการเปลี่ยนหน้าที่ใช้ในการแสดงผลก็เข้าไปตั้งค่าที่ 80 | `app/start/global.php` ตัวอย่าง 81 | 82 | App::down(function() 83 | { 84 | return Response::view('maintenance', array(), 503); 85 | }); 86 | -------------------------------------------------------------------------------- /controllers.md: -------------------------------------------------------------------------------- 1 | # Controllers 2 | 3 | 4 | 5 | ## การทำงานเบื้องต้น 6 | 7 | แทนที่เราจะวางฟังก์ชันไว้ที่ไฟล์ `routes.php` ควรเขียนลงไปที่ controller ดีกว่าครับ จะทำให้โค้ดมีระเบียบเรียบร้อย อ่านง่าย 8 | 9 | เราจะสร้าง Controllers ไว้ที่โฟลเดอร์ `app/controllers` โฟลเดอร์นี้จะถูกกำหนดที่อยู่ไว้ในตัวแปร `classmap` ในไฟล์ `composer.json` โดยเริ่มต้น . 10 | 11 | ตัวอย่างการเรียกใช้ controller: 12 | 13 | class UserController extends BaseController { 14 | 15 | /** 16 | * 17 | */ 18 | public function showProfile($id) 19 | { 20 | $user = User::find($id); 21 | 22 | return View::make('user.profile', array('user' => $user)); 23 | } 24 | 25 | } 26 | 27 | ทุก controller จะสืบทอดคลาส `BaseController` จะเก็บไว้ที่โฟลเดอร์ `app/controllers`โดยคลาส `BaseController` ก็สืบทอดต่อมาจาก `Controller` ต่อไปคือตัวอย่างการลงทะเบียน controller ไว้ที่ route ครับ 28 | 29 | Route::get('user/{id}', 'UserController@showProfile'); 30 | 31 | ตัวอย่างนี้เป็นการเรียกใช้งาน controller แบบใช้ namespace นะครับ 32 | 33 | Route::get('foo', 'Namespace\FooController@method'); 34 | 35 | เราสามารถตั้งชื่อย่อให้เพื่อสะดวกต่อการใช้งาน ตามตัวอย่างข้างล่างเลยครับ 36 | 37 | Route::get('foo', array('uses' => 'FooController@method','as' => 'name')); 38 | 39 | จะสร้างลิ้งไปที่ controller ก็ใช้ฟังก์ชัน `URL::action` 40 | 41 | $url = URL::action('FooController@method'); 42 | 43 | ใช้ฟังก์ชัน `currentRouteAction` เพื่อเรียกคำร้องขอที่ผ่านมา 44 | 45 | $action = Route::currentRouteAction(); 46 | 47 | 48 | ## Controller Filters 49 | 50 | คือการกรองค่า ที่ส่งเข้ามายังตัวเว็บซึ่ง laravel ก็มีรูปแแบบการทำ filter ไว้ให้อยู่แล้วเหมือนในตัวอย่างคือ เมื่อเว็บเริ่มทำงาน ก็ตรวจว่าได้ลงชื่อเข้าใช้งานไหม แล้วค่าที่ส่งมาปลอดภัยไหม ส่งเครื่องหมายแปลกประหลาดมาไหม โดยทำการตรวจด้วย filter ชื่อ csrf แล้วถ้ามีการเรียก fooAction กับ barAction ก็ทำการเก็บ log ไว้ด้วย 51 | 52 | class UserController extends BaseController { 53 | 54 | /** 55 | * ฟังก์ชัน _construct จะถูกเรียกก่อนเมื่อมีการเรียกใช้คลาสนี้ 56 | */ 57 | public function __construct() 58 | { 59 | $this->beforeFilter('auth'); 60 | 61 | $this->beforeFilter('csrf', array('on' => 'post')); 62 | 63 | $this->afterFilter('log', array('only' => 64 | array('fooAction', 'barAction'))); 65 | } 66 | 67 | } 68 | 69 | เราสามารถจับกลุ่มให้ตัวกรองได้ เหมือนในตัวอย่างนะครับ 70 | 71 | class UserController extends BaseController { 72 | 73 | /** 74 | * Instantiate a new UserController instance. 75 | */ 76 | public function __construct() 77 | { 78 | $this->beforeFilter(function() 79 | { 80 | //จะกรองค่าไหนบ้างก็ใส่ตรงนี้เลย 81 | }); 82 | } 83 | 84 | } 85 | 86 | 87 | ## RESTful Controllers 88 | 89 | restful controller ของ laravel คือการกำหนดว่าเมื่อมีการส่งคำขอแบบนี้ไปที่ฟังก์ชันนี้ให้ตอบสนองแบบไหนนะครับ เป็นการกรองตามชนิดของคำร้อง ทั้ง `get,post,put,delete` การกรองระดับชนิดของคำร้องขอ ทำให้เราจัดการได้ง่ายขึ้น 90 | 91 | **การกำหนดค่า restful controller ใน route** 92 | 93 | Route::controller('users', 'UserController'); 94 | 95 | เมื่อเรากำหนด ดังตัวอย่างด้านบนแล้ว คลาส UserController ก็จะรับแค่ค่าที่เรากำหนด 96 | โดยเราจะใส่ชนิดของคำร้องขอที่เราจะรับไว้ที่หน้าตัวฟังก์ชัน 97 | 98 | class UserController extends BaseController { 99 | 100 | public function getIndex() 101 | { 102 | // ฟังก์ชันนี้จะรับคำร้องขอที่เป็นชนิด get เท่านั้น 103 | } 104 | 105 | public function postProfile() 106 | { 107 | // ฟังก์ชันนี้จะรับคำร้องขอที่เป็นชนิด post เท่านั้น 108 | } 109 | 110 | } 111 | 112 | ในกรณีที่ชื่อฟังชันเรามีหลายคำใช้เครื่องหมาย - เพื่อเรียกได้ดังตัวอย่างเราเรียกใช้ฟังก์ชัน adminprofile ซึงมีสองคำ 113 | `users/admin-profile` 114 | 115 | public function getAdminProfile() {} 116 | 117 | 118 | ## Resource Controllers 119 | 120 | Resource controllers คือการลงทะเบียน restful controller ของเรากับ Route มีคำสั่งใน command line ที่ช่วยให้เราสร้าง restful controller ได้รวดร็วขึ้น. ตัวอย่าง เราอยากจะสร้าง controller เพื่อจัดการภาพเราก็ใช้คำสั่ง `controller:make` ตามตัวอย่าง 121 | 122 | php artisan controller:make PhotoController 123 | 124 | แล้วก็ลงทะเบียนบอก route ว่า controller นี้เป็น restful 125 | 126 | Route::resource('photo', 'PhotoController'); 127 | 128 | การใช้คำสั่งอัติโนมัติสร้างจะทำให้เราได้ restful controller แบบเต็มรูปแบบ ยังเป็นการสร้างตัวอย่างการใช้งาน restful ให้ด้วย 129 | 130 | **รูปแบบของ restful controller ที่คำสั่ง artisan จะสร้างให้** 131 | 132 | Verb | Path | Action | Route Name 133 | ----------|-----------------------|----------|------------- 134 | GET | /resource | index | resource.index 135 | GET | /resource/create | create | resource.create 136 | POST | /resource | store | resource.store 137 | GET | /resource/{id} | show | resource.show 138 | GET | /resource/{id}/edit | edit | resource.edit 139 | PUT/PATCH | /resource/{id} | update | resource.update 140 | DELETE | /resource/{id} | destroy | resource.destroy 141 | 142 | ถ้าเราไม่ต้องการสร้างทั้งหมดตามในตารางก็กำหนดเป็นรายตัวไปเลยครับ ดังตัวอย่าง 143 | 144 | php artisan controller:make PhotoController --only=index,show 145 | 146 | php artisan controller:make PhotoController --except=index 147 | 148 | แล้วก็กำหนดค่าใน route ให้ใช้งานได้เฉพาะฟังก์ชันก็ได้ 149 | 150 | Route::resource('photo', 'PhotoController', 151 | array('only' => array('index', 'show'))); 152 | 153 | 154 | 155 | ## การแสดงผลเมื่อมีคำร้องที่ไม่ถูกต้อง 156 | 157 | เราจะใช้ฟังก์ชัน `missingMethod`เพื่อจัดการคำร้องขอที่ไม่ตรงตามที่เรากำหนดไว้ จะส่งไปไหนจะแสดงอะไรก็กำหนดได้เลยครับ: 158 | 159 | **ตัวอย่าง** 160 | 161 | public function missingMethod($parameters) 162 | { 163 | // 164 | } -------------------------------------------------------------------------------- /database.md: -------------------------------------------------------------------------------- 1 | # การจัดการฐานข้อมูลเบื้องต้น 2 | 3 | 4 | 5 | ## การตั้งค่า 6 | 7 | เราจะไปตั้งค่าที่ `app/config/database.php`. ซึ่งเราจะไปตั้งค่าการเชื่อมต่อข้างในนี้ครับ 8 | 9 | laravel ในขณะนี้สนับสนุน: MySQL, Postgres, SQLite, and SQL Server. 10 | 11 | 12 | ## การทำ Queries 13 | 14 | เราใช้คลาส `DB` ในการเรียกใช้การคิวรี่นะครับ 15 | 16 | **ตัวอย่างการคิวรี่** 17 | 18 | $results = DB::select('select * from users where id = ?', array(1)); 19 | 20 | ฟังก์ชัน`select`จะส่งค่าเป็น `array`กลับมาเสมอ 21 | 22 | **ตัวอย่างการเพิ่มข้อมูล** 23 | 24 | DB::insert('insert into users (id, name) values (?, ?)', array(1, 'Dayle')); 25 | 26 | **ตัวอย่างการแก้ไขข้อมูล** 27 | 28 | DB::update('update users set votes = 100 where name = ?', array('John')); 29 | 30 | **ตัวอย่างการลบข้อมูล** 31 | 32 | DB::delete('delete from users'); 33 | 34 | > **หมายเหตุ:** คำสั่ง `update` กับ `delete` จะคืนค่าเป็นจำนวนของแถวที่ได้ทำการจัดการไป. 35 | 36 | **ตัวอย่างการใช้คำสั่งทั่วไป** 37 | 38 | DB::statement('drop table users'); 39 | 40 | เราสามารถกำหนดให้ฟังก์ชันนี้ทำงานเมื่อมีการคิวรี่เกิดขึ้นโดยใช้ฟังก์ชัน `DB::listen` 41 | 42 | **ตัวอย่างการใช้งาน** 43 | 44 | DB::listen(function($sql, $bindings, $time) 45 | { 46 | // 47 | }); 48 | 49 | 50 | ## Database Transactions 51 | 52 | เมื่อเราจะทำการคิวรี้หลายๆ คำสั่งเราจะใช้ฟังก์ชัน `transaction` ในการควบคุม เหมือนในตัวอย่างข้างล่าง 53 | 54 | DB::transaction(function() 55 | { 56 | DB::table('users')->update(array('votes' => 1)); 57 | 58 | DB::table('posts')->delete(); 59 | }); 60 | 61 | 62 | ## การเข้าถึงการเชื่อมต่อฐานข้อมูล 63 | 64 | สมมุติเว็บของเราใช้ฐานข้อมูลหลายชนิด สามารถใช้ฟังก์ชัน `DB::connection` ในการเรียกฐานข้อมูล เฉพาะที่เราต้องการดังตัวอย่าง 65 | 66 | $users = DB::connection('foo')->select(...); 67 | 68 | แล้วก็สามารถเชื่อมต่อใหม่ด้วยคำสั่ง reconnect 69 | 70 | DB::reconnect('foo'); 71 | 72 | 73 | ## การเก็บประวัติการคิวรี่ 74 | 75 | โดยค่าเริ่มต้น laravel จะเก็บประวัติไว้ในหน่วยความจำอยู่เเล้ว ในกรณีที่เว็บของเรามีคำร้องขอจำนวนมาก การเก็บประวัติจะใช้หน่วยความจำมาก เราจะใช้ฟังก์ชัน `disableQueryLog` เพื่อทำการหยุดเก็บประวัติ ตัวอย่าง 76 | 77 | DB::connection()->disableQueryLog(); -------------------------------------------------------------------------------- /eloquent.md: -------------------------------------------------------------------------------- 1 | # Eloquent ORM 2 | 3 | 4 | 5 | 6 | ## ทำความรู้จักก่อน 7 | 8 | Eloquent ORM คือการที่เราจำลองตารางเป็นคลาสแล้ว เรียกใช้งานเป็นชื่อของตาราง นั้นเลยทำให้เข้าใจการพัฒนารวดเร็วขึ้น เข้าใจง่ายขึ้น ที่เรียกว่า Eloquent เพราะตัวมันมีความเรียบง่าย 9 | 10 | 11 | ## การใช้งานเบื้องต้น 12 | 13 | เริ่มต้นด้วยการสร้าง moedel ไว้ที่โฟลเดอร์ `app/models` 14 | 15 | **ตัวอย่างการสร้าง model** 16 | 17 | class User extends Eloquent {} 18 | 19 | ถ้าคลาสนี้จะไม่ใช้ตารางตามชื่อ model เราก็สามารถใช้ตัวแปร `table` ในการกำหนดชื่อตารางที่เราจะใช้ เหมือนในตัวอย่าง 20 | 21 | class User extends Eloquent { 22 | 23 | protected $table = 'my_users'; 24 | 25 | } 26 | 27 | > **หมายเหตุ:** Eloquent จะถือว่าคอลัมน์ `id` เป็นคีย์หลักเสมอ เราสามารถใช้ตัวแปร `primaryKey` เพื่อกำหนดคีย์หลักได้เอง และเช่นเดียวกัน เราสามารถใช้ตัวแปร `connection`เพื่อกำหนดฐานข้อมูลที่เราจะใช้ใน model นี้ 28 | 29 | ถ้าในตารางของเรามีคอลัมน์ที่ชื่อ `updated_at` กับ `created_at` จะถูกใช้ในการเก็บเวลาที่ข้อมูลในแถวนี้ถูกเพิ่มหรือแก้ไข. ถ้าเราไม่ต้องการเพียงแค่ตั้งค่าตัวแปร `$timestamps` ให้เป็น `false` 30 | 31 | **การคิวรี่โดยใช้ eoloquent** 32 | 33 | ค้นหาข้อมูลทั้งหมดจากตาราง user 34 | 35 | $users = User::all(); // 36 | 37 | **ค้นหาตามเงื่อนไข** 38 | 39 | ค้นหาโดยค่า id เท่ากับ 1 40 | 41 | $user = User::find(1); // 42 | 43 | แสดงค่าในคอลัมน์ออกมา 44 | 45 | var_dump($user->name); // 46 | 47 | > **Note:** ทุกคำสั่งที่ใช้ใน [query builder](/docs/queries) สามารถใช้กับ eloquent ได้เช่นกัน 48 | 49 | **การคิวรี่แล้วส่งต่อ** 50 | 51 | บางเวลาเมื่อค้นหาเเล้วไม่เจอเราต้องการให้เกิดหน้าแสดงข้อผิดพลาดขึ้นมา สามารถใช้ฟังก์ชัน `findOrFail` เหมือนในตัวอย่างเลยครับ ถ้าค้นไม่เจอเราจะส่งไปหน้า 404 ทันที 52 | 53 | $model = User::findOrFail(1); 54 | 55 | $model = User::where('votes', '>', 100)->firstOrFail(); 56 | 57 | อยากจะสร้างการแสดงข้อผิดพลาดโดยที่เรากำหนดเองก็สามารถทำตามตัวอย่างเลยครับ สมมุติเราจะสร้างฟังก์ชัน `ModelNotFoundException`เราก็เรียกตัวคลาสหลักเข้ามาก่อน 58 | 59 | use Illuminate\Database\Eloquent\ModelNotFoundException; 60 | 61 | App::error(function(ModelNotFoundException $e) 62 | { 63 | return Response::make('Not Found', 404); 64 | }); 65 | 66 | **ตัวอย่างการคิวรี่แบบหลายเงื่อนไข** 67 | 68 | $users = User::where('votes', '>', 100)->take(10)->get(); 69 | 70 | foreach ($users as $user) 71 | { 72 | var_dump($user->name); 73 | } 74 | 75 | 76 | **Eloquent Aggregates** 77 | 78 | $count = User::where('votes', '>', 100)->count(); 79 | 80 | ถ้าเราอยากเขียนคำสั่งคิวรี่ ขึ้นมาใช้เองก็ต้องใช้ฟังก์ชัน `whereRaw` 81 | 82 | $users = User::whereRaw('age > ? and votes = 100', array(25))->get(); 83 | 84 | 85 | ## การส่งค่าอาเรย์ลงฐานข้อมูล 86 | 87 | เราสามารถส่ง ค่าจำนวนมากอย่างเช่น อาเรย์ ลงฐานข้อมูลได้ง่ายๆ แต่ต้องใช้ตัวแปร
88 | `fillable` เพื่อกำหนดว่าคอลัมน์ไหนที่สามารถใส่อาเรย์ได้
89 | `guarded` เพื่อกำหนดว่าคอลัมน์ไหนใส่อาเรย์ลงไปไม่ได้ 90 | 91 | **ตัวอย่างการกำหนดค่า fillable** 92 | 93 | class User extends Eloquent { 94 | 95 | protected $fillable = array('first_name', 'last_name', 'email'); 96 | 97 | } 98 | 99 | 100 | **ตัวอย่างการตั้งค่าตัวแปร guard** 101 | 102 | class User extends Eloquent { 103 | 104 | protected $guarded = array('id', 'password'); 105 | 106 | } 107 | 108 | ต้วอย่างคอลัมน์ `id` and `password` เราจะไม่อนุญาติให้ทำการใส่ค่าที่มาในรูปแบบอาเรย์ลงไป 109 | 110 | **การป้องกันไม่ให้ทำการเพิ่มข้อมูลเป็นอาเรย์** 111 | 112 | protected $guarded = array('*'); 113 | 114 | 115 | ## เพิ่ม, ลบ, แก้ไข 116 | 117 | 118 | **ตัวอย่างการแก้ไขข้อมูลแบบไม่ใช้ namespace** 119 | 120 | $user = new User; 121 | 122 | $user->name = 'John'; 123 | 124 | $user->save(); 125 | 126 | > **หมายเหตุ:** โดยเริ่มต้น laravel จะทำการเพิ่มค่าคีย์หลักให้อัตโนมัติ ถ้าเราไม่ต้องการก็ตั้งค่าตัวแปร `incrementing`ใน model ให้เป็น `false`. 127 | 128 | เราสามารถใช้คำสั่ง create เพื่อสร้างข้อมูลใหม่ได้ แต่ก่อนหน้านั้นต้องกำหนดตัวแปร `fillable` หรือ `guarded` ไม่งั้นเพิ่มไม่ได้ติด error 129 | 130 | 131 | **การสร้างข้อมูลใหม่** 132 | 133 | $user = User::create(array('name' => 'John')); 134 | 135 | 136 | **ตัวอย่างการแก้ไขข้อมูล** 137 | 138 | $user = User::find(1); 139 | 140 | $user->email = 'john@foo.com'; 141 | 142 | $user->save(); 143 | 144 | บางเวลาเราต้องบันทึกค่าในตารางที่อ้างอิงกัน เราจะใช้คำสั่ง `push` 145 | 146 | **บันทึกค่าพร้อมกับบันทึกลงตารางที่มีการเชื่อมกันอยู่** 147 | 148 | $user->push(); 149 | 150 | 151 | **ตัวอย่างการลบข้อมูล** 152 | 153 | $user = User::find(1); 154 | 155 | $user->delete(); 156 | 157 | **ลบโดยกำหนด id เป็นเงื่อนไข** 158 | 159 | User::destroy(1); 160 | 161 | User::destroy(1, 2, 3); 162 | 163 | ตัวอย่างการลบแบบมีเงื่อนไข: 164 | 165 | $affectedRows = User::where('votes', '>', 100)->delete(); 166 | 167 | ถ้าเราต้องการแก้ไขเฉพาะคอลัมน์ที่ใช้บันทึกเวลา เราจะใช้คำสั่ง `touch` 168 | 169 | **ตัวอย่างการใช้งาน** 170 | 171 | $user->touch(); 172 | 173 | 174 | ## การกำหนดว่าข้อมูลนี้ถูกลบเเล้ว 175 | เราสร้างตัวแปร `$softdelete` เพื่อบอก model ว่าไม่ต้องลบจริง เหมือนกับเราเอาไปเก็บไว้ในถังขยะก่อน ยังไม่ได้เอาไปเผาทิ้งจริงๆ 176 | 177 | class User extends Eloquent { 178 | 179 | protected $softDelete = true; 180 | 181 | } 182 | แล้วก็เพิ่มคอลัมน์ `deleted_at` ลงในตาราง เพื่อกำหนดว่าข้อมูลแถวนี้ถูกลบแล้วหรือยัง 183 | 184 | เมื่อเราเรียกคำสั่ง `delete` กับ model นี้คอลัมน์ `deleted_at` จะถูกเพิ่มค่าให้เป็นวันเวลาที่เราลบ เมื่อเราค้นหาข้อมูลโดยใช้ model นี้ข้อมูลแถวที่เราทำการ 185 | ลบจะไม่ถูกดึงขึ้นมา 186 | 187 | **ตัวอย่างการค้นหา โดยรวมแถวที่ถูกตั้งค่าว่าลบแล้ว** 188 | 189 | $users = User::withTrashed()->where('account_id', 1)->get(); 190 | 191 | **ตัวอย่างการค้นหา โดยค้นหาเฉพาะแถวที่ถูกตั้งค่าว่าลบแล้ว** 192 | 193 | $users = User::onlyTrashed()->where('account_id', 1)->get(); 194 | 195 | ถ้าต้องการยกเลิกการลบ ใช้คำสั่ง `restore` ได้เลยครับ 196 | 197 | $user->restore(); 198 | 199 | หรือจะเรียกคืนเฉพาะแถวก็ตามตัวอย่างนี้เลย 200 | 201 | User::withTrashed()->where('account_id', 1)->restore(); 202 | 203 | ฟังก์ชัน `restore` สามารถใช้กับความสัมพันธ์ได้ด้วย 204 | 205 | $user->posts()->restore(); 206 | 207 | ถ้าต้องการลบข้อมูลจริงๆ ก็ใช้คำสั่ง `forceDelete` 208 | 209 | $user->forceDelete(); 210 | 211 | คำสัง `forceDelete` ก็สามารถใช้กับความสัมพันธ์ก็ได้ 212 | 213 | $user->posts()->forceDelete(); 214 | 215 | ฟังก์ชัน `trashed` ใช้ในการตรวจว่าโมเดลนี้มีการตั้งค่า softdelete ไว้ไหม 216 | 217 | if ($user->trashed()) 218 | { 219 | // 220 | } 221 | 222 | 223 | ## Timestamps การบันทึกเวลา 224 | 225 | โดยค่าเริ่มต้น laravel ใช้คอลัมน์ `created_at` และ `updated_at` ในตารางของเราโดยอัตโนมัติ. 226 | 227 | **ตัวอย่างการยกเลิกการเก็บเวลาในการจัดการข้อมูล** 228 | 229 | class User extends Eloquent { 230 | 231 | protected $table = 'users'; 232 | 233 | public $timestamps = false; 234 | 235 | } 236 | 237 | ฟังก์ชัน `freshTimestamp`ใช้ในการกำหนดรูปแบบวันเวลาที่เราจะเก็บ 238 | 239 | **ตัวอย่างการใช้งาน** 240 | 241 | class User extends Eloquent { 242 | 243 | public function freshTimestamp() 244 | { 245 | return time(); 246 | } 247 | 248 | } 249 | 250 | 251 | ## Query Scopes 252 | 253 | เราใช้คำนำหน้าฟังก์ชันว่า `scope` เพื่อทำการสร้างฟังก์ชันที่ใช้คิวรี่แบบเฉพาะของเราเอง: 254 | 255 | **ตัวอย่างการใช้งาน scope** 256 | 257 | class User extends Eloquent { 258 | 259 | public function scopePopular($query) 260 | { 261 | return $query->where('votes', '>', 100); 262 | } 263 | 264 | } 265 | 266 | **การใช้งานคิวรี่ที่มาจาการใช้คำสั่ง scope** 267 | 268 | $users = User::popular()->orderBy('created_at')->get(); 269 | 270 | 271 | ## ความสัมพันธ์ 272 | 273 | การจัดการความสัมพันธ์ตารางใน laravel มี 4 รูปแบบ 274 | 275 | - 1 ต่อ 1 276 | - 1 ต่อ กลุ่ม 277 | - กลุ่ม ต่อ กลุ่ม 278 | - ความสัมพันธ์แบบซับซ้อน 279 | 280 | 281 | ### 1 ต่อ 1 282 | 283 | ตัวอย่างความสัมพันธ์แบบ 1 ต่อ 1 ผู้ใช้งานมีโทรศัพท์ได้เเค่เครื่องเดียว 284 | 285 | **ตัวอย่างความสัมพันธ์แบบ 1 ต่อ 1** 286 | 287 | class User extends Eloquent { 288 | 289 | public function phone() 290 | { 291 | return $this->hasOne('Phone'); 292 | } 293 | 294 | } 295 | 296 | เราใช้ฟังก์ชันเป็นตัวกำหนดตารางที่เราจะเชื่อมด้วย ตัวอย่างข้างล่างการค้นหาโทรศัพท์ของผู้ใช้งานที่มี id เท่ากับ 1 297 | 298 | $phone = User::find(1)->phone; 299 | 300 | ถ้าเขียนเป็น php ธรรมดาก็จะได้เเบบนี้ครับ 301 | 302 | select * from users where id = 1 303 | 304 | select * from phones where user_id = 1 305 | 306 | โดยค่าเริ่มต้นเเล้ว Eloquent จะใช้คอลัมน์ `user_id` ในตาราง `Phone` เป็น คีย์เชื่อม ถ้าเราไม่เอา จะเอาชื่อที่เราตั้งเองก็ใช้ตัวแปร `hasOne` เป็นตัวแก้ดังตัวอย่าง 307 | 308 | return $this->hasOne('Phone', 'custom_key'); 309 | 310 | ในการเชื่อมโมเดลสิ่งที่สำคัญคือการตั้งค่าความสัมพันธ์ให้ตรงกันใน `Phone` model เราก็จะใช้ฟังก์ชัน `belongsTo` ในการเชื่อมกลับไปยัง `User` 311 | 312 | **ตัวอย่างการเชื่อมกลับไปยัง User Model** 313 | 314 | class Phone extends Eloquent { 315 | 316 | public function user() 317 | { 318 | return $this->belongsTo('User'); 319 | } 320 | 321 | } 322 | 323 | เหมือนกับข้างบนครับ เราไม่เอา `user_id` เป็นคีย์เชื่อมก็ต้องกำหนดด้วย ตามตัวอย่าง 324 | 325 | class Phone extends Eloquent { 326 | 327 | public function user() 328 | { 329 | return $this->belongsTo('User', 'custom_key'); 330 | } 331 | 332 | } 333 | 334 | 335 | ### 1 ต่อ กลุ่ม 336 | 337 | ความสัมพันธ์แบบ 1 ต่อ กลุ่ม มีตัวอย่างคือ 1 โพสมีได้หลาย ความคิดเห็น 338 | ตัวอย่างการใช้ hasMany 339 | 340 | class Post extends Eloquent { 341 | 342 | public function comments() 343 | { 344 | return $this->hasMany('Comment'); 345 | } 346 | 347 | } 348 | 349 | ตัวอย่างการค้นหาตารางที่เชื่อมกันอยู่ 350 | 351 | $comments = Post::find(1)->comments; 352 | 353 | ตัวอย่างการค้นหาแบบหลายเงื่อนไขครับ ดังตัวอย่าง เราจะค้นหาความคิดเห็นที่มี title ชื่อ foo โดยเอาค่าเเรกที่เจอก่อน 354 | 355 | $comments = Post::find(1)->comments()->where('title', '=', 'foo')->first(); 356 | 357 | อีกครั้ง อย่าลืมเชื่อมกลับไปยังตารางที่เชื่อมมานะครับ 358 | 359 | **ตัวอย่างอีกครั้ง** 360 | 361 | class Comment extends Eloquent { 362 | 363 | public function post() 364 | { 365 | return $this->belongsTo('Post'); 366 | } 367 | 368 | } 369 | 370 | 371 | ### กลุ่ม ต่อ กลุ่ม 372 | 373 | กลุ่มต่อกลุ่ม จะเป็นความสัมพันธ์ที่ยุ่งยากพอสมควรเลยครับ เรามีตัวอย่างคือ ผู้ใช้งานมีสิทธิการใช้งานได้หลายสิทธิ์ ทั้งเรียกดู,ลบ,แก้ไข,เพิ่ม แล้วแต่ละสิทธิ์ก็ถูกใช้ได้ในหลายผู้ใช้งาน เราต้องมี 3 ตาราง `users`, `roles`, กับ `role_user`. ตาราง `role_user`จะเก็บ `user_id` กับ `role_id` เพื่อบอกว่า ผู้ใช้งานคนนี้มีสิทธิทำอะไรได้บ้าง 374 | 375 | laravel ใช้ฟังก์ชัน `belongsToMany` ในการเชื่อมความสัมพันธ์: 376 | 377 | class User extends Eloquent { 378 | 379 | public function roles() 380 | { 381 | return $this->belongsToMany('Role'); 382 | } 383 | 384 | } 385 | 386 | ตอนนี้เราสามารถตรวจได้เเล้วว่าผู้ใช้งานหมายเลข 1 มีสิทธิทำอะไรได้บ้าง 387 | 388 | $roles = User::find(1)->roles; 389 | 390 | ถ้าเราต้องการใช้ชื่อตาราง ตามใจเราก็สามารถทำได้โดยการ ส่งพารามิเตอร์ไป ดังตัวอย่างครับ 391 | 392 | return $this->belongsToMany('Role', 'userroles'); 393 | 394 | หรือจะเปลี่ยนไปจนถึงชื่อคอลัมน์เลยก็ได้ แต่ต้องส่งชื่อ คอลัมน์ที่เราตั้งเองไปบอก model ด้วย 395 | 396 | return $this->belongsToMany('Role', 'userroles', 'user_id', 'foo_id'); 397 | 398 | อย่าลืมเชื่อมความสัมพันธ์กลับมาด้วยนะครับ 399 | 400 | class Role extends Eloquent { 401 | 402 | public function users() 403 | { 404 | return $this->belongsToMany('User'); 405 | } 406 | 407 | } 408 | 409 | 410 | ### ความสัมพันธ์ที่ยุ่งยากมากขึ้น 411 | เพื่อช่วยให้เข้าใจได้ง่ายขึ้นจะมีตัวอย่างมาให้ดูกันครับ 412 | **ตัวอย่างโครงสร้างตาราง** 413 | 414 | staff 415 | id - integer 416 | name - string 417 | 418 | orders 419 | id - integer 420 | price - integer 421 | 422 | photos 423 | id - integer 424 | path - string 425 | imageable_id - integer 426 | imageable_type - string 427 | 428 | มันพิเศษตรงที่คอลัมน์ `imageable_id` กับ `imageable_type` ของตาราง `photos` ที่เราจะใช้เก็บคีย์ที่ใช้เชื่อมตาราง photo เข้ากับตาราง staff หรือ order ใช้เก็บคีย์เชื่อมร่วมกันได้ โดยใช้คอลัมน์ เมื่อเรากำหนดคีย์เชื่อมและชื่อของตารางที่เชื่อมไป ORM จะทำการตรวจสอบโดยใช้คอลัมน์ที่ `imageable_type` ในการหาว่าคีย์นี้เป็นของตารางไหน โดยเราต้องตั้งชื่อฟังก์ชันว่า `imageable` เราต้องประกาศ model แบบนี้ครับ 429 | 430 | class Photo extends Eloquent { 431 | 432 | public function imageable() 433 | { 434 | return $this->morphTo(); 435 | } 436 | 437 | } 438 | 439 | class Staff extends Eloquent { 440 | 441 | public function photos() 442 | { 443 | return $this->morphMany('Photo', 'imageable'); 444 | } 445 | 446 | } 447 | 448 | class Order extends Eloquent { 449 | 450 | public function photos() 451 | { 452 | return $this->morphMany('Photo', 'imageable'); 453 | } 454 | 455 | } 456 | 457 | ตอนนี้เราสามารถใช้ id ของ staff หรือ order มาค้นหารูปภาพได้ 458 | 459 | **ตัวอย่าง** 460 | 461 | $staff = Staff::find(1); 462 | 463 | foreach ($staff->photos as $photo) 464 | { 465 | // 466 | } 467 | 468 | ความพิเศษจริง ๆอยู่ที่เมื่อเราใช้ `Photo` model ในการค้นครับ 469 | 470 | **ตัวอย่าง** 471 | 472 | $photo = Photo::find(1); 473 | 474 | $imageable = $photo->imageable; 475 | 476 | ความสัมพันธ์ที่ชื่อ `imageable` บน model `Photo` จะส่งข้อมูลของทั้ง `Staff` และ `Order` หรือตารางใดตารางหนึ่ง ขึ้นอยู่กับค่าที่เราใช้ค้นหาจะไปตรงกับ model ไหน 477 | 478 | 479 | 480 | 481 | ## การคิวรี่โดยใช้ความสัมพันธ์เป็นเงื่อนไข 482 | 483 | เราสามารถจำกัดผลการค้นหาด้วยฟังก์ชัน `has` 484 | 485 | **ค้นหาโดยจำกัดเฉพาะความสัมพันธ์** 486 | 487 | $posts = Post::has('comments')->get(); // เลือกข้อมูลของตาราง post โดยเอาเฉพาะที่มี comment 488 | 489 | You may also specify an operator and a count: 490 | 491 | $posts = Post::has('comments', '>=', 3)->get(); // เลือก post ที่มี comment มากกว่าหรือเท่ากับ 3 492 | 493 | 494 | ### การค้นหาแบบยืดหยุ่น 495 | 496 | Eloquent ทำให้เราสามารถค้นหาแบบต่อเนื่องโดย พยายามให้เราจำกัดขอบเขตการค้นหาให้ได้ลึกลงที่สุดเพื่อให้ได้เฉพาะข้อมูลที่ต้องการจริงๆ และพลิกแพลงรูปแบบของฟังก์ชันได้มากมาย ดังตัวอย่าง 497 | 498 | class Phone extends Eloquent { 499 | 500 | public function user() 501 | { 502 | return $this->belongsTo('User'); 503 | } 504 | 505 | } 506 | 507 | $phone = Phone::find(1); 508 | 509 | แทนที่เราจะทำแบบข้างบน ซึ่งจะทำให้เราได้ค่าที่ไม่ต้องการออกมามาก เราก็เปลี่ยนมาใช้แบบข้างล่าง เราสามารถเข้าถึง อีเมล์ ของผู้ใช้งาน คนแรกได้เลย 510 | 511 | echo $phone->user()->first()->email; 512 | 513 | หรือจะให้สั้นได้อีก ก็ทำตามนี้เลยครับ 514 | 515 | echo $phone->user->email; 516 | 517 | 518 | ## Eager Loading 519 | 520 | Eager loading มีเพื่อแก้ปัญหาการคิวรี่แบบ N + 1 ตัวอย่างคือ, ผู้เเต่งหนึ่งคนสามารถแต่งหนังสือได้หลายๆ เล่ม ความสัมพันธ์จะออกมาแบบนี้ 521 | 522 | class Book extends Eloquent { 523 | 524 | public function author() 525 | { 526 | return $this->belongsTo('Author'); 527 | } 528 | 529 | } 530 | 531 | แล้วการคิวรี้ที่มีปัญหาก็ประมาณนี้ 532 | 533 | foreach (Book::all() as $book) 534 | { 535 | echo $book->author->name; 536 | } 537 | 538 | 1 คิวรี้ จะทำการดึงค่าหนังสือทั้งหมดจากตาราง, แล้วการคิวรี่ครั้งต่อไปก็จะทำเหมือนกัน. ถ้ามีหนังสือ 25 เล่ม,จะมีการคิวรี่ถึง 26 ครั้ง คือเราใช้ข้อมูลทั้งหมดของตารางหนังสือไปค้นหาผูแต่ง 1 ผู้แต่งก็จะไปดึงหนังสือทั้งหมดของเขาออกมา 539 | 540 | select * from books 541 | 542 | select * from authors where id = ? 543 | 544 | นึกถึงเรามีข้อมูลเริ่มต้น 1000 แถว ปัญหานี้ส่วนใหญ่จะเกิดขึ้นกับความสัมพันธ์แบบ hasMany เพราะเราต้องนำทั้งหมดไปค้นหาต่อแล้วแต่ละแถวจะได้ผลลัพท์ออกมาหลายๆ แถวจำนวนผลการค้นหาที่มหาศาลจะทำให้การคิวรี่ช้ามากแต่ ซึงถ้าข้อมูลตั้งต้นยังมากกว่านี้ลงไปแต่งคิวรี่เองโดยใช้ Fluent Query Builder แต่ถ้ายังจะใช้ Eloquent ก็ยัง 545 | โชคดีที่ laravel มีฟังก์ชัน `with` ใช้ในการทำให้เร็วขึ้น 546 | 547 | foreach (Book::with('author')->get() as $book) 548 | { 549 | echo $book->author->name; 550 | } 551 | 552 | sql ที่เกิดขึ้นจะมีหน้าตาแบบนี้ครับ เริ่มจากค้นหาหนังสือทั้หมดก่อนแล้ว ค่อยเอา id ที่ได้ไปค้นต่อในตาราง authors เราเปลี่ยนไปใช้ in แทน 553 | 554 | select * from books 555 | 556 | select * from authors where id in (1, 2, 3, 4, 5, ...) 557 | 558 | จะทำให้เว็บของเราโหลดเร็วขึ้นอย่างมากเลยครับ 559 | 560 | ตัวอย่าง การใช้ eager loading ในกรณีตารางมีการเชื่อมกับอีกหลายตาราง 561 | 562 | $books = Book::with('author', 'publisher')->get(); 563 | 564 | จะใช้การทำ eager load กับคอลัมน์อื่นได้ 565 | 566 | $books = Book::with('author.contacts')->get(); 567 | 568 | In the example above, the `author` relationship will be eager loaded, and the author's `contacts` relation will also be loaded. 569 | 570 | ### Eager Load Constraints 571 | บางเวลาเราต้องการเฉพาะบางคอลัม์จาการทำ eager loading แล้วใส่เงื่อนไขเข้าไปอีก สามารถกำหนดได้ดัังนี้ครับ: 572 | 573 | $users = User::with(array('posts' => function($query) 574 | { 575 | $query->where('title', 'like', '%first%'); 576 | }))->get(); 577 | 578 | 579 | 580 | ### Lazy Eager Loading 581 | 582 | เราสามารถใช้การทำ eager loading ไปยังตารางที่เชื่อมกันได้เหมือนในตัวอย่างครับ 583 | เราเข้าไปค้นต่อไปในตาราง publisher ที่เชื่อมกับตาราง author อีก 584 | 585 | $books = Book::all(); 586 | 587 | $books->load('author', 'publisher'); 588 | 589 | 590 | ## การบันทึกข้อมูลแบบมีความสัมพันธ์ 591 | 592 | สมมุตอเราจะเพิ่มความคิดเห็นลงบทความนี้แล้วเราก็ต้องนำ id ของบทความที่เราโพสความคิดเห็นใส่ไปมาใส่ในความคิดเห็นด้วย 593 | 594 | **ตัวอย่างการเก็บข้อมูลที่ต้องมีความสัมพันธ์** 595 | 596 | $comment = new Comment(array('message' => 'A new comment.')); 597 | 598 | $post = Post::find(1); 599 | 600 | $comment = $post->comments()->save($comment); 601 | 602 | ในตัวอย่างคอลัมน์`post_id` จะถูกใส่ค่าให้อัติโนมัติ 603 | 604 | ### Associating Models (Belongs To) 605 | 606 | เมื่อเราจะทำการแก้ไขข้อมูลที่มีความสัมพันธ์แบบ กลุ่มต่อหนึ่ง เราต้องใช้ฟังก์ชัน `associate` ในการเพิ่มค่าคีย์เชื่อมไปยังตารางที่มีความสัมพันธ์อยู่ด้วย 607 | 608 | $account = Account::find(10); 609 | 610 | $user->account()->associate($account); 611 | 612 | $user->save(); 613 | 614 | ### การเพิมข้อมูลแบบกลุ่มต่อกลุ่ม (Many To Many) 615 | 616 | ตัวอย่างคือเราจะทำการเพิ่มความสามารถให้ผู้เราต้อง laravel มีฟังก์ชัน `attach` มาให้ใช้เเล้ว 617 | 618 | **การเพิ่มข้อมูลแบบกลุ่มต่อกลุ่ม** 619 | 620 | $user = User::find(1); 621 | 622 | $user->roles()->attach(1); 623 | 624 | ตัวอย่างข้างล่าง เราจะทำการเพิ่มข้อมูลไปยังตารางที่ใช้เชื่อม สามารถส่งเป็นอาเรย์ก็ได้: 625 | 626 | $user->roles()->attach(1, array('expires' => $expires)); 627 | 628 | เมื่อเพิ่มแล้วก็ลบได้ ฟังก์ชัน `detach` ใช้ลบค่าในตารางที่ใช้เชื่อม 629 | 630 | $user->roles()->detach(1); 631 | 632 | เราสามารถใช้ฟังก์ชัน `sync`เมทอด เพื่อการเพิ่มค่าไปยังตารางที่เชื่อมอยู่ด้วยได้ ในขณะที่เพิ่มลงในตารางหลัก 633 | 634 | **ตัวอย่างการใช้ sync กับความสัมพันธ์แบบกลุ่มต่อกลุ่ม** 635 | 636 | $user->roles()->sync(array(1, 2, 3)); 637 | 638 | 639 | **Aตัวอย่างการใช้ sync กับตารางกลาง** 640 | 641 | $user->roles()->sync(array(1 => array('expires' => true))); 642 | 643 | การใช้เมทอด `save` เพื่อทำการเพิ่มข้อมูลงตารางที่เชื่อมกันอยู่ 644 | 645 | $role = new Role(array('name' => 'Editor')); 646 | 647 | User::find(1)->roles()->save($role); 648 | 649 | ในตัวอย่างเราสร้าง `Role` model แล้วแนบไปกับ User model. แล้วยังสามารถแนบอาเรย์เข้าไปได้อีก 650 | 651 | User::find(1)->roles()->save($role, array('expires' => $expires)); 652 | 653 | 654 | ## การแก้ไขคอลัมน์ที่เก็บเวลาในตารางที้่่เชื่อมด้วย 655 | 656 | ตัวอย่าง เมื่อเราแก้ไขข้อมูลในตาราง Comment เราต้องการแก้ไขข้อมูลในตาราง Post ในแถวที่เชื่อมกันด้วย laravel เตรียมฟังก์ชัน `touch` มาให้เเล้ว วิธีการใช้งานในตัวอย่างเลยครับ 657 | 658 | class Comment extends Eloquent { 659 | 660 | protected $touches = array('post'); 661 | 662 | public function post() 663 | { 664 | return $this->belongsTo('Post'); 665 | } 666 | 667 | } 668 | 669 | ตอนนี้ถ้าเราทำการแก้ไขข้อมูลในตาราง `Comment`, คอลัมน์ `updated_at` ข้อมูลในตาราง `Post`ที่เชื่อมด้วยก็จะถูกแก้ไขด้วย 670 | 671 | 672 | 673 | ## การจัดการตารางที่ใช้เชื่อม 674 | 675 | laravel เตรียมฟังก์ชัน `pivot` มาให้เราใช้ในการจัดการข้อมูลของตารางที่ใช้เชื่อมตรงกลางระหว่างสองตาราง ดังตัวอย่างเลยครับ 676 | 677 | $user = User::find(1); 678 | 679 | foreach ($user->roles as $role) 680 | { 681 | echo $role->pivot->created_at; 682 | } 683 | 684 | คลาส `Role` model จะดึงค่าออกมาจากตารางกลาง โดยใช้ฟังก์ชัน`pivot` โดยอัติโนมัติ 685 | 686 | โดยค่าเริ่มต้นแล้วค่าที่ได้จาก ตารางที่เป็นตัวเชื่อมจะมีค่าเดียวที่ใช้อ้างอิงไปยัง อีกตารางคือ id เท่านั้น แต่ถ้าเราต้องการเพิ่ม ก็ต้องเพิ่มไปตอนที่กำหนดความสัมพันธ์แบบในตัวอย่าง 687 | 688 | return $this->belongsToMany('Role')->withPivot('foo', 'bar'); 689 | 690 | ตอนนี้ตัวแปร `foo` กับ `bar` จะถูกใช้กับฟังก์ชัน `pivot` ในการจัดการตาราง `Role` 691 | 692 | และถ้าเราต้องการ คอลัมน์ `created_at` กับ `updated_at` เพื่อใช้กำหนดเวลา laravel มีฟังก์ชัน `withTimestamps` ซึ่งเราต้องกำหนดตอนประกาศความสัมพันธ์ครับ 693 | 694 | return $this->belongsToMany('Role')->withTimestamps(); 695 | 696 | 697 | ต่อมาถ้าเราต้องการลบข้อมูลในตารางในตารางกลาง เพื่อความถูกต้องของข้อมูลเราจะใช้ฟังก์ชัน `detach`นะครับ 698 | 699 | **ตัวอย่างการใช้งาน** 700 | 701 | User::find(1)->roles()->detach(); 702 | 703 | เราจะทำการแก้ไขไม่ให้ผู้ใช้งานหมายเลข 1 มีสิทธิในการทำอะไรเลย 704 | 705 | 706 | ## Collections 707 | 708 | ข้อมูลที่เป็นผลลัพท์ของการค้นหานั้นจะกลับออกมาเป็น อาเรย์ eloquent อำนวนความสะดวกให้เราโดยมีฟังกชัน `contains` ให้ในการตรวจสอบข้อมูล 709 | 710 | **ตรวจว่าในผลลัพท์ที่ได้มามีข้อมูลที่มีคีย์หลัก เป็น 2 ไหม** 711 | 712 | $roles = User::find(1)->roles; 713 | 714 | if ($roles->contains(2)) 715 | { 716 | // 717 | } 718 | 719 | เพื่อความสบายของเรายิ่งขึ้นไปอีกเมื่อค้นเสร็จก็เอาเฉพาะค่า role แปลงเป็นอาเรย์ หรือ json เสร็จสรรพเลย 720 | 721 | $roles = User::find(1)->roles->toArray(); 722 | 723 | $roles = User::find(1)->roles->toJson(); 724 | 725 | แทนที่จะใช้การทำ foreach แบบปกติเหมือนเดิม eloquent มีฟังก์ชัน each กับ filter มาให้ 726 | **การใช้งาน each และ filter** 727 | 728 | $roles = $user->roles->each(function($role) 729 | { 730 | 731 | }); 732 | 733 | $roles = $user->roles->filter(function($role) 734 | { 735 | 736 | }); 737 | 738 | **เพิ่มการ Callback** 739 | 740 | $roles = User::find(1)->roles; 741 | 742 | $roles->each(function($role) 743 | { 744 | // 745 | }); 746 | 747 | **เรียงลำดับค่าที่อยู่ในอาเรย์ด้วยฟังก์ชัน sortby** 748 | 749 | $roles = $roles->sortBy(function($role) 750 | { 751 | return $role->created_at; 752 | }); 753 | 754 | บางครั้งเราต้องการเปลียนแปลงค่าทั้งออปเจคเลย eloquent ก็มีฟังก์ชัน `newCollection` ให้ใช้ในการเขียนทับ 755 | 756 | **ตัวอย่างการใช้งาน** 757 | 758 | class User extends Eloquent { 759 | 760 | public function newCollection(array $models = array()) 761 | { 762 | return new CustomCollection($models); 763 | } 764 | 765 | } 766 | 767 | 768 | ## Accessors & Mutators 769 | 770 | ถ้ายังไม่เข้าใจว่าสองฟังก์ชันนี้มันคืออะไร ทำอะไรได้บ้าง แนะนำเข้าไปอ่านที่ผมสรุปไว้ก่อนใน [บล็อก](http://taqmaninw.com/accesor-กับ-mutator-จะใช้ยังไงใน-php/) ครับ 771 | บางเวลาเราต้องการ จัดรูปแบบข้อมูลให้อยู่ในรูปแบบที่เราต้องการ ก่อนจะบันทึกหรือดึงมาใช้ eloquent เตรียมฟังก์ชัน `getFooAttribute` แต่การตั้งชื่อฟังก์ชันคำเริ่มต้นของคำที่เป็นชื่อของคอลัมน์ ต้องขึ้นต้นด้วยตัวพิมพ์ใหญ่ ในกรณีที่มีเครื่องหมาย _ มาคั่น คำหลังจากนั้นก็ต้องขึ้นต้นด้วยตัวพิมพ์ใหญ่ครับ 772 | 773 | **ตัวอย่าง** 774 | 775 | class User extends Eloquent { 776 | 777 | public function getFirstNameAttribute($value) 778 | { 779 | return ucfirst($value); 780 | } 781 | 782 | } 783 | 784 | ในตัวอย่างเราทำการสร้าง accessor ของคอลัมน์ `first_name` ทีนี้ค่าที่เราส่งเข้าฟังก์ชันนี้ก็จะถูกส่งไปเก็บถูกที่ละครับ 785 | 786 | การสร้างฟังก์ชัน Mutator ก็คล้ายๆ กัน 787 | 788 | **ตัวอย่าง** 789 | 790 | class User extends Eloquent { 791 | 792 | public function setFirstNameAttribute($value) 793 | { 794 | $this->attributes['first_name'] = strtolower($value); 795 | } 796 | 797 | } 798 | 799 | 800 | ## Date Mutators 801 | 802 | โดยค่าเริ่มต้นเเล้ว Eloquent จะทำการตั้งค่าให้คอลัมน์ `created_at`, `updated_at`, และ `deleted_at` ตามค่าเบื้องต้นของ php.ini อยู่เเล้วนะครับ 803 | 804 | แต่ถ้าเราต้องการแก้ไขหรือเรียกใช้งานแบบไม่อยากเข้าไปยุ่งตรงๆ ก็สามารถใช้ฟังก์ชัน `getDates` แบบในตัวอย่างเลยครับ 805 | 806 | public function getDates() 807 | { 808 | return array('created_at'); 809 | } 810 | 811 | ข้างในเราสามารถจัดการก่อนเอาไปใช้ได้เลย และ laravel ก็มีคลาสจัดการ วันเวลาที่มีฟังก์ชันหลากหลายมากอย่าง `Carbon` มาให้ใช้ด้วย แต่ต้องไปประกาศชื่อย่อในไฟล์ app.php ก่อนนะครับ โดยค่าเริ่มต้นเเล้วไม่มี 812 | 813 | 814 | 815 | ## Model Events 816 | 817 | Eloquent เตรียมฟังก์ชันที่คอยดักจับเหตุการณ์ต่างๆ มาให้เราดังนี้ครับ `creating`, `created`, `updating`, `updated`, `saving`, `saved`, `deleting`, `deleted`. แต่ถ้าค่าที่ส่งกลับมาเป็น `false` เหตุการณ์ `creating`, `updating`, หรือ `saving` จะถูกยกเลิก 818 | 819 | **การยกเลิกการแก้ไขข้อมูล** 820 | 821 | User::creating(function($user) 822 | { 823 | if ( ! $user->isValid()) return false; 824 | }); 825 | 826 | การที่เราจะสร้างฟังก์ชัน์ในการจัดการเหตุการณ์ของ model ต้องประกาศฟังชัน `boot` ก่อนนะครับ 827 | 828 | **การประกาศฟังก์ชัน boot** 829 | 830 | class User extends Eloquent { 831 | 832 | public static function boot() 833 | { 834 | parent::boot(); 835 | 836 | // Setup event bindings... 837 | } 838 | 839 | } 840 | 841 | 842 | ## Model Observers 843 | 844 | Eloquent มีคลาสชื่อ Observer ในการสร้างฟังก์ชันที่ใช้จัดการเหตุการณ์ ฟังก์ชัน`creating`, `updating`, `saving` ก็ตั้งตามเหตุการณ์ที่จะให้ฟังก์ชันนั้นจัดการครับ ตัวอย่าง 845 | 846 | class UserObserver { 847 | 848 | public function saving($model) 849 | { 850 | // 851 | } 852 | 853 | public function saved($model) 854 | { 855 | // 856 | } 857 | 858 | } 859 | 860 | แล้วเราก็ต้องประกาศโดยใช้ฟังชัน `observe` แบบตัวอย่าง 861 | 862 | User::observe(new UserObserver); 863 | 864 | 865 | ## การแปลงค่าเป็น Arrays หรือ JSON 866 | 867 | 868 | **การแปลงผลลัพทที่ค้นมาให้กลายเป็น array** 869 | 870 | $user = User::with('roles')->first(); 871 | 872 | return $user->toArray(); 873 | 874 | return User::all()->toArray(); 875 | 876 | 877 | **การแปลงผลลัพธ์ให้กลายเป็น json** 878 | 879 | return User::find(1)->toJson(); 880 | 881 | 882 | **การใช้งาน Eloquent จากใน route เลย** 883 | 884 | Route::get('users', function() 885 | { 886 | return User::all(); 887 | }); 888 | 889 | บางเวลาาเราไม่อยากให้บางคอลัมน์ถุกเรียกไปพร้อมกับ `toJson` หรือ `toArray` เราก็ใช้ตัวแปร `hidden` ในการนั้น 890 | 891 | **ต้วอย่างการใช้งาน** 892 | 893 | class User extends Eloquent { 894 | 895 | protected $hidden = array('password'); 896 | 897 | } 898 | -------------------------------------------------------------------------------- /errors.md: -------------------------------------------------------------------------------- 1 | # Errors & Logging 2 | 3 | 4 | ## การแสดง Error 5 | 6 | โดยค่าเริ่มต้นเเล้วการแสดงข้อผิดพลาดจะถูกเปิดใช้งานอยู่เเล้ว หากเราพัฒนาเว็บเสร็จ ก่อนจะส่งขึ้นโฮสติ้งก็ควรเข้าไปตั้งค่าตัวแปร `debug` ที่ `app/config/app.php` ให้เป็น `false` 7 | 8 | 9 | ## การจัดการ Errors 10 | 11 | โดยค่าเริ่มต้นเเล้วการจัดการข้อผิดพลาดต่างๆเราจะทำในไฟล์ `app/start/global.php` 12 | 13 | App::error(function(Exception $exception) 14 | { 15 | Log::error($exception); 16 | }); 17 | 18 | ถ้าเราอยากกำหนดการทำงานหลังจากเกิด `RuntimeException` เราก็ทำได้ดังตัวอย่างครับ 19 | 20 | App::error(function(RuntimeException $exception) 21 | { 22 | // Handle the exception... 23 | }); 24 | 25 | เมื่อเราใช้การ return ในฟังก์ชันข้างล่างนี้ ค่าจะถูกส่งกลับไปยังบราวเซอร์เสมอครับ: 26 | 27 | App::error(function(InvalidUserException $exception) 28 | { 29 | Log::error($exception); 30 | 31 | return 'Sorry! Something is wrong with this account!'; 32 | }); 33 | 34 | การดักรอ PHP fatal errors เราใช้ฟังก์ชัน `App::fatal` 35 | 36 | App::fatal(function($exception) 37 | { 38 | // 39 | }); 40 | 41 | 42 | ## HTTP Exceptions 43 | 44 | กรณีข้อผิดพลาดที่เกิดขึ้นเพราะไม่พบหน้าที่เรียก (404), กับไม่มีสิทธิเข้าถึง (401) เราสามารถแก้ไขค่าที่จะไปแสดงได้ดังนี้ 45 | 46 | App::abort(404, 'Page not found'); 47 | 48 | App::abort(401, 'You are not authorized.'); 49 | ค่า 404 คือรหัสข้อผิดพลาดครับ 50 | 51 | 52 | ## การจัดการข้อผิดพลาด 404 53 | 54 | เราสามารถสร้างหน้าแสดงข้อผิดพลาดที่เรา สามารถออกแบบได้เอง แล้วต้องมาตั้งค่าแบบในตัวอย่างนี้ พารามิเตอร์ที่หนึ่งคือ ที่อยู่ของไฟล์ view 55 | 56 | App::missing(function($exception) 57 | { 58 | return Response::view('errors.missing', array(), 404); 59 | }); 60 | 61 | 62 | ## การเก็บ log 63 | 64 | คลาสที่ใช้ในการเก็บ log ของ laravel เป็นการใช้คลาส [Monolog](http://github.com/seldaek/monolog) มาพัฒนาต่อ Laravel ตั้งค่าเริ่มต้นให้เก็บ log ทุกวันแล้วส่งไปเก็บไว้ใน `app/storage/logs`เราสามารถกำหนดค่า log ที่จะเขียนได้ดังตัวอย่าง 65 | 66 | Log::info('This is some useful information.'); 67 | 68 | Log::warning('Something could be going wrong.'); 69 | 70 | Log::error('Something is really going wrong.'); 71 | 72 | ประเภทของ log ถูกประกาศไว้ในมาตรฐาน [RFC 5424](http://tools.ietf.org/html/rfc5424) มี **debug**, **info**, **notice**, **warning**, **error**, **critical**, และ **alert**. 73 | 74 | ตัวอย่างการส่งค่าที่เป็นอาเรย์ให้ฟังก์ชัน info ที่อยู่ในคลาส log 75 | 76 | Log::info('Log message', array('context' => 'Other helpful information')); 77 | 78 | การดึงค่ามาใช้ก็ใช้ฟังก์ชันตามตัวอย่างเลยครับ 79 | 80 | $monolog = Log::getMonolog(); 81 | 82 | เราสามารถกำหนดเหตุการณ์ที่เราจะให้เก็บ log ได้โดยใช้ฟังก์ชัน listen: 83 | 84 | **ตัวอย่าง** 85 | 86 | Log::listen(function($level, $message, $context) 87 | { 88 | // 89 | }); 90 | -------------------------------------------------------------------------------- /events.md: -------------------------------------------------------------------------------- 1 | # Events 2 | 3 | 4 | ## การใช้งานเบื้องต้น 5 | 6 | คลาส `Event` เตรียมมาให้เราใช้ในการดักจับเหตุการณ์ต่างๆที่เกิดขึ้นบน เว็บของเรา 7 | หมายเหตุ Event คือเหตุการใดที่เกิดขึ้นบนเว็บเรา ยกตัวอย่างการเพิ่มลบแก้ไข , Listener คือ ฟังก์ชันที่คอยดักจับเหตุการ , fire คือฟังก์ชันที่สั่งให้เกิดเหตุการขึ้นเพื่อให้ listerner ทำงาน 8 | 9 | **การดักรอฟังเหตุการณ์** 10 | 11 | Event::listen('user.login', function($user) 12 | { 13 | $user->last_login = new DateTime; 14 | 15 | $user->save(); 16 | }); 17 | 18 | **การสั่งให้เกิดเหตุการณ์ขึ้น** 19 | 20 | $event = Event::fire('user.login', array($user)); 21 | 22 | เราสามารถกำหนดลำดับเหตุการที่จะให้เกิดได้ โดยค่าลำดับที่เกิดเรียงจากน้อยไปหามาก. 23 | 24 | **การใช้ลำดับควบคุมการทำงาน** 25 | 26 | Event::listen('user.login', 'LoginHandler', 10); 27 | 28 | Event::listen('user.login', 'OtherHandler', 5); 29 | 30 | บางครั้งเราอยากจะให้ฟังก์ชันที่ดักฟังอยู่ทำงานแค่ครั้งเดียว เราสามารถใช้การ return `false` เพื่อหยุดฟังก์ชันนี้ได้ 31 | 32 | **หยุดการทำงานของเหตุการ** 33 | 34 | Event::listen('user.login', function($event) 35 | { 36 | // Handle the event... 37 | 38 | return false; 39 | }); 40 | 41 | 42 | ## Wildcard Listeners 43 | 44 | คือการดักฟังทุกเหตุการเลย ไม่เฉพาะเจาะจงเเล้ว 45 | 46 | **การใช้งาน** 47 | 48 | Event::listen('foo.*', function($param, $event) 49 | { 50 | // Handle the event... 51 | }); 52 | 53 | ทีนี้ถ้ามีเหตุการณ์อะไรที่ขึ้นต้นด้วย `foo.`.ฟังก์ชันในตัวอย่างก็จะทำงาน 54 | 55 | 56 | ## ใช้ Classes กับ Listeners 57 | 58 | ในบางกรณี เราสามารถผูกคลาสเข้ากับเหตุการได้ โดย laravel จะใช้การทำ [Laravel IoC container](/docs/ioc),ในการจัดการ 59 | 60 | **ตัวอย่าง** 61 | 62 | Event::listen('user.login', 'LoginHandler'); 63 | 64 | โดยค่าเริ่มต้นฟังก์ชัน `handle` ในคลาส `LoginHandler`จะถูกเรียกก่อนเลย เหมือนกับ _construct 65 | 66 | **ฟังก์ชัน handle จะถูกเรียกใช้เลย** 67 | 68 | class LoginHandler { 69 | 70 | public function handle($data) 71 | { 72 | // 73 | } 74 | 75 | } 76 | 77 | ถ้าเราไม่ต้องการ ก็ผูกเมทอดที่เราต้องการเข้าไปดังนี้ครับ 78 | 79 | Event::listen('user.login', 'LoginHandler@onLogin'); 80 | 81 | 82 | ## การเรียงลำดับเหตุการ 83 | 84 | ใช้ฟังก์ชัน `queue` กับ `flush` ในการเรียงลำดับการเกิดเหตุการ 85 | 86 | **การสร้างลำดับ** 87 | 88 | Event::queue('foo', array($user)); 89 | 90 | 91 | 92 | ## Event Subscribers 93 | 94 | คือคลาสที่เราแบ่งกลุ่มฟังก์ชันที่ใช้จัดการเหตุการ โดยต้นทางมาจากฟังก์ชัน `subscribe` 95 | 96 | **ตัวอย่างการสร้างคลาส Subscriber** 97 | 98 | class UserEventHandler { 99 | 100 | /** 101 | * ติดตามการเข้าใช้งานของผู้ใช้งาน 102 | */ 103 | public function onUserLogin($event) 104 | { 105 | // 106 | } 107 | 108 | /** 109 | * ติดตามการออกจากระบบ 110 | */ 111 | public function onUserLogout($event) 112 | { 113 | // 114 | } 115 | 116 | /** 117 | * สร้างฟังก์ชันเพื่อใช้งานคลาส 118 | * 119 | * @param Illuminate\Events\Dispatcher $events 120 | * @return array 121 | */ 122 | public function subscribe($events) 123 | { 124 | $events->listen('user.login', 'UserEventHandler@onUserLogin'); 125 | 126 | $events->listen('user.logout', 'UserEventHandler@onUserLogout'); 127 | } 128 | 129 | } 130 | 131 | เมื่อประกาศคลาสแล้ว การนำไปใช้งานเราก็ต้องเอาไปลงทะเบียนกับคลาสหลัก 132 | 133 | **ตัวอย่าง** 134 | 135 | $subscriber = new UserEventHandler; 136 | 137 | Event::subscribe($subscriber); 138 | -------------------------------------------------------------------------------- /facades.md: -------------------------------------------------------------------------------- 1 | # Facades 2 | > **ความเห็นส่วนตัว** บทนี้จะต้องใช้จินตนาการเยอะหน่อยนะครับ เพราะเป็นเรื่องของแนวคิดที่ใช้สร้างจุดขายของตัว laravel เลยครับ ในการตัด $this-> ทิ้งไปทำให้โค้ดอ่านง่าย ทำความเข้าใจง่าย ลดบริมาณการเขียนลง ใครที่อยากจะเอาคลาสบน packagist มาทำเป็น package ใช้เองต้องอ่านครับ 3 | 4 | ## รู้จักด้านหน้าของตึกกันก่อน 5 | 6 | >ถ้ายังไม่รู้จักว่ามันคืออะไรลองไปอ่านที่ผม[สรุป](http://taqmaninw.com/facade-design-pattern-เพิ่งรู้ว่าหน้าตึกมันเป็นแบบนี้)ไว้ก็ได้ครับ 7 | 8 | Facades แปลเป็นไทยคือ ด้านหน้าของตึก ที่มาของมันคือการใช้ facade design pattern เข้ามาจัดการทำ ให้คลาสที่เราเรียกใช้งานกลายเป็นแบบ static แทนที่จะสร้างเป็นออปเจคเหมือนที่ผ่านมา การทำแบบ static คือการเรียกใช้คลาสนั้นตรงๆ เลยครับ การทำแบบนี้จะทำให้รูปแบบของฟังก์ชันดูเข้าใจได้ง่ายมาก 9 | บางครั้งเราไปเจอคลาสที่เจ๋งๆ และอยากเอาเข้ามาใช้ใน laravel เราก็อยากให้มันเรียกแบบ static ได้เพราะฉะนั้นเราจึงต้องมาดูบททนี้ครับ 10 | 11 | > **Note:** ก่อนที่จะมาเจาะลึกลงไปในโครงสร้างหลักของ laravel แนะนำให้ไปอ่านบบทนี้ [IoC container](/docs/ioc) ก่อนครับ 12 | 13 | 14 | ## หลักการเบื้องต้น 15 | 16 | โดยโครงสร้างหลักของ laravel แล้ว, facade คลาสถูกวางให้ใช้ในการเรียกใช้งาน วัตถุที่ถูกลงทะเบียนไว้ในคลาส Container ในการสร้าง facade ขึ้นใช้เองนั้น เราต้องการแค่เมทอด `getFacadeAccessor`แค่ตัวเดียวครับ ตัวคลาส `Facade` หลักจะทำการใช้ `__callStatic()` ซึ่งเป็น magic-method ของ php จะไปทำการเรียกออปเจ็คของคลาสที่เราทำการลงทะเบียนไว้ที่คลาส `Service Provider` 17 | ของ ไลบราลี่ นั้นๆ 18 | 19 | 20 | ## การประยุกต์ใช้งาน 21 | 22 | ในตัวอย่าง, เรายกตัวอย่าง คลาส `Cache`. ซึ่งเรียกตัวฟังก์ชัน `get` ซึ่งตอนนี้เป็นรูปแบบ static นะครับ 23 | 24 | $value = Cache::get('key'); 25 | 26 | แต่ถ้าเราตามเข้าไปดูตามเส้นทางนี้ `Illuminate\Support\Facades\Cache` เราจะไม่เห็นฟังก์ชัน `get` อยู่เลย 27 | 28 | class Cache extends Facade { 29 | 30 | /** 31 | * Get the registered name of the component. 32 | * 33 | * @return string 34 | */ 35 | protected static function getFacadeAccessor() { return 'cache'; } 36 | 37 | } 38 | 39 | การทำงานคือเมทอด `getFacadeAccessor()`จะทำการส่งค่าที่เราทำการผูกไว้ในคลาสหลัก โดยใช้สตริงที่เรากำหนดตรง return ในการค้นหาคลาสที่ตรงกันให้ 40 | 41 | เมื่อผู้ใช้งานอ้างอิงถึงตัว `Cache` คลาสในรูปแบบ static, Laravel จะผูก`cache` เข้ากับ IoC container และส่งคำขอฟังก์ชันตามในตัวอย่าง (กรณีนี้เป็น `get`) 42 | 43 | ถ้าจะเขียน `Cache::get` แบบปกติจะได้แบบนี้ครับ 44 | 45 | $value = $app->make('cache')->get('key'); 46 | 47 | 48 | ## การสร้าง Facades 49 | 50 | การสร้าง Facade ให้ package หรือ คลาสภายนอกต้องการ 3 อย่างครับ 51 | 52 | - การทำ IoC bind 53 | - คลาส facade 54 | - การสร้าง alias ให้ facade 55 | 56 | ตัวอย่างการสร้าง package แบบง่ายครับ 57 | `PaymentGateway\Payment`. 58 | 59 | namespace PaymentGateway; 60 | 61 | class Payment { 62 | 63 | public function process() 64 | { 65 | // 66 | } 67 | 68 | } 69 | 70 | เราต้องทำการผูกคลาสเข้ากับตัวคลาสหลักก่อน 71 | 72 | App::bind('payment', function() 73 | { 74 | return new \PaymentGateway\Payment; 75 | }); 76 | 77 | ที่ๆ เราจะนำฟังก์ชันข้างบนไปเขียนไว้คือที่ไฟล์ [service provider](/docs/ioc#service-providers) ที่ชื่อ `PaymentServiceProvider` โดยใส่ไว้ข้างในเมทอด `register`เราต้องเอาเส้นทางที่อยู่ของคลาส `PaymentServiceProvider` ไปใส่ตรงที่ `app/config/app.php` ด้วย 78 | 79 | ต่อมา เราก็สร้างคลาส Facade ให้กับคลาส Payment 80 | 81 | use Illuminate\Support\Facades\Facade; 82 | 83 | class Payment extends Facade { 84 | 85 | protected static function getFacadeAccessor() { return 'payment'; } 86 | 87 | } 88 | 89 | สุดท้าย เรานำที่อยู่ของไฟล์ Facade ไปใส่ที่อาเรย์ชื่อ `aliases` ใน `app/config/app.php` และต้องใช้คำสั่ง `php artisan dump-autoload ` ก่อนนะครับไม่งั้น laravel จะไม่เจอคลาส แล้วสุดท้ายเราสามารถเรียกเมทอด `process` ของ คลาส `Payment` ในรูปแบบ static ได้เเล้ว 90 | 91 | Payment::process(); 92 | 93 | 94 | -------------------------------------------------------------------------------- /helpers.md: -------------------------------------------------------------------------------- 1 | # Helper Functions 2 | 3 | เป็นคลาสอเนกประสงค์ที่รวมการจัดการอาเรย์,สตริง,ยูอาร์แอล อื่นๆ 4 | 5 | 6 | ## Arrays 7 | 8 | ### array_add 9 | 10 | ฟังก์ชัน `array_add` ใช้เพิ่ม key / value ลงในอาเรย์ถ้าไม่มี key นั้นอยู่ 11 | 12 | $array = array('foo' => 'bar'); 13 | 14 | $array = array_add($array, 'key', 'value'); 15 | 16 | ### array_divide 17 | 18 | ฟังก์ชัน `array_divide` จะทำการแบ่งอาเรย์ที่ส่งเข้าไปออก เป็นสองก้อน ก้อนหนึ่งเป็น key ก้อนหนึ่งเป็น value 19 | 20 | $array = array('foo' => 'bar'); 21 | 22 | list($keys, $values) = array_divide($array); 23 | 24 | ### array_dot 25 | 26 | ฟังก์ชัน `array_dot` จะทำการแผ่อาเรย์หลายมิติ ออกเป็นมิติเดียว โดยเราจะใช้เครื่องหมายดอทในการเข้าถึงหลังจากใช้ฟังก์ชันแแล้ว 27 | 28 | $array = array('foo' => array('bar' => 'baz')); 29 | 30 | $array = array_dot($array); 31 | 32 | // array('foo.bar' => 'baz'); 33 | 34 | ### array_except 35 | 36 | ฟังก์ชัน `array_except` ใช้ลบค่า key หรือ value ออกจากอาเรย์ 37 | 38 | $array = array_except($array, array('keys', 'to', 'remove')); 39 | 40 | ### array_fetch 41 | 42 | ฟังก์ชัน `array_fetch` จะส่งอาเรย์มิติเดียวที่เรากำหนดได้ว่าจะเอาค่าเฉพาะ คีย์ชื่ออะไร 43 | 44 | $array = array(array('name' => 'Taylor'), array('name' => 'Dayle')); 45 | 46 | var_dump(array_fetch($array, 'name')); 47 | 48 | // array('Taylor', 'Dayle'); 49 | 50 | ### array_first 51 | 52 | ฟังก์ชัน `array_first` จะส่งค่าแรกของอาเรย์คืนมา 53 | 54 | $array = array(100, 200, 300); 55 | 56 | $value = array_first($array, function($key, $value) 57 | { 58 | return $value >= 150; 59 | }); 60 | 61 | 62 | ### array_flatten 63 | 64 | ฟังก์ชัน `array_flatten` ทำการแตกอาเรย์หลายมิติลงมาเหลือมิติเดียว 65 | 66 | $array = array('name' => 'Joe', 'languages' => array('PHP', 'Ruby')); 67 | 68 | $array = array_flatten($array); 69 | 70 | // array('Joe', 'PHP', 'Ruby'); 71 | 72 | ### array_forget 73 | 74 | ฟังก์ชัน `array_forget` ใช้ลบค่าออกจากอาเรย์โดยกำหนดตำแหน่ง ด้วยใช้เครื่องหมายดอท 75 | $array = array('names' => array('joe' => array('programmer'))); 76 | 77 | $array = array_forget($array, 'names.joe'); 78 | 79 | ### array_get 80 | 81 | ฟังก์ชัน `array_get` ใช้ดึงค่าออกจากอาเรย์โดยกำหนดตำแหน่ง ด้วยเครื่องหมายดอท 82 | 83 | $array = array('names' => array('joe' => array('programmer'))); 84 | 85 | $value = array_get($array, 'names.joe'); 86 | 87 | ### array_only 88 | 89 | ฟังก์ชัน `array_only` ใช้ดึงค่าจากเฉพาะ key ที่เรากำหนด ได้ค่าเดียว 90 | 91 | $array = array('name' => 'Joe', 'age' => 27, 'votes' => 1); 92 | 93 | $array = array_only($array, array('name', 'votes')); 94 | 95 | ### array_pluck 96 | 97 | ฟังก์ชัน `array_pluck` ใช้ดึงค่าตามคีย์ที่กำหนด ได้หลายๆค่า 98 | 99 | $array = array(array('name' => 'Taylor'), array('name' => 'Dayle')); 100 | 101 | $array = array_pluck($array, 'name'); 102 | 103 | // array('Taylor', 'Dayle'); 104 | 105 | ### array_pull 106 | 107 | ฟังก์ชัน `array_pull` ใช้ดึงค่าออกมาพร้อมกับลบไปด้วย. 108 | 109 | $array = array('name' => 'Taylor', 'age' => 27); 110 | 111 | $name = array_pull($array, 'name'); 112 | 113 | ### array_set 114 | 115 | ฟังก์ชัน `array_set` ใช้เพิ่มค่าลงอาเรย์โดยกำหนดที่อยู่โดยใช้เครื่องหมายดอท 116 | 117 | $array = array('names' => array('programmer' => 'Joe')); 118 | 119 | array_set($array, 'names.editor', 'Taylor'); 120 | 121 | ### array_sort 122 | 123 | ฟังก์ชัน `array_sort` ใช้เรียงลำดับค่าในอาเรย์ 124 | 125 | $array = array( 126 | array('name' => 'Jill'), 127 | array('name' => 'Barry'), 128 | ); 129 | 130 | $array = array_values(array_sort($array, function($value) 131 | { 132 | return $value['name']; 133 | })); 134 | 135 | ### head 136 | 137 | ใช้คืนค่าแรกของ อาเรย์ มีประโยช์มากในการทำการเรียกฟังก์ชันแบบต่อเนื่อง 138 | 139 | $first = head($this->returnsArray('foo')); 140 | 141 | ### last 142 | 143 | ใช้คืนค่าสุดท้ายของ อาเรย์ มีประโยช์มากในการทำการเรียกฟังก์ชันแบบต่อเนื่อง 144 | 145 | $last = last($this->returnsArray('foo')); 146 | 147 | 148 | ## Paths 149 | ตัวแปรที่ใช้เก็บค่าที่อยู่ของโฟลเดอร์ 150 | ### app_path 151 | 152 | เก็บค่าที่อยู่ของโฟลเดอร์ `application` 153 | 154 | ### base_path 155 | 156 | เก็บค่าที่อยู่ของเว็บระดับ root เลย 157 | 158 | ### public_path 159 | 160 | เก็บค่าที่อยู่ของโฟลเดอร์ `public` 161 | 162 | ### storage_path 163 | 164 | เก็บค่าที่อยู่ของโฟลเดอร์ `application/storage` 165 | 166 | 167 | ## Strings 168 | คลาสนี้ ใช้จัดการตัวอักษร เช่นแปลงเป็นตัวใหญ่ รูปแบบไวยกรณ์ 169 | ### camel_case 170 | 171 | แปลงคำให้ขึ้นต้นด้วยตัวใหญซึ่งเรียกว่า `camelCase`. 172 | 173 | $camel = camel_case('foo_bar'); 174 | 175 | // fooBar 176 | 177 | ### class_basename 178 | 179 | ใช้ดึงชื่อคลาสจาก namespace path. 180 | 181 | $class = class_basename('Foo\Bar\Baz'); 182 | 183 | // Baz 184 | 185 | ### e 186 | 187 | เรียกใช้ฟังก์ชัน `htmlentites` เพื่อกรองค่า 188 | 189 | $entities = e('foo'); 190 | 191 | ### ends_with 192 | 193 | ใช้ตรวจว่าในประโยคจบด้วยคำที่กำหนดไหม 194 | 195 | $value = ends_with('This is my name', 'name'); 196 | 197 | ### snake_case 198 | 199 | แปลงคำให้ไปอยู่ในรูปแบบ `snake_case` คืออักษรขึ้นต้นคำเป็นตัวเล็กแล้วแบ่งคำด้วยเครื่องหมายอันเดอร์สกอร์ 200 | 201 | $snake = snake_case('fooBar'); 202 | 203 | // foo_bar 204 | 205 | ### starts_with 206 | 207 | ใช้ตรวจว่าในประโยคขึ้นต้นด้วยคำที่กำหนดไหม 208 | 209 | $value = starts_with('This is my name', 'This'); 210 | 211 | ### str_contains 212 | 213 | ใช้ตรวจว่าในประโยคมีคำที่กำหนดไหม 214 | 215 | $value = str_contains('This is my name', 'my'); 216 | 217 | ### str_finish 218 | 219 | เพิมตัวอักษรที่กำหนดลงไปท้ายคำ 220 | 221 | $string = str_finish('this/string', '/'); 222 | 223 | // this/string/ 224 | 225 | ### str_is 226 | 227 | ตรวจว่าค่าที่ป้อนเข้ามาตรงกับรูปแบบที่กำหนดไหม 228 | 229 | $value = str_is('foo*', 'foobar'); 230 | 231 | ### str_plural 232 | 233 | แปลงตัวอักษรจากเอกพจน์เป็นพหูพจ์ ปล.เติม s,es,ies 234 | 235 | $plural = str_plural('car'); 236 | 237 | ### str_random 238 | 239 | สุ่มตัวอักษรขึ้นมาโดยกำหนดความยาวตามค่าที่ป้อนเข้ามา 240 | 241 | $string = str_random(40); 242 | 243 | ### str_singular 244 | 245 | แปลงตัวอักษรจากเอกพจน์เป็นเอกพจน์ 246 | 247 | $singular = str_singular('cars'); 248 | 249 | ### studly_case 250 | 251 | แปลงคำให้ไปอยู่ในรูปแบบ `StudlyCase` คืออักษรขึ้นต้นคำเป็นตัวใหญ่ถ้ามีเครื่องหมายอันเดอร์สกอร์ก็ลบออก 252 | 253 | $value = studly_case('foo_bar'); 254 | 255 | // FooBar 256 | 257 | ### trans 258 | 259 | ใช้แปลภาษาเหมือนกับใช้ `Lang::get`. 260 | 261 | $value = trans('validation.required'): 262 | 263 | ### trans_choice 264 | 265 | แปลโดยเริ่มต้นจากคำที่กำหนดโดยนับต่อไปตามค่าจากตัวแปร $count เหมือนกับ `Lang::choice`. 266 | 267 | $value = trans_choice('foo.bar', $count); 268 | 269 | 270 | ## URLs 271 | เป็นฟังก์ชันที่ใช้จัดการ URL 272 | ### action 273 | 274 | สร้างลิ้งจาก controller 275 | 276 | $url = action('HomeController@getIndex', $params); 277 | 278 | ### asset 279 | 280 | สร้างลิ้งจากไฟล์ที่อยู่ในโฟลเดอร์ asset 281 | 282 | $url = asset('img/photo.jpg'); 283 | 284 | ### link_to 285 | 286 | สร้างลิ้งโดยกำหนดค่าต่างๆเอง 287 | 288 | echo link_to('foo/bar', $title, $attributes = array(), $secure = null); 289 | 290 | ### link_to_asset 291 | 292 | สร้างลิ้งจากไฟล์ที่อยู่ในโฟลเดอร์ asset 293 | 294 | echo link_to_asset('foo/bar.zip', $title, $attributes = array(), $secure = null); 295 | 296 | ### link_to_route 297 | 298 | สร้างลิ้งโดยอ้างอิงจากค่า route 299 | 300 | echo link_to_route('route.name', $title, $parameters = array(), $attributes = array()); 301 | 302 | ### link_to_action 303 | 304 | สร้างลิ้งเข้าไปหาฟังก์ชันใน controller 305 | 306 | echo link_to_action('HomeController@getIndex', $title, $parameters = array(), $attributes = array()); 307 | 308 | ### secure_asset 309 | 310 | สร้างลิ้งจากไฟล์ที่อยู่ในโฟลเดอร์ asset โดยใช้ https 311 | 312 | echo secure_asset('foo/bar.zip', $title, $attributes = array()); 313 | 314 | ### secure_url 315 | 316 | สร้างลิ้งที่เป็น https 317 | 318 | echo secure_url('foo/bar', $parameters = array()); 319 | 320 | ### url 321 | 322 | สร้างลิ้งจากการกำหนดเอง 323 | 324 | echo url('foo/bar', $parameters = array(), $secure = null); 325 | 326 | 327 | ## Miscellaneous 328 | ฟังก์ชันอเนกประสงค์ 329 | ### csrf_token 330 | 331 | สร้างค่า hash ที่ใช้ป้องกันการโจมตีแบบ csrf 332 | 333 | $token = csrf_token(); 334 | 335 | ### dd 336 | 337 | ใช้ในการดึงค่าทั้งหมดในตัวแปรออกมาแสดง 338 | 339 | dd($value); 340 | 341 | ### value 342 | ดึงค่าจากฟังก์ชันที่ไม่มีชื่อ 343 | 344 | $value = value(function() { return 'bar'; }); 345 | 346 | ### with 347 | 348 | ใช้ดึงค่ากลับมาเป็นวัตถุ 349 | 350 | $value = with(new Foo)->doWork(); 351 | -------------------------------------------------------------------------------- /html.md: -------------------------------------------------------------------------------- 1 | # Forms & HTML 2 | 3 | เป็นคลาสที่ใช้จัดการ Form กับ html 4 | 5 | 6 | ## การเปิดฟอร์ม 7 | 8 | **ตัวอย่าง** 9 | 10 | {{ Form::open(array('url' => 'foo/bar')) }} 11 | // 12 | {{ Form::close() }} 13 | 14 | โดยค่าเริ่มต้นชนิดของคำร้องขอจะเป็น `POST` ถ้าจะเปลี่ยนก็เเค่ใส่พารามิเตอร์ไปเหมือนในตัวอย่างครับ 15 | 16 | echo Form::open(array('url' => 'foo/bar', 'method' => 'put')) 17 | 18 | 19 | สามารถกำหนดเป้าหมายของไฟล์ที่จะส่งค่าไปได้หลายรูปแบบตามตัวอย่างเลยครับ 20 | 21 | echo Form::open(array('route' => 'route.name')) 22 | 23 | echo Form::open(array('action' => 'Controller@method')) 24 | 25 | จะกำหนดพารามิเตอร์โดยเฉพาะเลยก็ตามตัวอย่างครับ: 26 | 27 | echo Form::open(array('route' => array('route.name', $user->id))) 28 | 29 | echo Form::open(array('action' => array('Controller@method', $user->id))) 30 | 31 | ถ้าจะสร้างฟอร์มมาอัพโหลดไฟล์ก็ต้องตั้งค่าแบบตัวอย่างครับ `files` 32 | 33 | echo Form::open(array('url' => 'foo/bar', 'files' => true)) 34 | 35 | 36 | ## การป้องกัน CSRF 37 | 38 | Laravel เตรียมการป้องกันโดยสร้างค่า hash ขึ้นจาก session ของ user แล้วสร้าง hidden form ขึ้นมาใส่ไว้ เราเพียงแต่ใช้เมทอด `token`ประกาศไว้ก็เสร็จเเล้วครับ 39 | 40 | **ตัวอย่าง** 41 | 42 | echo Form::token(); 43 | 44 | **การป้องกัน csrf จากใน route** 45 | 46 | Route::post('profile', array('before' => 'csrf', function() 47 | { 48 | // 49 | })); 50 | 51 | 52 | ## การดึงค่าจากตารางมาใส่ในฟอร์ม 53 | 54 | laravel เตรียมเมทอด `Form::model` มาเพื่อการนั้นครับ 55 | 56 | **ตัวอย่าง** 57 | 58 | echo Form::model($user, array('route' => array('user.update', $user->id))) 59 | 60 | ถ้าชื่อของคอลัมน์ตรงกับ ชื่อของฟอร์มค่าก็จะปรากฏมาโดยอัติโนมัติ อย่างเช่นฟอร์มชื่อ `email`,ตรงกับโมเดลชื่อ `email` แต่ค่าที่จะปรากฏบนฟอร์มไม่ได้มีแค่ค่าที่มาจากโมเดลอย่างเดียว มีจาก session ค่าที่มาจากการส่งพารามิเตอร์อีก ลำดับการแสดงค่าจึงตามข้างล่างนี้ครับ 61 | 1. ค่าจาก Session (ค่าเก่าที่เกิดจาการป้อน) 62 | 2. ค่าจากการส่งพารามิเตอรื 63 | 3. ค่าจากโมเดล 64 | 65 | ซึ่งเมื่อ server ส่งค่าการตรวจสอบค่าที่ป้อนมาว่าผิดพลาด ค่าที่ส่งมาจากโมเดลก็จะตามกลับขึ้นมาด้วย 66 | 67 | > **หมายเหตุ:** เมือใช้ `Form::model`อย่าลืม `Form::close`! 68 | 69 | 70 | ## การใส่ป้ายชื่อ 71 | 72 | **การใส่ป้ายชื่อให้ฟอร์ม** 73 | 74 | echo Form::label('email', 'E-Mail Address'); 75 | 76 | **การใส่คลาสให้ฟอร์ม** 77 | 78 | echo Form::label('email', 'E-Mail Address', array('class' => 'awesome')); 79 | 80 | > **หมายเหตุ:** หลังจากใส่ค่า label ชื่อฟอร์ม ค่า id ก็จะตั้งตามค่า label โดยอัติโนมัติ. 81 | 82 | 83 | ## Text, Text Area, Password & Hidden Fields 84 | 85 | 86 | **ตัวอย่างฟอร์มที่ใช้รับค่า** 87 | 88 | echo Form::text('username'); 89 | 90 | **กำหนดค่าเริ่มต้นให้ฟอร์ม** 91 | 92 | echo Form::text('email', 'example@gmail.com'); 93 | 94 | > **หมายเหตุ:** *hidden* และ *textarea* ฟังก์ชันใช้งานเหมือน *text* เมทอด 95 | 96 | **สร้างฟอร์มรับรหัสผ่าน** 97 | 98 | echo Form::password('password'); 99 | 100 | **สร้างฟอร์มชนิดอื่น** 101 | 102 | echo Form::email($name, $value = null, $attributes = array()); 103 | echo Form::file($name, $attributes = array()); 104 | 105 | 106 | ## Checkboxes and Radio Buttons 107 | 108 | **สร้างฟอร์มชนิดเลือกค่า** 109 | 110 | echo Form::checkbox('name', 'value'); 111 | 112 | echo Form::radio('name', 'value'); 113 | 114 | **สร้างฟอร์มชนิดเลือกค่าโดยค่าเริ่มต้นคือเลือกไว้เเล้ว** 115 | 116 | echo Form::checkbox('name', 'value', true); 117 | 118 | echo Form::radio('name', 'value', true); 119 | 120 | 121 | ## File Input 122 | 123 | **สร้างฟอร์มอัพโหลดไฟล์** 124 | 125 | echo Form::file('image'); 126 | 127 | 128 | ## Drop-Down Lists 129 | 130 | **สร้างฟอร์มให้เลือกค่าแบบดรอบดาวน์** 131 | 132 | echo Form::select('size', array('L' => 'Large', 'S' => 'Small')); 133 | 134 | **สร้างฟอร์มชนิดเลือกค่าแบบดรอบดาวน์โดยค่าเริ่มต้นคือเลือกไว้เเล้ว** 135 | 136 | echo Form::select('size', array('L' => 'Large', 'S' => 'Small'), 'S'); 137 | 138 | **แบ่งกลุ่มให้ตัวเลือก** 139 | 140 | echo Form::select('animal', array( 141 | 'Cats' => array('leopard' => 'Leopard'), 142 | 'Dogs' => array('spaniel' => 'Spaniel'), 143 | )); 144 | 145 | 146 | ## Buttons 147 | 148 | **สร้างปุ่มส่งค่า** 149 | 150 | echo Form::submit('Click Me!'); 151 | 152 | > **หมายเหตุ:** ถ้าจะสร้างปุ่มธรรมดาก็ใช้ button 153 | 154 | 155 | ## Custom Macros 156 | 157 | macro คือชุดของ html ที่เราเขียนเตรียมไว้ สามารถนำเอาไปแทรกตามใจเราได้ 158 | 159 | **การสร้าง Form Macro** 160 | 161 | Form::macro('myField', function() 162 | { 163 | return ''; 164 | }); 165 | 166 | 167 | **เรียก Form Macro มาใช้** 168 | 169 | echo Form::myField(); 170 | -------------------------------------------------------------------------------- /installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | การติดตั้ง laravel 3 | 4 | 5 | ## Install Composer 6 | 7 | Laravel ใช้ [Composer](http://getcomposer.org) ในการจัดการไลบราลี่ต่างๆ รวมจนถึงคลาสหลักของระบบ เริ่มแรกเราต้องไปโหลด `composer.phar`. เราจะได้ไฟล์ที่มีนามสกุลเป็น phar มาแล้วเอาไปวางไว้ที่ `usr/local/bin` เพื่อให้ระบบมองเห็น บนวินโดเรามี [Windows installer](https://getcomposer.org/Composer-Setup.exe) อยากรู้เพิ่มเติมเข้าไปดูได้[บล็อก](http://taqmaninw.com/ccomposer-ผู้กอบกู้แห่งอาณาจักร-php)ของผมได้ครับ 8 | 9 | 10 | ## การติดตั้ง Laravel 11 | 12 | ### ใช้ Composer ในการติดตั้ง 13 | 14 | พิมพ์คำสั่งข้างล่างไปที่ commandline composer จะทำการดาวน์โหลดมาลงตรงที่เราเรียกใช้ 15 | 16 | composer create-project laravel/laravel 17 | 18 | ### ดาวน์โหลดเอง 19 | 20 | เมื่อติดตัง [laravel เวอร์ชันล่าสุด](https://github.com/laravel/laravel/archive/master.zip) แล้วก็แตกไฟล์ไปลงที่โฟลเดอร์ของ server เปิด command line เลือกที่อยู่ให้ตรงกับที่เอา laravel ไปวางแล้วรันคำสั่ง `php composer.phar install` (หรือ `composer install`) ก็เสร็จสิ้น 21 | 22 | ถ้าเราต้องการอัพเดทก็ใช้คำสั่ง `php composer.phar update` 23 | 24 | 25 | ## ความต้องการของระบบ 26 | 27 | - PHP >= 5.3.7 28 | - MCrypt PHP Extension 29 | 30 | 31 | ## การตั้งค่า 32 | 33 | laravel ไม่ได้ต้องการปรับแต่งอะไรมากเพียงแค่เราเข้้าไปที่ `app/config/app.php` โดยอาจปรับแค่ `timezone` กับ `locale` 34 | 35 | > **Note:** และมีค่า `key` ที่อยู่ใน `app/config/app.php`. เราต้องใช้คำสั่ง `php artisan key:generate`เพื่อสร้างคีย์ที่จะใช้สร้าง private key ในการสร้างรหัสผ่าน hash ในระบบ 36 | 37 | 38 | ### สิทธิ 39 | laravel ต้องการสิทธิในการอ่านเขียนโฟลเดอร์ app/storage 40 | 41 | 42 | ### เส้นทาง 43 | 44 | การกำหนดเส้นทางสามารถทำได้ที่ `bootstrap/paths.php` 45 | 46 | 47 | 48 | ## URLs ที่สวยงาม 49 | 50 | laravel เตรียมไฟล์ `public/.htaccess` ที่อนุญาตให้เราเรียกใช้งานโดยไม่ต้องใส่ `index.php`. โดยต้องการใช้งานขอ `mod_rewrite` บน server ก่อน 51 | 52 | -------------------------------------------------------------------------------- /introduction.md: -------------------------------------------------------------------------------- 1 | # แนะนำตัวกันก่อน 2 | 3 | 4 | ## ปรัชญาของ Laravel 5 | 6 | Laravel เป็น php framework ที่เน้นไปที่ความเรียบง่ายของการใช้งานตัวแปรต่างๆ . เราเชื่อว่าในการพัฒนาเว็บของคุณต้องเต็มไปด้วยความสนุกสนานแน่นอน,ประสบการณ์ความคิดสร้างสรรค์ที่จะตอบสนองความต้องการอย่างแท้จริง. Laravel พยายามลดงานในระหว่างการพัฒนาโดยสร้างระบบสำเร็จรูปมาให้อย่าง authentication, routing, sessions, และ caching. 7 | 8 | Laravel ที่จะเป็นหนึ่งใน เครื่องมือในการพัฒนาที่นักพัฒนาชื่นชอบ และสามารถใช้งานได้โดยที่ไม่ต้องเสียสละฟังก์ชันไหนไปเลย 9 | เราเชื่อว่า นักพัฒนาที่มีความสุขจะสร้างโค้ดที่เยี่ยมยอด เราพยายามนำสิ่งที่ดีของภาษาอื่นๆ เช่น Ruby on Rails, ASP.NET MVC, และ Sinatra เข้ามาผสมผสานเข้ากับ laravel 10 | 11 | Laravel เตรียมเครื่องมือที่ใช้เพื่อการสร้างเว็บแอพลิเคชัน ที่ยืดหยุ่นด้วย inversion of control container,ระบบ migration , และการทำ unit testing ที่แสนง่ายดาย 12 | 13 | 14 | ## เรียนรู้ Laravel 15 | 16 | หนึ่งในทางเลือกที่ดีคือการศึกษาคู่มือการใช้งาน หรือซื้อหนังสือในนี้ครับ 17 | 18 | - [Code Bright](https://leanpub.com/codebright) by Dayle Rees 19 | - [Laravel Testing Decoded](https://leanpub.com/laravel-testing-decoded) by Jeffrey Way 20 | - [Laravel From Aprentice to Artisan](https://leanpub.com/laravel) by Taylor Otwell 21 | 22 | 23 | ## นักพัฒนาหลัก 24 | 25 | Laravel ถูกสร้างโดย [Taylor Otwell](https://github.com/taylorotwell), และ [Dayle Rees](https://github.com/daylerees), [Shawn McCool](https://github.com/ShawnMcCool), [Jeffrey Way](https://github.com/JeffreyWay), [Jason Lewis](https://github.com/jasonlewis), [Ben Corlett](https://github.com/bencorlett), [Franz Liedke](https://github.com/franzliedke), [Dries Vints](https://github.com/driesvints), [Mior Muhammed Zaki](https://github.com/crynobone), และ [Phil Sturgeon](https://github.com/philsturgeon). 26 | 27 | 28 | ## ผู้สนับสนุน Laravel 29 | 30 | 31 | - [UserScape](http://userscape.com) 32 | - [Cartalyst](http://cartalyst.com) 33 | - [Elli Davis - Toronto Realtor](http://ellidavis.com) 34 | - [Jay Banks - Vancouver Lofts & Condos](http://jaybanks.ca/vancouver-lofts-condos) 35 | - [Julie Kinnear - Toronto MLS](http://juliekinnear.com/toronto-mls-listings) 36 | - [Jamie Sarner - Toronto Real Estate](http://jamiesarner.com) 37 | -------------------------------------------------------------------------------- /ioc.md: -------------------------------------------------------------------------------- 1 | # IoC Container 2 | 3 | 4 | ## Introduction 5 | >หมายเหตุ :: ถ้าใครยังไม่ค่อยเข้าใจว่าสองตัวนี้มันคืออะไรลองไปอ่านที่ผมสรุปไว้[ที่นี้](http://taqmaninw.com/inversion-of-control-กับ-dependency-injection-คืออะไร/)ก่อนครับ 6 | 7 | IOC คือคลาสที่ใช้ในการจัดการ `library` ภายนอกที่เรานำเข้ามาใช้ หรือที่ดึงเข้ามาใช้โดย `composer `ต่อไปนี้จะเรียกย่อๆว่า IOC นะครับ 8 | IOC จะช่วยในการเรียกใช้งานคลาสต่าง การทำความเข้าใจ IOC ถือว่าเป็นหัวใจ เลยในการปูทางสู่การทำเว็บขนาดใหญ่สำหรับ 9 | laravel นะครับ เพราะหลักการนี้จะเกี่ยวโยงไปถึงเรื่อง `Service Provider` กับ `Facade` 10 | 11 | 12 | ## การใช้งานเบื้องต้น 13 | 14 | 15 | **การใช้งาน IOC ในการผูก object** 16 | 17 | App::bind('foo', function($app) 18 | { 19 | return new FooBar; // 20 | }); 21 | ง่ายคือต่อไปนี้พารามิเตอร์ชื่อ foo จะใช้เป็นตัวแทนของ class FooBar ที่ถูกสร้างเป็นวัตถุแแล้ว 22 | 23 | **การเรียกใช้งาน** 24 | 25 | $value = App::make('foo'); 26 | 27 | เมื่อเราเรียกใช้งาน `App::make` เมทอด ฟังก์ชันข้างบนก็จะถูกเรียกใช้งาน ตัวแปร value 28 | ก็จะรับคุณสมบัติต่างๆ ของคลาส FooBar เข้ามา 29 | 30 | บางครั้งเราไม่ต้องการสร้าง `instane` ทุกครั้งที่รีเฟรช laravel มีฟังก์ชัน singleton มาให้ใช้ในการนี้เลยครับ 31 | 32 | **ตัวอย่างการใช้งาน** 33 | 34 | App::singleton('foo', function() 35 | { 36 | return new FooBar; 37 | }); 38 | 39 | ถ้าไม่ต้องการจัดเพิ่มเข้าไปทั้งคลาสจะยัดเข้าไปเป็นออปเจ็คก็ใช้ฟังก์ชัน `instance` ได้เลยครับ 40 | 41 | **ตัวอย่างการผูกออปเจคเข้าไป** 42 | 43 | $foo = new Foo; 44 | 45 | App::instance('foo', $foo); 46 | 47 | 48 | ## Automatic Resolution 49 | 50 | ตัวอย่างการผูกคลาสอย่างรวดเร็วขึ้นโดยไม่ต้องใช้ `App::bind` แล้วแต่ขอให้ชื่อตรงกันก็พอ 51 | 52 | **ตัวอย่าง** 53 | 54 | class FooBar { 55 | 56 | public function __construct(Google $baz) 57 | { 58 | $this->baz = $baz; 59 | } 60 | 61 | } 62 | 63 | $fooBar = App::make('FooBar'); 64 | 65 | ในตัวอย่างนี้ ตัวแปร $foofBar จะเก็บค่าคลาส `Google` ที่ถูกแทรกเข้ามา 66 | 67 | laravel จะทำการเรียกใช้ [reflection class](http://taqmaninw.com/Reflection-class-คืออะไร) ของ php เพื่อทำการตรวจสอบค่าต่างๆ ในคลาสนั้นให้เองครับ 68 | บางกรณีคลาสที่เราจะใช้งานดันไปดึงคลาสที่เป็น interface เข้ามาใช้ด้วย เพื่อการนั้นเราต้องใช้ `App::bind` เมทอด ในการผูก ดังตัวอย่าง 69 | 70 | **ตัวอย่างการผูก class ที่เป็นเรียกใช้งาน interface** 71 | 72 | App::bind('UserRepositoryInterface', 'DbUserRepository'); 73 | 74 | คลาสที่เราเรียกใช้งาน 75 | 76 | class UserController extends BaseController { 77 | 78 | public function __construct(UserRepositoryInterface $users) 79 | { 80 | $this->users = $users; 81 | } 82 | 83 | } 84 | 85 | ตอนนี้ `UserRepositoryInterface` จะถูกเรียกใช้งานแล้ว 86 | 87 | ## การประยุกต์ใช้งาน 88 | 89 | เพื่อความยืดหยุ่นในการทดสอบและใช้งาน Laravel เตรียมการให้เราใช้งาน IOC ไในหลายกรณีเลยครับ 90 | 91 | **ตัวอย่างการเรียกใช้งาน Class OrderRepository** 92 | 93 | class OrderController extends BaseController { 94 | 95 | public function __construct(OrderRepository $orders) 96 | { 97 | $this->orders = $orders; 98 | } 99 | 100 | public function getIndex() 101 | { 102 | $all = $this->orders->all(); 103 | 104 | return View::make('orders', compact('all')); 105 | } 106 | 107 | } 108 | 109 | ในตัวอย่างคลาส `OrderRepository` แทรกเข้าไปโดยอัติโนมัติเมื่อ คลาส `OrderController` ทำงาน เมื่อมีการทำ [unit testing](/docs/testing) คลาส `OrderRepository` ก็จะถูกเพิ่มเข้ามาเหมือนกัน 110 | 111 | [Filters](/docs/routing#route-filters), [composers](/docs/responses#view-composers), และ [event handlers](/docs/events#using-classes-as-listeners) อยู่นอกเหนือการทำงานของ IoC container เมื่อเราจะใช้ต้องทำตามตัวอย่างครับ 112 | 113 | **การใช้งาน View::composer,Route::filter และ Event::listen กับ IOC** 114 | 115 | Route::filter('foo', 'FooFilter'); 116 | 117 | View::composer('foo', 'FooComposer'); 118 | 119 | Event::listen('foo', 'FooHandler'); 120 | 121 | 122 | ## Service Providers 123 | 124 | Service providers เป็นการจับคลาส IOC ที่ทำงานคล้ายกันเข้ามาไว้ในที่เดียวกัน. 125 | แล้วเรียกใช้งาน ด้วย facade 126 | โดยหลักเเล้วทุกคลาสหลักของ laravel ใช้การทำ service provider ในการจัดการเราสามารถเข้าไปดูได้ตรงที่ตัวแปรอาเรย์ `providers` ตรงที่`app/config/app.php` 127 | 128 | จะสร้าง Service Provider ขึ้นมาใช้กับคลาสของเราเริ่มแรกต้องดึงคลาส `Illuminate\Support\ServiceProvider` และประกาศเมทอด `register` 129 | 130 | **ตัวอย่างการสร้าง Service Provider** 131 | 132 | use Illuminate\Support\ServiceProvider; 133 | 134 | class FooServiceProvider extends ServiceProvider { 135 | 136 | public function register() 137 | { 138 | $this->app->bind('foo', function() 139 | { 140 | return new Foo; 141 | }); 142 | } 143 | 144 | } 145 | 146 | ในเมทอด `register` คลาส IOC จะเป็นตัวแปร `$this->app` ถ้าเราทำเสร็จแล้วก็ต้องเอาเส้นทางที่อยู่ของคลาส Provider ของเราไปเพิ่มในอาเรย์ `providers` ใน `app.php` ด้วย 147 | 148 | การเรียกใช้งาน Service Provider ด้วยเมทอด `App::register` 149 | 150 | **ตัวอย่าง** 151 | 152 | App::register('FooServiceProvider'); 153 | 154 | 155 | ## Container Events 156 | 157 | ใน IOC ก็มี event อยู่ชื่อเมทอดว่า `resolving` 158 | 159 | **การใช้งาน resoliving เพื่อรอดูว่ามี IOC ตัวไหนทำงานบ้าง** 160 | 161 | App::resolving(function($object) 162 | { 163 | // 164 | }); 165 | 166 | -------------------------------------------------------------------------------- /lifecycle.md: -------------------------------------------------------------------------------- 1 | ## Laravel Lifecycle 2 | 3 | ### ตอนที่ 1 Autoloading 4 | มาดูวัฏจักรการทำงานของ Laravel กันครับ มีอยู่ด้วยกัน 4 ช่วง `Autoloading,Bootstrap,Application,Run` เริ่มที่ `Autoloading `ก่อนครับ 5 | 6 | 7 | 1. เริ่มจากไฟล์ `index.php` ครับ ช่วงที่เราตั้งค่า `vhost `เราจะตั้งให้เส้นทางที่เข้าถึงเริ่มแรก คือ `/public/` พอเริ่มเข้าถึงไฟล์ `index.php` ทำการเรียกไฟล์ `autoload.php` จากโฟลเดอร์ `bootstrap` 8 | 9 | 1. ในไฟล์ `autoload.php` จะทำการตั้งค่าเวลาที่ตัวเว็บเริ่มทำงาน 10 | ![](http://resource.thaicreate.com/upload/stock/20130712081741.jpg?v=1001) 11 | 12 | 13 | 14 | 15 | 16 | 1. จากนั้นเราจะ เรียกไฟล์ `autoload.php` จากโฟลเดอร์ `vendor` ขึ้นมา 17 | ![](http://resource.thaicreate.com/upload/stock/20130712081817.jpg?v=1001) 18 | 19 | 20 | 21 | 1. ที่เห็นชื่อยาวขนาดนี้เป็นเพราะถูกสุมมาจากการที่ใช้คำสั่ง`artisan dump autoload `เพื่อสร้าง รายชื่อของ `package` ใหม่นะครับ แต่ก่อนหน้านั้นเราจะทำการโหลดไฟล์ `package` ทั้งหมดก่อน 22 | โดยเรียกไฟล์ `autoload_real.php` ขึ้นมา 23 | ![](http://resource.thaicreate.com/upload/stock/20130712081839.jpg?v=1001) 24 | 25 | 26 | 27 | 1. ต่อมาใน ไฟล์ `vendor/composer/autoload_real.php` จะทำการเรียกไฟล์ `Classloader` มาทำการสร้างเป็นวัตถุชื่อ `$loader` แล้วก็ 28 | ![](http://resource.thaicreate.com/upload/stock/20130712081857.jpg?v=1001) 29 | 30 | 31 | 1. เรียกไฟล์ `autoload_classmap` กับ `autoload_namespace`ขึ้นมาซึ่งในไฟล์ `autoload_classmap` จะเป็นรายชื่อของไฟล์ `package` ทั้งหมดที่อยู่ในโฟลเดอร์ `vendor` ส่วนในไฟล์ `autoload_namespace` จะเป็นรายชื่อของตัว `namespace ` ที่ใช้เรียก `root path` ของไฟล์ `package` นั้นครับ 32 | ![](http://resource.thaicreate.com/upload/stock/20130712082030.jpg?v=1001) 33 | 34 | 35 | 36 | 1. พอเรียกเสร็จก็จะส่งกลับมาที่ ไฟล์ `autoload` แล้วก็ส่งค่าต่อไปให้ `ClassLoader` ของ `laravel` 37 | ![](http://resource.thaicreate.com/upload/stock/20130712082241.png?v=1001) 38 | 1. ตามลงมาดูว่า `Classloader`ของ `laravel` มันทำยังไงต่อนะครับ 39 | ฟังก์ชัน `register`ทำการเรียกใช้ ฟังก์ชัน `load ` 40 | ![](http://resource.thaicreate.com/upload/stock/20130712082325.png?v=1001) 41 | 42 | 43 | 44 | 1. ฟังก์ชัน `load`จะทำการเรียกโฟลเดอร์ `package` ที่มีตามรายชื่อในตัวแปร `class`ที่ส่งมาตอนแรก 45 | ![](http://resource.thaicreate.com/upload/stock/20130712082739.png?v=1001) 46 | 47 | 48 | 49 | 1. เท่านี้ก็เสร็จการโหลด `package` ในโฟลเดอร์ `vendor` ครับ อะแต่ยังไม่หมดนะครับ ยังเหลือ package ที่โฟลเดอร์ workbench เรียกใช้คลาส `Starter`เพื่อทำการลงทะเบียน `package` ในโฟลเดอร์ `workbench` 50 | ![](http://resource.thaicreate.com/upload/stock/20130712082901.jpg?v=1001) 51 | 52 | โฟลเดอร์ workbech คือส่วนที่เราใช้ในการพัฒนา package ในเครื่องเราซึ่งยังไม่เสร็จหรือว่าทำขึ้นใช้เอง เราก็จะมาเริ่มต้นจากตรงนี้ 53 | 54 | package ถือว่าเป็นส่วนสำคัญที่จะต้องรู้ก่อนใน laravel 4 นี้เลย การเขียน package เป็นจะทำให้เราเลือก php libraly ตัวไหนก็ได้บน packagist.org ซึ่งเป็นศูนย์รวมของ libraly ของ php ที่ใช้มาตรฐาน psr-0,psr-1,psr-2 มาสร้างเป็น pakage ใช้เอง ซึ่งผมก็ได้ศึกษาแล้วลองทำไปเเล้วหลายตัวครับ ไว้จบเรื่องนี้ เเล้วจะมาขียนเรื่องการสร้าง package ต่อครับ 55 | 56 | ปล.ตัวแปร Laravel_Start ตอนแรกเราสามารถนำไปใช้ ลบกับค่าเวลาปัจจุบันเพื่อหาเวลาที่เว็บใช้ จัดการคำร้องขอ 57 | 58 | 59 | ---------- 60 | 61 | ### ตอนที่ 2 Application 62 | 63 | 64 | 65 | 1. ขั้นตอนนี้จะเป็นการเริ่มสร้างตัวออปเจคหลักของ เว็บกันแล้วนะครับ 66 | เริ่มจากไฟล์ `bootstrap/start.php` เราจะดำดิ่งลงไปดูในคลาส ` Application` 67 | ![](http://resource.thaicreate.com/upload/stock/20130718073801.png?v=1001) 68 | ตรงคลาสนี้เป็นตัวหลักที่คอยขับเคลื่อนเว็บไซต์ของเราเลยครับ เพราะ มีการเรียกใช้ คลาสเข้ามาจำนวนมาก 69 | ฟังก์ชันในนี้ ผมจะไม่พยายามไปดูให้ตาลาย ให้รู้ว่าเรา มีฟังก์ชันที่เราต้องเข้าใจ คือ 70 | `App::share,App::bind,App::instance,App::make` เราไปดูต่อว่าเริ่มมาตัว `class Application`ทำอะไรต่อ 71 | 72 | 1. เนื่องจาก ทำการเรียกตัวคลาสเข้ามาแล้ว จึงทำการสร้างวัตถุใหม่ได้ทันทีเลยครับ สิ่งที่ต้องสร้างก่อนสามอันดับแรกเลยก็คือ `Class Exception` ใช้ในการจัดการข้อผิดพลาด 73 | `Class Routing` จัดการๆวิ่งของคำร้องขอ 74 | `Class Event` จัดการเหตุการณ์ต่าง ที่เกิดขึ้น 75 | ![](http://resource.thaicreate.com/upload/stock/20130718073947.png?v=1001) 76 | 77 | 1. กลับมาที่ ไฟล์ `start.php` ครับ ขั้นต่อมา เราจะทำการตรวจสถานะการทำงานของระบบนะครับ 78 | ว่าอยู่ในโหมดไหน ตรงนี้มีประโยชน์มากในกรณีเมื่อเรากำลังพัฒนาอยู่ก็ตั้งให้เป็น `development` ส่วนจะไปกำหนดที่ไหนค่อยมาพูดกันอีกทีครับ 79 | ![](http://resource.thaicreate.com/upload/stock/20130718074104.png?v=1001) 80 | 81 | 1. ทำการโหลดไฟล์ `path.php` ซึ่งจะเป็น `class `ใช้ในการกำหนดเส้นทางการเข้าหาโฟลเดอร์ต่างๆ 82 | ![](http://resource.thaicreate.com/upload/stock/20130718074232.png?v=1001) 83 | 84 | 1. ทำการเรียกใช้งานตัว `laravel` ละครับตรงนี้จะเป็นการ เรียกไฟล์ `start` ของตัว `laravel` ขึ้นมา 85 | ![](http://resource.thaicreate.com/upload/stock/20130718074344.png?v=1001) 86 | 87 | ---------- 88 | 89 | ### ตอนที่ 3 Bootstrap 90 | 91 | 1. laravel เริ่มการตรวจว่ามีการติตตั้ง `Mcrypt` ไหม 92 | ![](http://i.imgur.com/ptIiszw.png) 93 | 94 | 1. ต่อมาก็ตรวจสภาวะการตั้งค่าก่อนว่าเรากำลัง ตั้งให้อยู่ในสถานะการทอบสอบไหม 95 | ![](http://i.imgur.com/ZAvlT5S.png) 96 | 97 | 1. คลาส `Facade` จะทำการเคลียร์ ตัวแทนของมัน 98 | แล้วก็สร้างขึ้นใหม่ 99 | ![](http://i.imgur.com/iUA5IwB.png) 100 | 101 | 1. ทำการโหลดข้อมูลการตั้งค่าจากตัวแปร `$env` ขึ้นมาใส่ให้คลาส `Config` ครับ แล้วสร้างตัวแทนให้คลาส `Config` 102 | ![](http://i.imgur.com/xDX8G4H.png) 103 | 104 | 1. ทำการตั้งค่าวันเวลาโดยโหลดค่ามาจากตัวแปรในไฟล์ `app.php` 105 | ![](http://i.imgur.com/Ltc5Oyz.png) 106 | 107 | 1. โหลดค่าชื่อย่อจากที่ไฟล์ `app.php` มา 108 | ![](http://i.imgur.com/ZV5D44o.png) 109 | 110 | มาให้ฟังก์ชัน `getInstance` มาทำการลงทะเบียนไว้ 111 | ![](http://i.imgur.com/Ir4ihzX.png) 112 | 113 | 1. ทำการอนุญาตให้ใช้คำร้องขอชนิด `put` ใช้ทำการแก้ไขข้อมูล กับ `delete` ใช้ในการลบข้อมูล เพื่อใช้ตอนทำ `restful` ในกรณีที่ `firewall` ไม่อนุญาตุให้เมทอดสองอันนี้ผ่าน เราจึงจำเป็นต้องทำการเปลี่ยนส่วนหัวของเมทอด `post` ให้กลายเป็นสองเมทอดที่โดนบล็อก 114 | ![](http://i.imgur.com/mQlXv2q.png) 115 | 116 | 1. ทำการวมคลาสทุกตัวที่โหลดมาเข้าด้วยกัน `$config['providers']` คือรายชื่อคลาสที่อยู่ในไฟล์ `app.php` 117 | ![](http://i.imgur.com/ulQDYrx.png) 118 | 119 | 1. เรียกใช้ฟังก์ชัน `$app->boot()` เพื่อเริ่มต้นการทำงาน เเล้วเรียกไฟล์ `global.php` ซึ่งเป็นไฟล์ที่เราสามารถใช้กำหนดค่าเริ่มต้นเองได้ 120 | ![](http://i.imgur.com/atM8b1g.png) 121 | 122 | 1. รองสุดท้ายดึงไฟล์ที่เราใช้กำหนดสภาวะการตั้งค่าขึ้นมา 123 | ![](http://i.imgur.com/w6HpkVH.png) 124 | 125 | 1. สุดท้ายในบทนี้แล้วครับเรียกไฟล์ `routes.php` จบตอนครับ 126 | 127 | 128 | ### ตอนที่ 4 Run 129 | ตอนสุดท้ายแล้วครับ เราใกล้ได้คำตอบกลับหรือ `Response` 130 | 131 | 132 | 1. ทำการเขียน `session` 133 | 1. ค้นหา `Route` ที่ส่งมาว่าตรงกับตัวที่่กำหนดไว้ไหม 134 | 1. สั่งให้ `filter` เช่น `before`,`after` ทำงาน 135 | 1. สร้างคำตอบกลับหรือ `Response` 136 | 1. ส่งคำตอบกลับ 137 | 1. เรียกใช้ `after filter` อย่างเช่น `log` 138 | 139 | จบแล้วครับกว่าจะได้คำตอบกลับหนึ่งครั้งยาวนานไหมครับ 140 | 141 | ที่มา :: [Kenny Mayer Per Your Request](http://www.youtube.com/watch?v=bRyOrtCim70 ) -------------------------------------------------------------------------------- /localization.md: -------------------------------------------------------------------------------- 1 | # Localization 2 | 3 | 4 | ## แนะนำ 5 | 6 | คลาส `Lang` จะทำหน้าที่แปลภาษาในเบื้องต้นให้กับเมนูหรือป้ายกำหับต่างๆ ในเว็บของเรา 7 | 8 | 9 | ## ไฟล์ที่เก็บข้อมูลภาษา 10 | 11 | ถูกเก็บไว้ที่โฟลเดอร์ `app/lang` โดยโครงสร้างจะเป็นแบบนี้ 12 | 13 | /app 14 | /lang 15 | /en 16 | messages.php 17 | /es 18 | messages.php 19 | 20 | ไฟล์ที่เก็บภาษาจะเก็บในรูปแบบอาเรย์: 21 | 22 | **ตัวอย่างของไฟล์ภาษา** 23 | 24 | 'Welcome to our application' 28 | ); 29 | 30 | โดยค่าเริ่มต้นเเล้ว ค่าภาษาจะถูกกำหนดไว้ที่ `app/config/app.php` แต่ถ้าจะตั้งเราจะตั้งแบบไม่ให้คลุมไปทั้งเว็บก็ใช้เมทอด `App::setLocale` 31 | 32 | **ตัวอย่าง** 33 | 34 | App::setLocale('es'); 35 | 36 | 37 | ## การใช้งานเบื้องต้น 38 | 39 | **การดึงค่าจากไฟล์ภาษา** 40 | 41 | echo Lang::get('messages.welcome'); 42 | 43 | ฟังก์ชัน `get` ใช้ดึงค่าโดยมีพารามิเตอร์คือชื่อภาษาและแถวที่ต้องการดึง 44 | 45 | 46 | 47 | **การส่งพารามิเตอร์ไป** 48 | 49 | พารามิเตอร์ที่สองจะใช้รับค่าที่จะส่งมา 50 | 51 | 'welcome' => 'Welcome, :name', 52 | 53 | ตัวอย่างการใช้งาน 54 | 55 | echo Lang::get('messages.welcome', array('name' => 'Dayle')); 56 | 57 | **ตรวจว่าในไฟล์ภาษามีคอลัมน์นี้อยู่** 58 | 59 | if (Lang::has('messages.welcome')) 60 | { 61 | // 62 | } 63 | 64 | 65 | ## Pluralization 66 | 67 | Pluralization คือโครงสร้างไวยากรณ์ของแต่ละภาษาที่มีความแตกต่างกัน แต่เราใช้เครื่องหมาย ในการสร้างตัวเลือกระหว่างเอกพจน์กับพหูพจน์: 68 | 69 | 'apples' => 'There is one apple|There are many apples', 70 | 71 | เเล้วเราก็ใช้ฟังก์ชัน `Lang::choice` ในการเลือก 72 | 73 | echo Lang::choice('messages.apples', 10); 74 | 75 | เนื่องจากการแปลภาษาของ laravel สืบทอดมาจากของ Symfony เราจึงสามารถสร้างเงื่อนไขที่ซับซ้อนดังตัวอย่างได้ 76 | 77 | 'apples' => '{0} There are none|[1,19] There are some|[20,Inf] There are many', 78 | -------------------------------------------------------------------------------- /mail.md: -------------------------------------------------------------------------------- 1 | # Mail 2 | 3 | 4 | ## การตั้งค่า 5 | 6 | Laravel นำไลบราลี่ [SwiftMailer](http://swiftmailer.org) มาใช้งาน การตั้งค่าอยู่ที่ `app/config/mail.php`,โดยจะให้เราเปลี่ยน SMTP host, port, และ username กับ password, แล้วก็ค่า `from` คือค่าเริ่มต้นของชื่อผู้รับ. ถ้าเราต้องการใช้ไลบรารี `php mail` ในการส่งก็เพียงเปลี่ยน `driver` เป็น `mail` 7 | 8 | 9 | ## การใช้งานเบื้องต้น 10 | 11 | ฟังก์ชัน `Mail::send` ใช้ในการส่งอีเมล์ 12 | 13 | Mail::send('emails.welcome', $data, function($message) 14 | { 15 | $message->to('foo@example.com', 'John Smith')->subject('Welcome!'); 16 | }); 17 | 18 | เมทอด `send` ตัวแปรแรกคือไฟล์ html ที่เป็นรูปแบบข้อมความในเมล์. ตัวที่สองคือข้อมูลที่จะเขียนลงเมล์ `$data` ซึ่งจะถูกส่งไปยัง view ตัวที่สามเป็นฟังก์ชันที่ใช้กำหนดค่าต่างๆของอีเมล์ 19 | 20 | > **Note:** ตัวแปร `$message` คือออปเจ็คของตัว Swiftmailer class ซึ่งเราจะใช้กำหนดค่าต่างๆของเมล์ 21 | 22 | 23 | Mail::send(array('html.view', 'text.view'), $data, $callback); 24 | 25 | ตัวอย่างคือเราเลือกที่จะส่งไปในรูปแบบใด `html` หรือ `text` 26 | 27 | Mail::send(array('text' => 'view'), $data, $callback); 28 | 29 | ตัวอย่างการปรับแต่งเนื้อหาภายในเมล์: 30 | 31 | Mail::send('emails.welcome', $data, function($message) 32 | { 33 | $message->from('us@example.com', 'Laravel'); 34 | 35 | $message->to('foo@example.com')->cc('bar@example.com'); 36 | 37 | $message->attach($pathToFile); 38 | }); 39 | 40 | เมื่อจะทำการแนบไฟล์เราต้องใส่นามสกุลกับชื่อให้มันด้วย: 41 | 42 | $message->attach($pathToFile, array('as' => $display, 'mime' => $mime)); 43 | 44 | 45 | 46 | ## การแทรกไฟล์ไว้ระหว่างบรรทัด 47 | 48 | เราสามารถแนบรูปไปโดยไม่ให้เเสดงได้โดยใช้ฟังก์ชัน `embed` 49 | 50 | **ตัวอย่างการใช้งาน** 51 | 52 | 53 | Here is an image: 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | ## เรียงลำดับการส่งอีเมล์ 63 | 64 | Laravel เตรียมคลาส [Queue](/docs/queues) มาให้เราใช้ในการเรียงลำดับการส่งอีเมล์ 65 | 66 | **ตัวอย่าง** 67 | 68 | Mail::queue('emails.welcome', $data, function($message) 69 | { 70 | $message->to('foo@example.com', 'John Smith')->subject('Welcome!'); 71 | }); 72 | 73 | เราสามารถหน่วงเวลาการส่งโดยใช้ฟังก์ชัน `later` ตามตัวอย่างครับ 74 | 75 | Mail::later(5, 'emails.welcome', $data, function($message) 76 | { 77 | $message->to('foo@example.com', 'John Smith')->subject('Welcome!'); 78 | }); 79 | 80 | ถ้าเรามีหลายคิว มีฟังก์ชันให้เราเรียงคิวอีก คือ `queueOn` และ `laterOn` 81 | 82 | Mail::queueOn('queue-name', 'emails.welcome', $data, function($message) 83 | { 84 | $message->to('foo@example.com', 'John Smith')->subject('Welcome!'); 85 | }); 86 | 87 | 88 | ## Mail & Local Development 89 | 90 | ในการพัฒนานั้น เรายังไม่ต้องใช้งานเมล์จริงๆในการส่งก็ได้ laravel เตรียมฟังก์ชัน `Mail::pretend` หรือตั้งค่า `pretend` ใน `app/config/mail.php` เป็น `true`. เพื่อเข้าสู่ `pretend` mode ข้อความบนเมล์ที่ถูกส่งจะถูกเขียนบนล็อกแทย 91 | -------------------------------------------------------------------------------- /migrations.md: -------------------------------------------------------------------------------- 1 | # Migrations & Seeding 2 | 3 | 4 | ## คำอธิบายเบื้องต้น 5 | 6 | Migrations คือการเก็บประวัติสร้างจุดเซฟของฐานข้อมูล. ทำให้เราสามารถเพิ่มลบตาราง โดยย้อนกลับได้หากไม่ถูกใจ ส่วนการเขียนตารางต้องไปดูเรื่อง [Schema Builder](/docs/schema) การทำ migration จะเป็นการควบคุมการทำงานของ schema. 7 | 8 | 9 | ## สร้าง Migrations 10 | 11 | เริ่มด้วยการรันคำสัง `migrate:make` บน commandline: 12 | 13 | **การสร้างตารางโดยใช้ commandline** 14 | 15 | php artisan migrate:make create_users_table 16 | 17 | ไฟล์ migration ถูกเก็บไว้ที่โฟลเดอร์ `app/database/migrations` แต่ละไฟล์จะมีวันกำกับชื่อ ด้วยเพื่อให้ระบบรู้ลำดับการสร้างไฟล์ 18 | 19 | เราสามารถกำหนดที่อยู่ของไฟล์ได้โดยพารามิเตอร์ `--path` เหมือนตัวอย่างข้างล่างครับ 20 | 21 | php artisan migrate:make foo --path=app/migrations 22 | 23 | พารามิเตอร์ `--table` และ `--create` ใช้ในการสร้าง ตารางทั้งคู่เลยครับ 24 | 25 | php artisan migrate:make create_users_table --table=users --create 26 | 27 | 28 | ## Running Migrations 29 | 30 | **การสั่งให้คำสั่ง migration ทำงาน** 31 | 32 | php artisan migrate 33 | 34 | **กำหนดที่อยู่ของไฟล์ที่จะรัน** 35 | 36 | php artisan migrate --path=app/foo/migrations 37 | 38 | **สั่งรันเฉพาะตรง package** 39 | 40 | php artisan migrate --package=vendor/package 41 | 42 | > **หมายเหตุ:** ถ้าเราเจอ `error Class not found`ให้รันคำสั่ง `composer update`. 43 | 44 | 45 | ## Rolling Back Migrations 46 | 47 | **การย้อนกลับการทำงานครั้งล่าสุด** 48 | 49 | php artisan migrate:rollback 50 | 51 | **การย้อนกลับทั้งหมด** 52 | 53 | php artisan migrate:reset 54 | 55 | **การย้อนกลับแล้วทำงานใหม่อีกรอบ** 56 | 57 | php artisan migrate:refresh 58 | 59 | php artisan migrate:refresh --seed 60 | 61 | 62 | ## Database Seeding 63 | 64 | Laravel เตรียมการฟังก์ชันที่ช่วยในการป้อนข้อมูลจำลอง ที่อาจจะใช้ทดสอบการทำงานของเว็บไว้ในโฟลเดอร์ `app/database/seeds`. ชื่อคลาสเราก็ตั้งชื่อตามตารางและรูปแบบให้เป็นไปตามแบบนี้ครับ `UserTableSeeder`, โดยค่าเริ่มต้นเเล้วจะเป็น `DatabaseSeeder` โดยใช้ฟังก์ชัน `call` เพื่อรันคลาสอื่นๆ 65 | ทำให้เราลำดับการทำงานได้ 66 | 67 | **ตัวอย่าง** 68 | 69 | class DatabaseSeeder extends Seeder { 70 | 71 | public function run() 72 | { 73 | $this->call('UserTableSeeder'); 74 | 75 | $this->command->info('User table seeded!'); 76 | } 77 | 78 | } 79 | 80 | class UserTableSeeder extends Seeder { 81 | 82 | public function run() 83 | { 84 | DB::table('users')->delete(); 85 | 86 | User::create(array('email' => 'foo@bar.com')); 87 | } 88 | 89 | } 90 | 91 | การทำงานก็ใช้คำสั่ง `db:seed` command บน Artisan CLI: 92 | 93 | php artisan db:seed 94 | 95 | ทำการย้อนกลับการทำงานด้วย 96 | 97 | php artisan migrate:refresh --seed 98 | -------------------------------------------------------------------------------- /packages.md: -------------------------------------------------------------------------------- 1 | # Package Development 2 | 3 | 4 | ## คำอธิบายเบื้องต้น 5 | 6 | Packages คือการนำไลบรารี่ภายนอกเข้ามาใช้งานใน laravel ซึ่งส่วนมากจะอยู่บน [Packagist](http://packagist.org) และส่วนมากอีกไม่ได้ปรับแต่งให้เข้ากับ framework ไหนเป็นพิเศษ 7 | ซึ่งตรงนี้เราก็ต้อง ออกเเรงกันหน่อยครับ ถ้าอยากจะมี package เป็นของเราเอง 8 | ส่วน [การติดตั้ง package](http://taqmaninw.com/การติดตั้ง-package-บน-laravel-4) ถ้ามาเขียนในนี้คงจะยาว ผมเลยเขียนไว้ที่เว็บแล้ว อยากรู้ต้องทำไงต้องตามไปดูเลยครับ 9 | 10 | 11 | ## การสร้าง Package 12 | 13 | สถานที่ๆเราจะทำการพัฒนาคือโฟลเดอร์ชื่อ `workbench` ครับ แต่ตอนแรกเราต้องเข้าไปตั้งค่าที่ไฟล์ `app/config/workbench.php` ในไฟล์นี้เราต้องเปลี่ยน `name` และ `email` ซึ่ง `composer.json` จะนำไปใส่เวลาเราสร้าง package ขึ้นมา 14 | 15 | **สร้างโครงของ package ขึ้นมาด้วย CommandLine** 16 | 17 | php artisan workbench vendor/package --resources 18 | 19 | parameter แรก `vendor` คือชื่อผู้พัฒนา `package` คือชื่อของ `package` `resources` เป็นพารามิเตอร์ที่บอกให้สร้าง `migrations`, `views`, `config`, ด้วย 20 | 21 | เมื่อคำสั่งข้างบนทำงาน `package`ของเราจะไปปรากฏที่โฟลเดอร์ `workbench` ต่อมาเราจะสร้าง `ServiceProvider` ซึงการตั้งชื่อจะเป็นแบบนี้ `[Package]ServiceProvider` ส่วนการนำไปลงททะเบียนที่ไฟล์ `app.php` นั้นเส้นทางของไฟล์จะเป็นแบบนี้ครับ `Taylor\Zapper\ZapperServiceProvider` ซึ่งต้องนำไปวางไว้ที่อาเรย์ชื่อ `providers` 22 | 23 | ก่อนที่จะเริ่มพัฒนา package ของเรา ควรมารู้จักโครงสร้างของมันก่อนครับ 24 | 25 | 26 | ## โครงสร้างของ package 27 | 28 | 29 | **โครงสร้างโฟลเดอร์ของ package** 30 | 31 | /src 32 | /Vendor 33 | /Package 34 | PackageServiceProvider.php 35 | /config 36 | /lang 37 | /migrations 38 | /views 39 | /tests 40 | /public 41 | 42 | เมื่อตามเข้าไปดูในโฟลเดอร์ `src/ชื่อของเรา/ชื่อpackageของเรา` จะเจอกับไฟล์ `ServiceProvider`กับโฟลเดอร์ `config`, `lang`, `migrations`, และ `views` ซึ่งจะเหมือนในตัวโฟลเดอร์ app หลักของเราแต่ย่อส่วนลงมาครับ 43 | 44 | 45 | ## Service Providers 46 | 47 | เริ่มแรกในไฟล์ `Service Provider` จะมีฟังก์ชัน `boot` และ `register`. ซึ่งในนี้เราจะสามารถ ใส่ฟังก์ชันอะไรก็ได้ที่จะช่วยจัดการ package ของเรา เช่น ดึงไฟล์ route เข้ามา,ใช้ IOC ดึงคลาสอื่นเข้ามาช่วยเพิ่ม event เข้ามาดักฟัง 48 | 49 | ฟังก์ชัน `register` จะเริ่มทำงานทันทีเมื่อ package เริ่มทำงาน, ถ้าเรา package ของเราต้องการคลาสอื่นๆ ในการทำงานร่วมด้วยต้องใช้เมทอด `boot` ครับ 50 | 51 | โดยค่าเริ่มต้นเเล้วฟังก์ชัน `boot` จะมีค่ามาให้ดังนี้ 52 | 53 | $this->package('vendor/package'); 54 | // ตัวอย่างถ้ามีคลาสที่ต้องใช้ร่วมระหว่างการ boot package 55 | ClassLoader::addDirectories(array( 56 | app_path().'/widgets' 57 | )); 58 | 59 | ถ้าลบบรรทัดแรกออกไปผลก็คือ package ไม่ทำงานครับ laravel จะไม่รู้จัก package นี้เลย 60 | 61 | 62 | ## Package Conventions 63 | 64 | ตัวอย่างการเรียกใช้งานค่าต่างๆใน package 65 | 66 | **เรียก view ของ package** 67 | 68 | return View::make('package::view.name'); 69 | 70 | **เรียกค่าของการตั้งค่า** 71 | 72 | return Config::get('package::group.option'); 73 | 74 | > **หมายเหตุ:** ถ้า package ของเรามี migrations ควรใสชื่อ package เข้าไปอยู่ไฟล์ด้วย เพื่อป้องกันการเหมือนกับ packages อื่น 75 | 76 | 77 | ## ขั้นตอนในการพัฒนา 78 | 79 | พอสร้างโปรเจคเสร็จ เราก็ใช้คำสั่ง `php artisan dump-autoload` เพื่อสร้างไฟล์ที่บอกที่อยู่ของ package ของเราขึ้นมา 80 | 81 | **ตัวอย่าง** 82 | 83 | php artisan dump-autoload 84 | 85 | 86 | ## Package Routing 87 | 88 | การที่จะโหลดไฟล์ route เข้ามาใช้ต้องใช้ฟังก์ชัน `include` ในฟังก์ชัน `boot` ครับ 89 | 90 | **ตัวอย่างการดึง route มาใช้ใน Service Provider** 91 | 92 | public function boot() 93 | { 94 | $this->package('vendor/package'); 95 | 96 | include __DIR__.'/../../routes.php'; 97 | } 98 | 99 | > **หมายเหตุ:**ถ้าต้องการใช้ controller ด้วยมั่นใจว่ามันต้องถูกเพิ่มไว้ในไฟล์ `composer.json` ในส่วน autoload 100 | 101 | 102 | ## การตั้งค่า Package 103 | 104 | บาง package เราต้องดึงค่าต่างๆ เช่น appid,appsecret มาใช้ โดยเริ่มต้นไฟล์ `config.php` จะอยู่ในตัว package กรณีที่ดึงลงมาด้วย composer แล้วติดตั้งเสร็จไฟล์ จะอยู่ที่โฟลเดอร์ `/app/config/package` 105 | 106 | **การเข้าถึงไฟล์ config** 107 | 108 | Config::get('package::file.option'); 109 | 110 | ตัวพารามิเตอร์แรกคือชื่อของ package หลังจาก semicolon คือชื่อไฟล์ หลังเครื่องหมายดอทคือชื่อ อาเรย์ `config.php`. ถ้าโฟลเดอร์ที่ใช้เก็บไฟล์ config ของ package มีไฟล์เดียวก็ไม่ต้องใส่ชื่อก็ได้ครับ 111 | 112 | **ตัวอย่างกรณีโฟลเดอร์มีไฟล์เดียว** 113 | 114 | Config::get('package::option'); 115 | 116 | บางครั้งไฟล์ที่ต้องใช้ใน package มันก็ดันไมได้อยู่ใน package สามารถใช้ฟังก์ชัน `addNamespace` ซึ่งมีอยู่ในคลาส `View`, `Lang`, กับ `Config`ดังต้วอย่างเลยครับ 117 | 118 | 119 | View::addNamespace('package', __DIR__.'/path/to/views'); 120 | 121 | ทีนี้เราก็สามารถใช้งานคลาส View ใน package ได้ละ 122 | 123 | return View::make('package::view.name'); 124 | 125 | 126 | ### Cascading Configuration Files 127 | 128 | เมื่อเราดาวน์โหลดไฟล์ package มาด้วย composer ต้องนำไฟล์โฟลเดอร์ config ของ package ออกมาใช้ก่อน 129 | 130 | **ตัวอย่างการใช้งาน** 131 | 132 | php artisan config:publish vendor/package 133 | 134 | เมื่อคำสั่งทำงานเสร็จจะปรากฎอยู่ที่ `app/config/packages/vendor/package` 135 | 136 | 137 | 138 | ## Package Migrations 139 | 140 | เราสามารถทำ migration ให้กับ package โด้โดยใช้พารามิเตอร์ `--bench` ตามตัวอย่างเลยครับ 141 | 142 | **สร้าง migration ให้ package ในโฟลเดอร์ workbench** 143 | 144 | php artisan migrate:make create_users_table --bench="vendor/package" 145 | 146 | **สั่งให้ migration ของ package ทำงาน** 147 | 148 | php artisan migrate --bench="vendor/package" 149 | 150 | เมื่อพัฒนาเสร็จอยากจะลองใช้งานจริงเองก่อนเราต้องใช้พารามิเตอร์ `--package`เพื่อส่ง package ไปไว้ที่โฟลเดอร์ `vendor` 151 | 152 | **ตัวอย่างคำสั่งการย้าย package ไปไว้ที่ vendor** 153 | 154 | php artisan migrate --package="vendor/package" 155 | 156 | 157 | ## Package Assets 158 | 159 | บาง package จะมีไฟล์ JavaScript, CSS, และ images.เราไม่สามารถสร้างลิ้งโดยตรงจากโฟลเดอร์ `vendor` หรือ `workbench` ฉะนั้นเราต้องย้ายไปไว้ที่ โฟลเดอร์ `public` 160 | 161 | **การย้ายไฟล์ css,js,image โดยใช้ commandline** 162 | 163 | php artisan asset:publish 164 | 165 | php artisan asset:publish vendor/package 166 | 167 | แต่ถ้า package ยังอยู่ในโฟลเดอร์ workbench ต้องใช้คำสั่งนี้ครับ 168 | 169 | php artisan asset:publish --bench="vendor/package" 170 | 171 | ตอนนี้โฟลเดอร์จะถูกส่งไปไว้ที่ โฟลเดอร์`public/packages` ตัวอย่างชื่อโฟลเดอร์ `userscape/kudos` ตัวอย่างเส้นทางที่อยุ่ `public/packages/userscape/kudos`. 172 | 173 | 174 | ## การแบ่งปัน Packages ของเรา 175 | 176 | เมื่อพัฒนาเสร็จแล้ว เราเกิดอยากให้คนอื่นช่วยพัฒนาต่อ หรืช่วยหาบั๊กให้ เราต้องอัพ package ของเราขึ้น github หรือ bitbucket ก่อนครับ หลังจากนั้นไปสมัคร [Packagist](http://packagist.org) เพื่อนำ package ของเราไปผูกไว้กับฐานข้อมูลหลักของ composer หลังจากนั่น ก็ใช้ composer โหลดลงมาใช้เลย 177 | 178 | 179 | -------------------------------------------------------------------------------- /pagination.md: -------------------------------------------------------------------------------- 1 | # Pagination 2 | คือแบ่งการแสดงข้อมูลเป็นหน้าไปครับ 3 | 4 | ## การตั้งค่า 5 | 6 | การตั้งค่าการของอยู่ที่ `app/config/view.php` ตัวแปรชื่อ `pagination` ในการแบ่งหน้า ฟังก์ชัน `pagination::slider` ใช้ในการสร้างเลขหน้า `pagination::simple` ใช้สร้างปุ่ม "previous" และ "next" 7 | 8 | 9 | ## การใช้งาน 10 | 11 | การใช้งานมีอยู่หลายรูปแบบ เเต่ที่ง่ายที่สุดใช้เมทอด `paginate`บน query builder หรือ Eloquent model. 12 | 13 | **ตัวอย่างโดยใช้ query builder** 14 | 15 | $users = DB::table('users')->paginate(15); 16 | 17 | You may also paginate [Eloquent](/docs/eloquent) models: 18 | 19 | **ตัวอย่างโดยใช้ Eloquent Model** 20 | 21 | $users = User::where('votes', '>', 100)->paginate(15); 22 | 23 | ในตัวอย่างเรากำหนดจำนวนข้มูลต่อหน้าได้ ส่วนการแสดงผลบน view เราจะใช้ฟังก์ชัน `links` 24 | 25 |
26 | 27 | name; ?> 28 | 29 |
30 | 31 | links(); ?> 32 | 33 | เพียงแค่นี้ก็จะได้การแบ่งหน้าละครับ. 34 | 35 | เราสามารถจัดการๆ แบ่งหน้าได้โดยฟังก์ชันต่อไปนี้ครับ: 36 | 37 | - `getCurrentPage` 38 | - `getLastPage` 39 | - `getPerPage` 40 | - `getTotal` 41 | - `getFrom` 42 | - `getTo` 43 | 44 | บางครั้งเราอยากสร้างเองเพราะอาจจะมีข้อมูลที่ต้องผ่านการคำนวนหลายขั้น ก็ใช้เมทอดนี้เลยครับ `Paginator::make` 45 | 46 | **ตัวอย่าง** 47 | 48 | $paginator = Paginator::make($items, $totalItems, $perPage); 49 | 50 | 51 | ## Appending To Pagination Links 52 | 53 | เราสามารทำการเรียงลำดับการแสดงผลได้โดยใช้เมทอด `appends` เหมือนในตัวอย่าง 54 | 55 | appends(array('sort' => 'votes'))->links(); ?> 56 | 57 | ลิ้งที่ออกมาหน้าตาจะเป็นแบบนี้ 58 | 59 | http://example.com/something?page=2&sort=votes -------------------------------------------------------------------------------- /queries.md: -------------------------------------------------------------------------------- 1 | # Query Builder 2 | คือการจัดการๆคิวรี่ของ laravel ช่วยอำนวยความสะดวกให้เรา ไม่ต้องเขียนคิวรี่ยาวๆ ด้วยตัวเองครับ 3 | 4 | 5 | ## การเลือกข้อมูล 6 | 7 | **ดึงค่าทั้งหมดจากตาราง users** 8 | 9 | $users = DB::table('users')->get(); 10 | 11 | foreach ($users as $user) 12 | { 13 | var_dump($user->name); 14 | } 15 | 16 | **ดึงค่าแถวแรกจากตาราง users โดย name เท่ากับ john** 17 | 18 | $user = DB::table('users')->where('name', 'John')->first(); 19 | 20 | var_dump($user->name); 21 | 22 | **ดึงค่าจากตาราง users โดย name เท่ากับ john แล้วก็เอาแค่คอลัมน์ที่ชื่อว่า name** 23 | 24 | $name = DB::table('users')->where('name', 'John')->pluck('name'); 25 | 26 | **ดึงค่าทั้งหมดจากตาราง roles โดยเอาแค่คอลัมน์ title** 27 | 28 | $roles = DB::table('roles')->lists('title'); 29 | 30 | ค่าที่คืนมาจะเป็นอาเรย์นะครับ ถ้าเราอยากใส่คีย์ให้แต่ละแถวเราใส่พารามิเตอร์ตัวที่สองเข้าไป name จะไปเป็นคีย์ให้กับ title 31 | 32 | $roles = DB::table('roles')->lists('title', 'name'); 33 | 34 | **เมทอด select ใช้กำหนดคำสั่งในการเลือกเอง** 35 | 36 | $users = DB::table('users')->select('name', 'email')->get(); 37 | 38 | $users = DB::table('users')->distinct()->get(); 39 | 40 | $users = DB::table('users')->select('name as user_name')->get(); 41 | 42 | **เลือกข้อมูลจากผลการคิวรี่อีกที** 43 | 44 | $query = DB::table('users')->select('name'); 45 | 46 | $users = $query->addSelect('age')->get(); 47 | 48 | **การใช้ where** 49 | 50 | $users = DB::table('users')->where('votes', '>', 100)->get(); 51 | 52 | **การใช้หลายๆเงื่อนไขโดยวิธีเชนเมทอด** 53 | 54 | $users = DB::table('users') 55 | ->where('votes', '>', 100) 56 | ->orWhere('name', 'John') 57 | ->get(); 58 | 59 | **ใช้ between** 60 | 61 | $users = DB::table('users') 62 | ->whereBetween('votes', array(1, 100))->get(); 63 | 64 | **ตัวอย่างการใช้ where กับ In ร่วมกัน** 65 | 66 | $users = DB::table('users') 67 | ->whereIn('id', array(1, 2, 3))->get(); 68 | 69 | $users = DB::table('users') 70 | ->whereNotIn('id', array(1, 2, 3))->get(); 71 | 72 | **ใช้หาแถวที่เป็นค่าวางตามคอลัมน์** 73 | 74 | $users = DB::table('users') 75 | ->whereNull('updated_at')->get(); 76 | 77 | **ตัวอย่างการเรียงลำดับข้อมูล** 78 | 79 | $users = DB::table('users') 80 | ->orderBy('name', 'desc') 81 | ->groupBy('count') 82 | ->having('count', '>', 100) 83 | ->get(); 84 | 85 | **การจำกัดข้อมูล** 86 | 87 | $users = DB::table('users')->skip(10)->take(5)->get(); 88 | 89 | 90 | ## Joins 91 | 92 | **ตัวอย่างการ join ครับ** 93 | 94 | DB::table('users') 95 | ->join('contacts', 'users.id', '=', 'contacts.user_id') 96 | ->join('orders', 'users.id', '=', 'orders.user_id') 97 | ->select('users.id', 'contacts.phone', 'orders.price'); 98 | 99 | การจอยแบบเติมคิวรี่ลงไปช่วยประหยัดเวลา เวลาคิดไม่ออกว่าจะใช้ฟังก์ไหนดี แทรกคิวรี่ลงไปตรงๆ เลย: 100 | 101 | DB::table('users') 102 | ->join('contacts', function($join) 103 | { 104 | $join->on('users.id', '=', 'contacts.user_id')->orOn(...); 105 | }) 106 | ->get(); 107 | 108 | 109 | ## Advanced Wheres 110 | 111 | **การ where แบบ หลายเงื่อนไข** 112 | 113 | DB::table('users') 114 | ->where('name', '=', 'John') 115 | ->orWhere(function($query) 116 | { 117 | $query->where('votes', '>', 100) 118 | ->where('title', '<>', 'Admin'); 119 | }) 120 | ->get(); 121 | 122 | หน้าตาของคิวรี่จะออกมาเป็นแบบนี้ 123 | 124 | select * from users where name = 'John' or (votes > 100 and title <> 'Admin') 125 | 126 | **หาว่ามีค่านี้อยู่ไหม** 127 | 128 | DB::table('users') 129 | ->whereExists(function($query) 130 | { 131 | $query->select(DB::raw(1)) 132 | ->from('orders') 133 | ->whereRaw('orders.user_id = users.id'); 134 | }) 135 | ->get(); 136 | 137 | หน้าตาของคิวรี่จะออกมาเป็นแบบนี้ 138 | 139 | select * from users 140 | where exists ( 141 | select 1 from orders where orders.user_id = users.id 142 | ) 143 | 144 | 145 | ## Aggregates การหาผลรวมชนิดต่างๆ 146 | 147 | 148 | **ตัวอย่างการคำนวนค่า** 149 | 150 | $users = DB::table('users')->count(); 151 | 152 | $price = DB::table('orders')->max('price'); 153 | 154 | $price = DB::table('orders')->min('price'); 155 | 156 | $price = DB::table('orders')->avg('price'); 157 | 158 | $total = DB::table('users')->sum('votes'); 159 | 160 | 161 | ## Raw Expressions 162 | 163 | Raw คือการใส่คิวรี่แบบสดๆ เข้าไปเลยไม่ต้องไปให้ฟังก์ชันสร้างให้ ประหยัดเวลามากขึ้นเมื่อเราต้องการค้นหาแบบซับซ้อน 164 | 165 | **ตัวอย่างการใช้คำสั่งคิวรี่** 166 | 167 | $users = DB::table('users') 168 | ->select(DB::raw('count(*) as user_count, status')) 169 | ->where('status', '<>', 1) 170 | ->groupBy('status') 171 | ->get(); 172 | 173 | **การเพิ่มและลดค่าให้คอลัมน์** 174 | 175 | DB::table('users')->increment('votes'); 176 | 177 | DB::table('users')->increment('votes', 5); 178 | 179 | DB::table('users')->decrement('votes'); 180 | 181 | DB::table('users')->decrement('votes', 5); 182 | 183 | การกำหนดค่าคอลัมน์ที่จะเพิ่มค่าให้ 184 | 185 | DB::table('users')->increment('votes', 1, array('name' => 'John')); 186 | 187 | 188 | ## การเพิ่มข้อมูล 189 | 190 | **ตัวอย่าง** 191 | 192 | DB::table('users')->insert( 193 | array('email' => 'john@example.com', 'votes' => 0) 194 | ); 195 | 196 | 197 | **การเพิ่มค่าพร้อมกับเพิ่มค่า id ด้วย** 198 | 199 | $id = DB::table('users')->insertGetId( 200 | array('email' => 'john@example.com', 'votes' => 0) 201 | ); 202 | 203 | > **หมายเหตุ:** ถ้าใช้ PostgreSQL เมทอด insertGetId คาดหวังว่าจะใช้คอลัมน์ "id" เป็นตัวที่มันจะเพิ่มให้ 204 | 205 | **การเพิ่มหลายๆข้อมูล** 206 | 207 | DB::table('users')->insert(array( 208 | array('email' => 'taylor@example.com', 'votes' => 0), 209 | array('email' => 'dayle@example.com', 'votes' => 0), 210 | )); 211 | 212 | 213 | ## การแก้ไข 214 | 215 | **ตัวอย่าง** 216 | 217 | DB::table('users') 218 | ->where('id', 1) 219 | ->update(array('votes' => 1)); 220 | 221 | 222 | ## การลบ 223 | 224 | **ตัวอย่าง** 225 | 226 | DB::table('users')->where('votes', '<', 100)->delete(); 227 | 228 | **การลบข้อมูลทั้งหมดเป็นการลบแบบแถวต่อแถว** 229 | 230 | DB::table('users')->delete(); 231 | 232 | **การลบแบบลบทั้งตารางด้วยแล้วสร้างขึ้นใหม่** 233 | 234 | DB::table('users')->truncate(); 235 | 236 | 237 | ## การทำ Unions 238 | 239 | union คือการจับผลลัพท์ของการ selecet 2 ครั้ง มารวมกันเป็นหนึ่งผลลัพท์ 240 | **Performing A Query Union** 241 | 242 | $first = DB::table('users')->whereNull('first_name'); 243 | 244 | $users = DB::table('users')->whereNull('last_name')->union($first)->get(); 245 | 246 | เมทอด `unionAll` ใช้งานเหมือนกับ `union` เลยครับ 247 | 248 | 249 | ## Caching Queries 250 | 251 | เราสามารถทำการแคชหรือบันทึกผลการคิวรี่ไว้บน session ก่อนด้วยเมทอด `remember` 252 | 253 | **ตัวอย่าง** 254 | 255 | $users = DB::table('users')->remember(10)->get(); 256 | 257 | ในตัวอย่างเราจะแคชผลการค้นหานี้เป็นเวลา 10 นาที ระหว่างนี้การคิวรี่จากตัวอย่างจะไม่ไปดึงข้อมูลจากฐานข้อมูล แต่จะดึงจากแคชจนกว่าจะหมดเวลาครับ -------------------------------------------------------------------------------- /queues.md: -------------------------------------------------------------------------------- 1 | # Queues 2 | 3 | คลาสที่ช่วยเรียงลำดับการทำงานของฟังก์ชันต่างๆ 4 | 5 | 6 | ## การตั้งค่า 7 | 8 | Laravel Queue เตรียมฟังก์ชันที่ใช้ในการเข้าถึง api ของเว็บที่ให้บริการคิวไว้ 9 | การคิวคือการเรียงลำดับงานของเว็บไซต์ เช่น เรามีเมล์ที่ต้องส่งถึง 1000 ฉบับถ้าส่งแบบเดิม server อาจจะรับไม่ไหว เราจึงมีคลาส queue มาเพื่อการนี้ครับ 10 | 11 | ไฟล์ที่ใช้ตั้งค่าเก็บไว้ที่ `app/config/queue.php`. ในไฟล์จะมีข้อมูลที่เราต้องใช้ในการเชื่อมต่อผู้ให้บริการคิว เช่น [Beanstalkd](http://kr.github.com/beanstalkd), [IronMQ](http://iron.io), [Amazon SQS](http://aws.amazon.com/sqs), and synchronous (สำหรับการทดสอบในเครื่อง) 12 | 13 | ชื่อคลาสของผู้ให้บริการคิวที่เราจะป้อนเข้าไป: 14 | 15 | - Beanstalkd: `pda/pheanstalk` 16 | - Amazon SQS: `aws/aws-sdk-php` 17 | - IronMQ: `iron-io/iron_mq` 18 | 19 | 20 | ## การใช้งานเบื้องต้น 21 | 22 | ในการส่งงานใหม่เข้าไปในคิวเราใช้ฟังก์ชัน `Queue::push` 23 | 24 | **Pushing A Job Onto The Queue** 25 | 26 | Queue::push('SendEmail', array('message' => $message)); 27 | 28 | พารามิเตอร์ตัวแรกเป็น ฟัง์ชันที่เราใช้ควบคุมคิวนี้. ตัวที่สองเป็นข้อมูลที่เราจะทำการคิว 29 | 30 | **ตัวอย่างฟังก์ชันที่ใช้ควบคุมการคิว** 31 | 32 | class SendEmail { 33 | 34 | public function fire($job, $data) 35 | { 36 | // 37 | } 38 | 39 | } 40 | 41 | ฟังก์ชัน`fire`รับพารามิเตอร์ `Job` ตัวที่สองคือข้อมูล `data` ที่จะส่งลงคิว 42 | 43 | ถ้าเราไม่ใช่เมทอด `fire`เราสามารถกำหนดได้ตามตัวอย่างครับ 44 | 45 | **เปลี่ยนจาก fire เป็น Push** 46 | 47 | Queue::push('SendEmail@send', array('message' => $message)); 48 | 49 | เมื่อมีการทำงานไปเเล้วเราก็ต้องลบข้อมูลออกไปโดยใช้เมทอด `delete` เพื่อลบ `Job` instance: 50 | 51 | **ตัวอย่างการลบ** 52 | 53 | public function fire($job, $data) 54 | { 55 | // Process the job... 56 | 57 | $job->delete(); 58 | } 59 | 60 | ถ้าเราต้องการเอางานที่ทำไปกลับมาเข้าคิวอีกครั้งก็ใช้เมทอด `release` ครับ 61 | 62 | **ตัวอย่าง** 63 | 64 | public function fire($job, $data) 65 | { 66 | // Process the job... 67 | 68 | $job->release(); 69 | } 70 | 71 | เราสามารถกำหนดเวลาที่จะหน่วงไว้ก่อนที่จะสั่งให้งานต่อไปทำงานได้แบบนี้ครับ 72 | 73 | $job->release(5); 74 | 75 | เมื่องานที่เข้าคิวเกิดข้อผิดพลาดขึ้น จะถูกนำกลับไปต่อคิวใหม่ เราสามารถตรวจสอบการทำงานใหม่ได้โดยฟังก์ชัน `attempts` 76 | 77 | **ตรวจหางานที่มีการพยายามทำมากกว่า 3 ครั้ง** 78 | 79 | if ($job->attempts() > 3) 80 | { 81 | // 82 | } 83 | 84 | 85 | 86 | **การเรียกข้อมูลของาน** 87 | 88 | $job->getJobId(); 89 | 90 | 91 | ## Queueing Closures 92 | 93 | เราสามารถใช้งานฟังก์ชันที่ไม่มีชื่อในการสร้างงานได้โดยตัวอย่างเลยครับ 94 | 95 | 96 | Queue::push(function($job) use ($id) 97 | { 98 | Account::delete($id); 99 | 100 | $job->delete(); 101 | }); 102 | 103 | > **หมายเหตุ:** เมื่อใช้ฟังก์ชันที่ไม่มีชื่อกับ queue ตัวแปร `__DIR__` และ `__FILE__` จะไม่สามารถใช้งานได้ 104 | 105 | ถ้าใช้บริการของ Iron.io [push queues](#push-queues), ควรจะไม่ใช้งานฟังก์ชันที่ไม่มีชื่อในเมล์. จะมีการตรวจสอบคำร้องว่าส่งมาจาก Iron.io.จริงหรือไม่ ตัวอย่าง `https://yourapp.com/queue/receive?token=SecretToken`.ควรทำการตรวจสอบค่า secrettoken ก่อนทำการคิว. 106 | 107 | 108 | ## Running The Queue Listener 109 | 110 | Laravel เตรียมคำสั่ง`queue:listen` เพื่อรอรับคำขอที่มากจากผู้ให้บริการ 111 | 112 | **ตัวอย่างการใช้งาน** 113 | 114 | php artisan queue:listen 115 | 116 | เราสามารถกำหนดค่าการเชื่อมต่อเสริมลงไปได้: 117 | 118 | php artisan queue:listen connection 119 | 120 | เราสามารถใช้โปรแกรม [Supervisor](http://supervisord.org/) เพื่อตรวจสอบว่าคำสั่ง queue listener ยังทำงานอยู่ไหม 121 | 122 | สามารถตั้งค่าเวลาที่จะอนุญาตุให้เกิดทำงานขึ้นได้ 123 | 124 | **ตัวอย่างการหน่วงเวลา** 125 | 126 | php artisan queue:listen --timeout=60 127 | 128 | 129 | **สั่งให้งานชิ้นแรกที่อยู่บนคิวทำงาน** 130 | 131 | php artisan queue:work 132 | 133 | 134 | ## Push Queues 135 | 136 | Push queues คือการโยนภาระการรอรับคิวจากที่ทำบนเครื่องขิงเรา เปลี่ยนไปให้ผู้บริการทำแทน ซึ่งมี [Iron.io](http://iron.io) เจ้าเดียวที่สนับสนุน. ก่อนอื่นเราต้องไปสมัครบริการของ Ironio ก่อน, แล้วนำข้อมูลการเชื่อมต่อมาใส่ไว้ที่ `app/config/queue.php` 137 | 138 | ต่อมาก็ใช้คำสั่ง Artisan `queue:subscribe` เพื่อลงทะเบียนคิวไว้กับ Iron.io: 139 | 140 | **ตัวอย่าง** 141 | 142 | php artisan queue:subscribe queue_name http://foo.com/queue/receive 143 | 144 | ตอนนี้ ถ้าเราไปดูที่หน้าแสดงผลคิวที่ Iron.io , ก็จะเห็นรายการคิว และรายชื่อลิ้งที่เราจะสั่งให้ทำงาน. เราสามารถลงทะเบียนไว้ทีละหลายๆลิ้งก็ได้.ต่อมาเราต้องมาสร้าง route เพื่อรับคำร้องขอของ Iron.io โดยชื่อ route จะเป็น `queue/receive` และส่งค่ากลับไปด้วยฟังก์ชัน `Queue::marshal` 145 | 146 | Route::post('queue/receive', function() 147 | { 148 | return Queue::marshal(); 149 | }); 150 | 151 | เมทอด `marshal` จะดูแลการทำงานของคิวให้ -------------------------------------------------------------------------------- /quick.md: -------------------------------------------------------------------------------- 1 | # การเริ่มต้นอย่างรวดเร็ว 2 | 3 | > หมายเหตุ :: url ที่เราจะเรียกใช้งานในตอนเริ่มแรกคือ localhost หรือ 127.0.0.1 4 | > ตามด้วยชื่อโฟลเดอร์ของเว็บที่เราสร้าง แล้วตามด้วย public นะครับ ยกตัวอย่าง 127.0.0.1/taqmaninw/public นะครับ 5 | 6 | บททนี้จะทำให้เราเห็นภาพรวมของ laravel นะครับ 7 | 8 | 9 | ## การติดตั้ง 10 | 11 | ถ้าไม่รู้จัก composer แนะนำไปอ่าน [ที่นี้](http://taqmaninw.com/composer-คืออะไร) ก่อน เริ่มจากใช้คำสั่ง 12 | 13 | composer create-project laravel/laravel ชื่อโปรเจค --prefer-dist 14 | 15 | หลังจากนั้น composer จะทำการดาวน์โหลดไฟล์ต่างๆ มาเก็บที่โฟลเดอร์ที่เรากำหนดชื่อไว้ 16 | 17 | หลังจากนั้นก็ทำความรู้จักกับ [โครงสร้างโฟลเดอร์ของ laravel](http://taqmaninw.com/ทำความรู้จักโครงสร้างโฟลเดอร์ของ-laravel-4) เริ่มแรกเราต้องไปกำหนดค่าต่างๆ ที่โฟลเดอร์ `app/config` ก่อนในนี้ก็จะมีการตั้งค่าให้มากมายแต่เราอาจต้องการแค่ [การกำหนดค่าเบื้องต้น](http://taqmaninw.com/การตั้งค่าเบื้องต้นให้กับ-laravel) 18 | 19 | 20 | ## Routing 21 | เราต้องกำหนด url ที่เราจะอนุญาตให้เข้าถึง ฟังก์ชันต่างก่อนที่ `app/routes.php` ตัวอย่างการสร้าง Route เบื้องต้น 22 | 23 | Route::get('users', function() 24 | { 25 | return 'Users!'; 26 | }); 27 | 28 | ตอนนี้เมื่อเราพิมพ์ชื่อโปรเจคของเราบนบราวเซอร์แล้วตามด้วย `/users` เราจะเห็นคำว่า `Users!` แสดงอยู่ 29 | 30 | การสร้าง Route ไปหา Controller 31 | 32 | Route::get('users', 'UserController@getIndex'); 33 | 34 | ตอนนี้ `/user` จะถูกส่งไปที่ฟังก์ชน getIndex ของ UserController 35 | 36 | 37 | การสร้าง View 38 | 39 | ต่อมาเรามาสร้างไฟล์ที่จะใช้จัดการรูปแบบในการแสดงผลที่โฟลเดอร์ `app/views` เราสร้างไฟล์ที่ชื่อ `layout.blade.php` และ `users.blade.php`ต่อด้วย `layout.blade.php` 40 | 41 | 42 | 43 |

Laravel Quickstart

44 | 45 | @yield('content') 46 | 47 | 48 | 49 | ต่อมาในไฟล์ `users.blade.php` เราจะดึงไฟล์ layout มาลง 50 | 51 | @extends('layout') 52 | 53 | @section('content') 54 | Users! 55 | @stop 56 | 57 | เพื่อความไม่งงว่าตัวแปรเหล่านี้คืออะไร ตามไปดูที่นี่เลยครับ [Blade documentation](/docs/templates) 58 | 59 | ถ้าเราจะแสดงไฟล์ view ที่เราสร้างก็ต้องอาศัย Route ดังตัวอย่าง 60 | 61 | Route::get('users', function() 62 | { 63 | return View::make('users'); 64 | }); 65 | 66 | ต่อไปเราจะไปลุยดาต้าเบสกันนะครับ 67 | 68 | 69 | ## การทำ Migration 70 | 71 | เราจะใช้คลาส [Migration](#migration) ในการจัดการฐานข้อมูลนะครับ 72 | เริ่มต้นด้วยการตั้งค่าในการเชื่อมต่อฐานข้อมูลก่อนที่ไฟล์ `app/database` ในค่าเริ่มต้นเเล้วอาเรย์ `driver`จะเป็น `mysql` แล้วเราก็เปลี่ยนค่าตรง `mysql` เป็นข้อมูลในการเชื่อมต่อฐานข้อมูลของเรา 73 | 74 | ต่อมาในการสร้าง migration เราใช้ คำสั่ง artisan ใน commandline จากในโฟลเดอร์โปรเจคของเรา ตัวอย่าง 75 | 76 | php artisan migrate:make create_users_table 77 | 78 | ต่อมาไฟล์ migrration จะไปโผล่ที่โฟลเดอร์ `app/database/migrations` ในไฟล์จะมีฟังก์ชัร `up` และ `down` เราจะสร้าง [Schema](#schema-builder) เพื่อการจัดการฐานข้อมูล 79 | 80 | ตัวอย่างการสร้าง [Schema](#schema-builder) 81 | 82 | public function up() 83 | { 84 | Schema::create('users', function($table) 85 | { 86 | $table->increments('id'); 87 | $table->string('email')->unique(); 88 | $table->string('name'); 89 | $table->timestamps(); 90 | }); 91 | } 92 | 93 | public function down() 94 | { 95 | Schema::drop('users'); 96 | } 97 | 98 | ต่อมาเราก็รันคำสั่ง 99 | 100 | php artisan migrate 101 | 102 | ถ้าอยากย้อนคำสั่ง `migrate` เราต้องใช้คำสั่ง `migrate:rollback` 103 | 104 | 105 | ## Eloquent ORM 106 | 107 | [Eloquent](#eloquent-oRM) คือ ชุดคำสั่งที่เราใช้ในการทำ sql query นั่นเองครับ ช่วยให้เราสะดวกสะบาย ทำงานได้รวดเร็วขึ้น เริ่มแรกเราต้องไปสร้าง `model ` ที่โฟลเดอร์ `app/models` โดยตั้งชื่อว่า `User.php` ตัวอย่างการประกาศคลาสในโมเดล 108 | 109 | class User extends Eloquent {} 110 | 111 | ตัวอย่างการเรียกใช้ Eloquent Model ครับ 112 | 113 | Route::get('users', function() 114 | { 115 | $users = User::all(); 116 | 117 | return View::make('users')->with('users', $users); 118 | }); 119 | 120 | เมทอด `all`ที่ต่อจากเนมสเปซ `User` จะคิวรี่ค่าทั้งหมดจากตาราง `users` ส่วนใน `View` เราใช้ฟังก์ชัน `with` เพื่อดึงเฉพาะคอลัมน์ user ครับ 121 | 122 | 123 | 124 | ## Displaying Data 125 | 126 | ตัวอย่างการแสดงค่าที่มาจากฐานข้อมูลบนไฟล์ view ครับ 127 | 128 | @extends('layout') 129 | 130 | @section('content') 131 | @foreach($users as $user) 132 |

{{ $user->name }}

133 | @endforeach 134 | @stop 135 | 136 | 137 | ต่อไปเราต้องไปเรียนรู้เรื่อง [Eloquent](#eloquent-orm) และ [Blade](#templates). หรือแวะเข้าไปอ่านเล่นๆ ก่อนที่เรื่อง[Queues](#queues) และ [Unit Testing](#testing).ถ้าต้องการใช้งานในระดับสูงต่อก็ไปที่ [IoC Container](#ioc). -------------------------------------------------------------------------------- /redis.md: -------------------------------------------------------------------------------- 1 | # Redis 2 | 3 | [Redis](http://redis.io) เป็นโอเพ่นซอร์สฐานข้อมูลขนาดเล็ก ที่เก็บข้อมูลในรูปแบบ คีย์กับค่า หนึ่งค่าต้องมีคีย์กำกับ ประมาณนี้ครับ อยากรู้จักมากกว่านี้ต้องลองไปเล่นที่ [try redis](http://try.redis.io/) โดยข้อมูลที่อยู่ในนี้จะมี [strings](http://redis.io/topics/data-types#strings), [hashes](http://redis.io/topics/data-types#hashes), [lists](http://redis.io/topics/data-types#lists), [sets](http://redis.io/topics/data-types#sets), และ [sorted sets](http://redis.io/topics/data-types#sorted-sets). 4 | 5 | 6 | ## การปรับแต่ง 7 | 8 | การปรับแต่ง redis เราทำใน **app/config/database.php** ในนี้เราจะเห็นอาเรย์ชื่อ **redis** แบบนี้ครับ 9 | 10 | 'redis' => array( 11 | 12 | 'cluster' => true, 13 | 14 | 'default' => array('host' => '127.0.0.1', 'port' => 6379), 15 | 16 | ), 17 | 18 | โดยค่าเริ่มต้นเเล้ว ถูกตั้งให้สนับสนุนการพ้ฒนาบนเครื่อง เราสามารถปรับแต่งได้ตามใจครับ 19 | อาเรย์ชื่อ `cluster` ใช้เพื่อบอกให้ redis ที่อยู่ในเครื่องทำการ client-side sharding ข้าม Redis nodes ของคุณ, ทำให้เราสามารถสร้าง ram จำนวนมากได้. แต่การทำ client-side sharding แต่เราไม่สามารถจับการ failover ได้ 20 | 21 | 22 | 23 | 24 | ## การใช้งาน 25 | 26 | เราสามารถสร้างตัวแปรที่เป็นตัวแทนของเมทอด `Redis::connection` โดยการ 27 | 28 | $redis = Redis::connection(); 29 | 30 | เรายังไม่ได้กำหนดชื่อ server redis ของเราต้องกำหนดก่อนนะครับ 31 | 32 | $redis = Redis::connection('other'); 33 | 34 | ถ้าอยากศึกษาต่อไปที่นี้ครับ [Redis commands](http://redis.io/commands) ในการจัดการต่างๆ laravel มีฟังก์ชันต่างๆ มาให้เเล้วครับ: 35 | 36 | $redis->set('name', 'Taylor'); 37 | 38 | $name = $redis->get('name'); 39 | 40 | $values = $redis->lrange('names', 5, 10); 41 | 42 | ถ้าไม่ต้องการใช้คำสั่ง laravel ก็สามารถใช้เมทอด `command` ในการใช้คำสั่งของ redis ตรงๆได้ 43 | 44 | $values = $redis->command('lrange', array(5, 10)); 45 | 46 | คลาส `Redis` ที่เป็นตัว static คลาสครับ: 47 | 48 | Redis::set('name', 'Taylor'); 49 | 50 | $name = Redis::get('name'); 51 | 52 | $values = Redis::lrange('names', 5, 10); 53 | 54 | 55 | 56 | ## Pipelining 57 | 58 | Pipelining คือการส่งคำสั่งหลายๆ ตัวไปยัง redis server laravel มีเมทอด `pipeline` มาให้ใช้ 59 | 60 | **ตัวอย่าง** 61 | 62 | Redis::pipeline(function($pipe) 63 | { 64 | for ($i = 0; $i < 1000; $i++) 65 | { 66 | $pipe->set("key:$i", $i); 67 | } 68 | }); -------------------------------------------------------------------------------- /requests.md: -------------------------------------------------------------------------------- 1 | # Requests & Input 2 | คลาสนี้ใช้จัดการคำร้องขอต่างๆ เช่น ค่าที่ส่งมาจากฟอร์ม 3 | 4 | ## Basic Input 5 | 6 | 7 | **รับเฉพาะค่าที่มีชื่อตรงกับที่กำหนด** 8 | 9 | $name = Input::get('name'); 10 | 11 | **กำหนดค่าสำรองกรณีค่าที่ส่งมาเป็น null** 12 | 13 | $name = Input::get('name', 'Sally'); 14 | 15 | **ตรวจว่าค่าที่ส่งมาเป็นค่าว่างไหม** 16 | 17 | if (Input::has('name')) 18 | { 19 | // 20 | } 21 | 22 | **รับค่าทั้งหมดของคำร้องขอ** 23 | 24 | $input = Input::all(); 25 | 26 | **รับค่าเป็นกรณีๆ ไป** 27 | 28 | $input = Input::only('username', 'password'); 29 | 30 | $input = Input::except('credit_card'); 31 | 32 | 33 | 34 | 35 | ## Cookies 36 | 37 | **การดึงค่าจาก cookies** 38 | 39 | $value = Cookie::get('name'); 40 | 41 | **สร้าง cookie และส่งคืนไปให้ผู้ใช้งาน** 42 | 43 | $response = Response::make('Hello World'); 44 | 45 | $response->withCookie(Cookie::make('name', 'value', $minutes)); 46 | 47 | **สร้าง cookie ที่ไม่หมดอายุ** 48 | 49 | $cookie = Cookie::forever('name', 'value'); 50 | 51 | 52 | ## Old Input 53 | 54 | คือการที่เราเก็บค่าที่ได้จากฟอร์มไว เพื่อทำการใส่ในฟอร์มถัดไป หรือนำไปแสดงหลังจากหน้าโหลดเสร็จ 55 | 56 | **การนำค่าในฟอร์มเก็บใส่ session** 57 | 58 | Input::flash(); 59 | 60 | **การรับค่าเฉพาะกรณี** 61 | 62 | Input::flashOnly('username', 'email'); 63 | 64 | Input::flashExcept('password'); 65 | 66 | เราทำการส่งค่าในฟอร์มเก่าที่เก็บไว้ขึ้นไปในฟอร์ม 67 | 68 | return Redirect::to('form')->withInput(); 69 | 70 | return Redirect::to('form')->withInput(Input::except('password')); 71 | 72 | 73 | **การดึงค่าจากในฟอร์มเก่า** 74 | 75 | Input::old('username'); 76 | 77 | 78 | ## Files 79 | 80 | **รับค่าจากการอัพโหลดไฟล์** 81 | 82 | $file = Input::file('photo'); 83 | 84 | **ตรวจว่าไฟล์ถูกอัพโหลดไหม** 85 | 86 | if (Input::hasFile('photo')) 87 | { 88 | // 89 | } 90 | 91 | ค่าที่ถูกคืนมาจะเป็นเมทอด `file` method ซึ่งมาจากคลาส `Symfony\Component\HttpFoundation\File\UploadedFile` ซึ่งสืบทอดมาจากคลาส `SplFileInfo` ซึ่งเตรียมเมทอดไว้ให้เราจัดการไฟล์ไว้เยอะเลยครับ 92 | 93 | **เปลี่ยนที่อยู่ให้ไฟล์ที่อัพขึ้นมา** 94 | 95 | Input::file('photo')->move($destinationPath); 96 | 97 | Input::file('photo')->move($destinationPath, $fileName); 98 | 99 | **ดึงค่าเส้นทางทีอยูของไฟล์่** 100 | 101 | $path = Input::file('photo')->getRealPath(); 102 | 103 | **ดึงชื่อเริ่มต้นของไฟล์** 104 | 105 | $name = Input::file('photo')->getClientOriginalName(); 106 | 107 | **ดึงค่าขนาดของไฟล์** 108 | 109 | $size = Input::file('photo')->getSize(); 110 | 111 | **ดึงนามสกุลของไฟล์** 112 | 113 | $mime = Input::file('photo')->getMimeType(); 114 | 115 | 116 | ## Request Information 117 | 118 | คลาส `Request`ของ laravel สืบทอดมาจากคลาส `Symfony\Component\HttpFoundation\Request` ตอไปนี้คือฟังก์ชันสำคัญครับ 119 | 120 | **ดึงค่า URI จากการเรียกครั้งล่าสุด** 121 | 122 | $uri = Request::path(); 123 | 124 | **ตรวจสอบว่าคำร้องขอที่ส่งเข้ามาตรงกับกฏที่เราตั้งไว้ไหม** 125 | 126 | if (Request::is('admin/*')) 127 | { 128 | // 129 | } 130 | 131 | **ดึงค่า url ของคำร้องขอ** 132 | 133 | $url = Request::url(); 134 | 135 | **ดึงค่า URI เฉพาะส่วน** 136 | 137 | $segment = Request::segment(1); 138 | // http::/taqmaninw.com/admin/post/id?=3 139 | // $sengment จะเท่ากับ admin 140 | 141 | **ดึงค่า header ** 142 | 143 | $value = Request::header('Content-Type'); 144 | 145 | **ดึงค่าจากตัวแปร $_SERVER** 146 | 147 | $value = Request::server('PATH_INFO'); 148 | 149 | **ตรวจว่าคำขอเป็น ajax ไหม** 150 | 151 | if (Request::ajax()) 152 | { 153 | // 154 | } 155 | 156 | **ตรวจว่าคำขอมาจาก https ไหม** 157 | 158 | if (Request::secure()) 159 | { 160 | // 161 | } 162 | -------------------------------------------------------------------------------- /responses.md: -------------------------------------------------------------------------------- 1 | # Views & Responses 2 | บทนี้จะมาพูดถึงคลาส views กับ Response นะครับ 3 | 4 | ## Basic Responses 5 | 6 | **การส่งค่าคืนแบบง่ายๆ** 7 | 8 | Route::get('/', function() 9 | { 10 | return 'Hello World'; 11 | }); 12 | 13 | **สร้างการส่งกลับเอง** 14 | 15 | คลาส `Response` สืบทอดมาจากคลาส `Symfony\Component\HttpFoundation\Response` เราจะมาดูเฉพาะเมทอดที่สำคัญกันนะครับ 16 | 17 | ตัวอย่างการสร้างคำตอบกลับนะครับ 18 | 19 | $response = Response::make($contents, $statusCode); 20 | 21 | $response->header('Content-Type', $value); 22 | 23 | return $response; 24 | 25 | **เพิ่ม cookie ลงไปในคำตอบกลับ** 26 | 27 | $cookie = Cookie::make('name', 'value'); 28 | 29 | return Response::make($content)->withCookie($cookie); 30 | 31 | 32 | ## Redirects การส่งกลับ 33 | 34 | **ส่งกลับไปที่ route** 35 | 36 | return Redirect::to('user/login'); 37 | 38 | **ส่งกลับไปพร้อมกับ ข้อความ** 39 | 40 | return Redirect::to('user/login')->with('message', 'Login Failed'); 41 | 42 | **ส่งกลับไปที่ route ที่มีชื่อย่อตามตัวอย่าง** 43 | 44 | return Redirect::route('login'); 45 | 46 | **ส่งกลับไปที่ route ที่มีชื่อย่อตามตัวอย่างพร้อมกับค่า** 47 | 48 | return Redirect::route('profile', array(1)); 49 | 50 | **ส่งกลับไปที่ route ที่มีชื่อย่อตามตัวอย่างพร้อมกับตัวแปร** 51 | 52 | return Redirect::route('profile', array('user' => 1)); 53 | 54 | **ส่งกลับไปที่ฟังก์ชันใน controller ** 55 | 56 | return Redirect::action('HomeController@index'); 57 | 58 | **ส่งกลับไปที่ฟังก์ชันใน controller พร้อมกับพารามิเตอร์** 59 | 60 | return Redirect::action('UserController@profile', array(1)); 61 | 62 | **ส่งกลับไปที่ฟังก์ชันใน controller พร้อมกับตัวแปร** 63 | 64 | return Redirect::action('UserController@profile', array('user' => 1)); 65 | 66 | 67 | ## Views 68 | 69 | Views คือส่วนที่ใช้เก็บไฟล์ที่ใช้สร้างหน้า html นะครับจะถูกเก็บไว้ที่โฟลเดอร์ `app/views` 70 | ตัวอย่าง view 71 | 72 | 73 | 74 | 75 | 76 |

Hello,

77 | 78 | 79 | 80 | การใช้งาน view เบื้องต้นครับ 81 | 82 | Route::get('/', function() 83 | { 84 | return View::make('greeting', array('name' => 'Taylor')); 85 | }); 86 | 87 | 88 | 89 | **ส่งค่าไปที่ view ครับ** 90 | 91 | $view = View::make('greeting', $data); 92 | 93 | $view = View::make('greeting')->with('name', 'Steve'); 94 | 95 | ในตัวอย่างตัวแปร `$name`จะถูกใช้งานบน View ได้ 96 | 97 | You may also share a piece of data across all views: 98 | 99 | View::share('name', 'Steve'); 100 | 101 | **การส่ง view แทรกเข้าไปในอีก view หนึ่งครับ** 102 | 103 | เราสร้างโฟลเดอร์ขึ้นมาเก็บ view ที่เราจะทำเป็น view ย่อยก่อนตัวอย่าง `app/views/child/view.php` ตัวอย่างการใช้งาน 104 | 105 | $view = View::make('greeting')->nest('child', 'child.view'); 106 | 107 | $view = View::make('greeting')->nest('child', 'child.view', $data); 108 | 109 | ผลที่ออกมาครับ 110 | 111 | 112 | 113 |

Hello!

114 | 115 | 116 | 117 | 118 | 119 | ## View Composers 120 | 121 | View composers คือเมทอดที่ช่วยเราในการจัดการค่าที่เราต้องแสดง ในทุกหน้าของ view 122 | ลดการเขียนโค้ดซ้ำซ้อน 123 | 124 | **ตัวอย่างการใช้งาน** 125 | 126 | View::composer('profile', function($view) 127 | { 128 | $view->with('count', User::count()); 129 | }); 130 | 131 | ตอนนี้ทุกครั้งที่ `profile` view ถูกสร้าง `count` จะถูกส่งขึ้นไปด้วย 132 | 133 | เราสามารถส่งขึ้นไปทีละหลายๆ view ได้ 134 | 135 | View::composer(array('profile','dashboard'), function($view) 136 | { 137 | $view->with('count', User::count()); 138 | }); 139 | 140 | ถ้าเราต้องการทำให้เป็นคลาสเพื่อง่ายต่อการจัดกลุ่ม เราต้องทำแบบนี้ครับ 141 | 142 | View::composer('profile', 'ProfileComposer'); 143 | 144 | สร้างคลาสขึ้นมา 145 | 146 | class ProfileComposer { 147 | 148 | public function compose($view) 149 | { 150 | $view->with('count', User::count()); 151 | } 152 | 153 | } 154 | 155 | แล้วอย่าลืมเพิ่มเข้าไปที่ไฟล์ `composer.json` 156 | 157 | 158 | ## การส่งกลับแบบพิเศษ 159 | 160 | **สร้างการส่งกลับในรูปแบบของ json** 161 | 162 | return Response::json(array('name' => 'Steve', 'state' => 'CA')); 163 | 164 | **สร้างการส่งกลับในรูปแบบของ jsonp** 165 | 166 | return Response::json(array('name' => 'Steve', 'state' => 'CA'))->setCallback(Input::get('callback')); 167 | 168 | **สร้างการส่งกลับในรูปแบบของการดาวน์โหลดไฟล์** 169 | 170 | return Response::download($pathToFile); 171 | 172 | return Response::download($pathToFile, $name, $headers); 173 | -------------------------------------------------------------------------------- /routing.md: -------------------------------------------------------------------------------- 1 | # Routing 2 | 3 | ใช้ในการกำหนดว่าเมื่อเราเรียกลิ้งนี้จะให้ทำอะไรขึ้นบ้าง 4 | 5 | ## Basic Routing 6 | 7 | ในการตั้งค่าเราจะไปที่ `app/routes.php` โดยรูปแบบของฟังก็ชันที่เป็น Route จะเป็นแบบ Closure callback Closure คืออะไรตามไปตามเข้าไปอ่าน [ที่นี่ครับ](http://taqmaninw.com/Closure-ฟังก์ชันนิรนามของ-php) 8 | 9 | **การรับค่าที่เป็น get** 10 | 11 | Route::get('/', function() 12 | { 13 | return 'Hello World'; 14 | }); 15 | 16 | **การรับค่าที่เป็น POST** 17 | 18 | Route::post('foo/bar', function() 19 | { 20 | return 'Hello World'; 21 | }); 22 | 23 | **กำหนด route ในการเรียกพารามิเตอร์ foo ในทุกรูปแบบเมทอด** 24 | 25 | Route::any('foo', function() 26 | { 27 | return 'Hello World'; 28 | }); 29 | 30 | **ลิ้งที่เรียกมาต้องเป็น https เท่านั้น** 31 | 32 | Route::get('foo', array('https', function() 33 | { 34 | return 'Must be over HTTPS'; 35 | })); 36 | 37 | 38 | 39 | 40 | ## Route Parameters 41 | 42 | ตัวอย่างการกำหนดรูปแบบของพารามิเตอร์ 43 | 44 | Route::get('user/{id}', function($id) 45 | { 46 | return 'User '.$id; 47 | }); 48 | 49 | **พารามิเตอร์แบบมีหรือไม่มีก็ได้** 50 | 51 | Route::get('user/{name?}', function($name = null) 52 | { 53 | return $name; 54 | }); 55 | 56 | **กำหนดพารามิเตอร์แบบตายตัว** 57 | 58 | Route::get('user/{name?}', function($name = 'John') 59 | { 60 | return $name; 61 | }); 62 | 63 | **การใช้ regex ตรวจสอบว่าพารามิเตอร์ตรงกับที่กำหนดไว้ไหม** 64 | 65 | Route::get('user/{name}', function($name) 66 | { 67 | // 68 | }) 69 | ->where('name', '[A-Za-z]+'); 70 | 71 | Route::get('user/{id}', function($id) 72 | { 73 | // 74 | }) 75 | ->where('id', '[0-9]+'); 76 | 77 | จะใส่ไปเป็นอาเรย์ก็ได้ 78 | 79 | Route::get('user/{id}/{name}', function($id, $name) 80 | { 81 | // 82 | }) 83 | ->where(array('id' => '[0-9]+', 'name' => '[a-z]+')) 84 | 85 | 86 | ## Route Filters 87 | 88 | คือการกำหนดฟังก์ชันที่ใช้ในการตรวจสอบข้อมูล `auth` ใช้ตรวจว่ามีการล็อกอินไหม, `guest` ตรวจว่ายังไม่ได้ล็อกอิน, และ `csrf`ตรวจว่าเป็นการทำ csrf ไหม.ซึ่งเราจะไปประกาศไว้ที่ `app/filters.php` 89 | 90 | **ตัวอย่างการสร้าง filter** 91 | 92 | Route::filter('old', function() 93 | { 94 | if (Input::get('age') < 200) 95 | { 96 | return Redirect::to('home'); 97 | } 98 | }); 99 | 100 | 101 | 102 | **การใส่ filter ให้ route** 103 | 104 | Route::get('user', array('before' => 'old', function() 105 | { 106 | return 'You are over 200 years old!'; 107 | })); 108 | 109 | **การใส่ route หลายตัว** 110 | 111 | Route::get('user', array('before' => 'auth|old', function() 112 | { 113 | return 'You are authenticated and over 200 years old!'; 114 | })); 115 | 116 | **การกำหนดค่าเฉพาะให้ filter** 117 | 118 | Route::filter('age', function($route, $request, $value) 119 | { 120 | // 121 | }); 122 | 123 | Route::get('user', array('before' => 'age:200', function() 124 | { 125 | return 'Hello World'; 126 | })); 127 | 128 | filter บางตัวเราสั่งให้ทำงานหลังจากที่ route ทำงานไปแล้วเราต้องกำหนดตัวแปร `$response` เพื่อกำหนดค่าที่จะส่งไปให้ตัวฟังก์ชันด้วย 129 | 130 | Route::filter('log', function($route, $request, $response, $value) 131 | { 132 | // 133 | }); 134 | 135 | **Pattern Based Filters** 136 | 137 | เราสามารถกำหนด filter ให้ทำงานเฉพาะเมื่อมีการเรียกตรงกับที่เรากำหนดได้ ตามตัวอย่างเลยครับ. 138 | 139 | Route::filter('admin', function() 140 | { 141 | // 142 | }); 143 | 144 | Route::when('admin/*', 'admin'); 145 | 146 | ตามตัวอย่างเราเพิ่ม filter ชื่อ `admin` เข้ากับทุกลิ้งที่มี `admin/` อยู่ข้างใน 147 | 148 | แล้วก็ยังสามารถกำหนดเมทอดให้ได้ด้วย 149 | 150 | Route::when('admin/*', 'admin', array('post')); 151 | 152 | **Filter Classes** 153 | 154 | ในการกรองขั้นสูงเราสามารถสร้างคลาสขึ้นมาได้เอง แล้วทำการใช้ [IoC Container](/docs/ioc) เรียกใช้คลาสนั้น 155 | 156 | **ตัวอย่างคลาส** 157 | 158 | class FooFilter { 159 | 160 | public function filter() 161 | { 162 | // Filter logic... 163 | } 164 | 165 | } 166 | 167 | **ลงทะเบียนคลาสโดยให้ชื่อที่จะนำไปใช้ว่า foo** 168 | 169 | Route::filter('foo', 'FooFilter'); 170 | 171 | 172 | ## Named Routes 173 | 174 | คือการตั้งชื่อย่อให้กับ route: 175 | 176 | Route::get('user/profile', array('as' => 'profile', function() 177 | { 178 | // 179 | })); 180 | 181 | กำหนดให้ชื่อย่อนี้จะใช้ controller ไหน 182 | 183 | Route::get('user/profile', array('as' => 'profile', 'uses' => 'UserController@showProfile')); 184 | 185 | ตอนนี้เราใช้ชื่อย่อ เพื่อสร้างลิ้งได้เเล้ว 186 | 187 | $url = URL::route('profile'); 188 | 189 | $redirect = Redirect::route('profile'); 190 | 191 | เราใช้เมทอด`currentRouteName` เพื่อดึงชื่อของ Route ที่ทำงานในขณะนี้ได้ 192 | 193 | $name = Route::currentRouteName(); 194 | 195 | 196 | ## Route Groups 197 | 198 | เราสามารถกำหนดกลุ่มให้ Route ได้ทำให้สะดวกมากขึ้น 199 | 200 | Route::group(array('before' => 'auth'), function() 201 | { 202 | Route::get('/', function() 203 | { 204 | // Has Auth Filter 205 | }); 206 | 207 | Route::get('user/profile', function() 208 | { 209 | // Has Auth Filter 210 | }); 211 | }); 212 | 213 | 214 | ## Sub-Domain Routing 215 | 216 | **การสร้าง Route ให้กับโดนเมนย่อย** 217 | 218 | Route::group(array('domain' => '{account}.myapp.com'), function() 219 | { 220 | 221 | Route::get('user/{id}', function($account, $id) 222 | { 223 | // 224 | }); 225 | 226 | }); 227 | 228 | ## Route Prefixing 229 | 230 | ในการกำหนดคำที่ใช้กำหนดกลุ่มของ เราใช้ prefix ในการตรวจสอบ 231 | 232 | **ตัวอย่างการใช้ prefix** 233 | 234 | Route::group(array('prefix' => 'admin'), function() 235 | { 236 | 237 | Route::get('user', function() 238 | { 239 | // 240 | }); 241 | 242 | }); 243 | 244 | 245 | ## Route Model Binding 246 | 247 | คือการผูกโมเดลเขาไปกับ Route โดยใช้เมทอด `Route::model` 248 | 249 | **การใช้งาน** 250 | 251 | Route::model('user', 'User'); 252 | 253 | ต่อมาก็กำหนดให้เมื่อมีการเรียกลิ้งที่มี `{user}`เป็นพารามิเตอร์ 254 | 255 | Route::get('profile/{user}', function(User $user) 256 | { 257 | // 258 | }); 259 | 260 | เราก็จะทำการแทรก `User` instance เข้าไปใน Route ยกตัวอย่าง `profile/1` ถูกเรียก `User` instance ก็จะมี ID = 1. 261 | 262 | 263 | 264 | ถ้าพารามิเตอร์ที่ส่งเข้ามาไม่ตรงกับ `model` ใดๆเราสามารถกำหนดการแสดงข้อผิดพลาดำได้ 265 | 266 | Route::model('user', 'User', function() 267 | { 268 | throw new NotFoundException; 269 | }); 270 | 271 | ต่อมา เมทอด `Route::bind` เป็นการผูกพารามิเตอร์เข้ากับ โมเดล เมื่อมีการส่งค่าเข้าตรงกับ route ที่กำหนดค่าก็จะก็จะถูกส่งมาที่เมทอดนี้ก่อน 272 | 273 | Route::bind('user', function($value, $route) 274 | { 275 | return User::where('name', $value)->first(); 276 | }); 277 | 278 | -------------------------------------------------------------------------------- /schema.md: -------------------------------------------------------------------------------- 1 | # Schema Builder 2 | 3 | คลาส `Schema`ใช้ในการจัดการตาราง มักใช้ร่วมกับคำสั่ง migration 4 | 5 | 6 | ## สร้างและลบตาราง 7 | 8 | สร้างตารางใหม่ด้วยเมทอด `Schema::create` ตามตัวอย่างเลยครับ 9 | 10 | Schema::create('users', function($table) 11 | { 12 | $table->increments('id'); 13 | }); 14 | 15 | เมทอดตัวแรกคือชื่อตาราง พารามิเตอร์ที่สองคือ `Closure` ที่จะรับออปเจคของคลาส `Blueprint` ในการสร้างตาราง 16 | 17 | จะเปลี่ยนชื่อตารางใช้เมทอด`rename` 18 | 19 | Schema::rename($from, $to); 20 | 21 | ในการเลือกการเชื่อมต่อกรณีเรามีหลายฐานข้อมูลใช้เมทอด `Schema::connection` 22 | 23 | Schema::connection('foo')->create('users', function($table) 24 | { 25 | $table->increments('id'): 26 | }); 27 | 28 | จะลบตารางใช้เมทอด `Schema::drop` 29 | 30 | Schema::drop('users'); 31 | 32 | Schema::dropIfExists('users'); 33 | 34 | 35 | ## เพิ่มคอลัมน์ 36 | 37 | ในการแก้ไขตารางเราใช้คำสั่ง `Schema::table` 38 | 39 | Schema::table('users', function($table) 40 | { 41 | $table->string('email'); 42 | }); 43 | 44 | ตารางคำสั่งต่างของคลาส `Blueprint` ครับ 45 | 46 | Command | Description 47 | ------------- | ------------- 48 | `$table->increments('id');` | ใช้ทำ auto_increment ให้ (primary key). 49 | `$table->string('email');` | ค่าที่ออกมาจะเป็น VARCHAR ความยาว 255 50 | `$table->string('name', 100);` | ค่าที่ออกมาจะเป็น VARCHAR ความยาว 100 51 | `$table->integer('votes');` | ค่าที่ออกมาจะเป็น interger 52 | `$table->bigInteger('votes');` | ค่าที่ออกมาจะเป็น bigint 53 | `$table->smallInteger('votes');` | ค่าที่ออกมาจะเป็นSMALLINT 54 | `$table->float('amount');` | ค่าที่ออกมาจะเป็น FLOAT 55 | `$table->decimal('amount', 5, 2);` | ค่าที่ออกมาจะเป็น decimal ที่มีค่าระหว่าง 5,2 56 | `$table->boolean('confirmed');` | ค่าที่ออกมาจะเป็น BOOLEAN 57 | `$table->date('created_at');` | ค่าที่ออกมาจะเป็น DATE 58 | `$table->dateTime('created_at');` | ค่าที่ออกมาจะเป็นDATETIME 59 | `$table->time('sunrise');` | ค่าที่ออกมาจะเป็น TIME 60 | `$table->timestamp('added_on');` | ค่าที่ออกมาจะเป็น TIMESTAMP 61 | `$table->timestamps();` | เพิ่มคอลัมน์ **created\_at** และ **updated\_at** columns 62 | `$table->softDeletes();` | เพิ่มคอลัมน์ **deleted\_at** 63 | `$table->text('description');` | ค่าที่ออกมาจะเป็น TEXT 64 | `$table->binary('data');` | ค่าที่ออกมาจะเป็น BLOB 65 | `$table->enum('choices', array('foo', 'bar'));` | ค่าที่ออกมาจะเป็น ENUM 66 | `->nullable()` | อนุญาตให้เป็นค่าว่างได้ 67 | `->default($value)` | สร้างค่าเริ่มต้น 68 | `->unsigned()` | เลี่ยน INTEGER เป็น UNSIGNED 69 | 70 | ถ้าเราใช้ MySQL dสามารถใช้เมทอด `after` ทำการเรียงลำดับคอลัมน์ 71 | 72 | **ตัวอย่าง** 73 | 74 | $table->string('name')->after('email'); 75 | 76 | 77 | ## เปลี่ยนชื่อ Columns 78 | 79 | ใช้เมทอด `renameColumn` ครับ 80 | 81 | **ตัวอย่าง** 82 | 83 | Schema::table('users', function($table) 84 | { 85 | $table->renameColumn('from', 'to'); 86 | }); 87 | 88 | > **หมายเหตุ:** คอลัมน์ชนิด `enum` ไม่สนับสนุน 89 | 90 | 91 | ## ลบ Columns 92 | 93 | **ตัวอย่าง** 94 | 95 | Schema::table('users', function($table) 96 | { 97 | $table->dropColumn('votes'); 98 | }); 99 | 100 | **ลบหลายๆ คอลัมน์** 101 | 102 | Schema::table('users', function($table) 103 | { 104 | $table->dropColumn('votes', 'avatar', 'location'); 105 | }); 106 | 107 | 108 | ## ตรวจว่าตารางมีอยู่ไหม 109 | 110 | **ตรวจว่าตารางมีอยู่ไหม** 111 | 112 | if (Schema::hasTable('users')) 113 | { 114 | // 115 | } 116 | 117 | **ตรวจว่าคอลัมน์มีอยู่ไหม** 118 | 119 | if (Schema::hasColumn('users', 'email')) 120 | { 121 | // 122 | } 123 | 124 | 125 | ## เพิ่ม Indexes 126 | 127 | **สร้างทั้ง Column และ Index** 128 | 129 | $table->string('email')->unique(); 130 | 131 | 132 | Command | Description 133 | ------------- | ------------- 134 | `$table->primary('id');` | เพิ่ม primary key 135 | `$table->primary(array('first', 'last'));` | เพิ่ม composite keys 136 | `$table->unique('email');` | เพิ่ม unique index 137 | `$table->index('state');` | เพิ่ม basic index 138 | 139 | 140 | ## Foreign Keys คีย์เชื่อม 141 | 142 | 143 | **ตัวอย่างการเพิ่มคีย์เชื่อม** 144 | 145 | $table->foreign('user_id')->references('id')->on('users'); 146 | 147 | ในตัวอย่างเราทำการให้คอลัมน์ `user_id`อ้างอิงกับคอลัมน์ `id` บนตาราง`users` 148 | 149 | เราสามารถเสริมคำสั่ง "on delete" และ "on update" เข้าไปเหมือนตัวอย่าง 150 | 151 | $table->foreign('user_id') 152 | ->references('id')->on('users') 153 | ->onDelete('cascade'); 154 | 155 | ในการลบใช้เมทอด `dropForeign` ตัวอย่าง 156 | 157 | $table->dropForeign('posts_user_id_foreign'); 158 | 159 | > **หมายเหตุ:** ให้ชนิดของคอลัมน์ที่เป็นคีย์เชื่อมให้เป็น `unsigned` ทุกครั้งกรณีที่เชื่อมไปยัง คอลัมน์ที่เป็น interger และเป็น auto_increment ครับ 160 | 161 | 162 | ## ลบ Indexes 163 | 164 | ในการลบคีย์เชื่อม larave ตั้งค่าคีย์เป็นค่าเริ่มต้นให้เเล้วนะครับ โดยอ้างอิงจากชนิดกับชื่อของตารง 165 | 166 | Command | Description 167 | ------------- | ------------- 168 | `$table->dropPrimary('users_id_primary');` | ลบคีย์หลักจากตาราง users 169 | `$table->dropUnique('users_email_unique');` | ลบคีย์เดี่ยวจากตาราง users 170 | `$table->dropIndex('geo_state_index');` | ลบคีย์ทั่วไปจาก ตาราง geo 171 | 172 | ##ชนิดของตาราง 173 | 174 | การเซตชนิดของตารางเราใช้เมทอด `engine` ตามตัวอย่างครับ 175 | 176 | Schema::create('users', function($table) 177 | { 178 | $table->engine = 'InnoDB'; 179 | 180 | $table->string('email'); 181 | }); 182 | -------------------------------------------------------------------------------- /security.md: -------------------------------------------------------------------------------- 1 | # Security 2 | คลาสนี้ใช้ในการสร้างระบบรักษาความปลอดภัยต่างอย่างเช่น การเข้ารหัสเพื่อใช้ใน password,session,cookie 3 | 4 | 5 | 6 | ## การเก็บรหัสผ่าน 7 | 8 | Class `Hash` ของ `laravel` ใช้ส่วนขยาย `Bcrypt` ของ php มาพัฒนาต่อยอด 9 | 10 | **การสร้างค่า hash** 11 | 12 | $password = Hash::make('secret'); 13 | 14 | **การตรวจสอบค่า hash** 15 | 16 | if (Hash::check('secret', $hashedPassword)) 17 | { 18 | // The passwords match... 19 | } 20 | 21 | **ตรวจว่า password ต้องการเข้ารหัสอีกครั้ง กรณีลืมรหัสผ่าน** 22 | 23 | if (Hash::needsRehash($hashed)) 24 | { 25 | $hashed = Hash::make('secret'); 26 | } 27 | 28 | 29 | ## การยืนยันตัวบุคคล 30 | 31 | การล็อกอิน laravel เตรียมเมทอด `Auth::attempt` มาให้ตัวอย่างการใช้งาน 32 | 33 | if (Auth::attempt(array('email' => $email, 'password' => $password))) 34 | { 35 | return Redirect::intended('dashboard'); 36 | } 37 | 38 | ค่า `email` เราสามารถเปลี่ยนไปตามใจเราได้ครับ ส่วนเมทอด `Redirect::intended` ใช้ส่งผู้ใช้งานกลับไปที่ลิ้งที่เข้าเรียกมาครับ 39 | 40 | เมื่อเมทอด `attempt` ถูกเรียก event `auth.attempt` จะถูกเรียกและ event `auth.login` จะถูกเรียกเมื่อการเข้าสู่ระบบสำเร็จ 41 | 42 | 43 | **ตรวจสอบว่ามีการล็อกอินค้างอยู่ไหม** 44 | 45 | if (Auth::check()) 46 | { 47 | // The user is logged in... 48 | } 49 | 50 | 51 | **ตัวอย่างการปรับปรุงเมทอด attempt ให้สามารถทำการจำชื่อผู้ใช้กับรหัสผ่านได้** 52 | 53 | if (Auth::attempt(array('email' => $email, 'password' => $password), true)) 54 | { 55 | // The user is being remembered... 56 | } 57 | 58 | 59 | 60 | **กากำหนดเงื่อนไขตอนล็อกอิน** 61 | 62 | if (Auth::attempt(array('email' => $email, 'password' => $password, 'active' => 1))) 63 | { 64 | // ถ้า active เป็น 1 แสดงว่ายืนยันอีเมล์แล้ว 65 | } 66 | 67 | 68 | **การเข้าถึงเข้อมูลคนที่ล็อกอิน** 69 | 70 | $email = Auth::user()->email; 71 | 72 | ใช้เมทอด `loginUsingId` เพื่อดึง Id ของคนที่ล็อกอินมา 73 | 74 | Auth::loginUsingId(1); 75 | 76 | สมมุตว่าเรากำหนดว่าการเปลี่ยนแปลงเลขบัตรเครดิตต้องใช้รหัสผ่านยืนยันเพิ่มเติม เมทอด `validate` สามารถทำงานนี้ให้เราได้ 77 | 78 | **การใช้งานการยืนยันตัวตนโดยไม่ไดเข้าสู่ระบบ** 79 | 80 | if (Auth::validate($credentials)) 81 | { 82 | // 83 | } 84 | 85 | 86 | 87 | **การล็อกอินแบบไม่มี session หรือ cookies** 88 | 89 | if (Auth::once($credentials)) 90 | { 91 | // 92 | } 93 | 94 | **เมทอดที่ใช้ล็อกเอาท์** 95 | 96 | Auth::logout(); 97 | 98 | 99 | ## การจำลองการล็อกอิน 100 | 101 | การล็อกอินแบบ ที่เราจำลองขึ้้นมาเองครับ เมทอด`login` ใช้ค่าจากฐานข้อมูลมาล็อกอินได้ทันทีเลย 102 | 103 | $user = User::find(1); 104 | 105 | Auth::login($user); 106 | 107 | 108 | ### การป้องกัน CSRF 109 | 110 | 111 | **ทำการแนบค่า token เข้ากับฟอร์ม** 112 | 113 | 114 | 115 | **ตรวจสอบค่า token ที่ถูกส่งมา** 116 | 117 | Route::post('register', array('before' => 'csrf', function() 118 | { 119 | return 'You gave a valid CSRF token!'; 120 | })); 121 | 122 | 123 | ## HTTP Basic Authentication 124 | 125 | laravel เตรียม filter ชื่อ `auth.basic` เพื่อตรวจว่า มีการล็อกอินไหม 126 | 127 | **ตัวอย่าง** 128 | 129 | Route::get('profile', array('before' => 'auth.basic', function() 130 | { 131 | // Only authenticated users may enter... 132 | })); 133 | 134 | โดยค่าเริ่มต้นเเล้วเมทอด `basic` ใช้คอลัมน์ email ในการตรวจสอบ ถ้าเราจะเปลี่ยนก็ใช้ 135 | 136 | return Auth::basic('username'); 137 | 138 | laravel เตรียมฟังก์ชัน `Oncebasic` มาเพื่อการล็อกอินแบบไม่สร้าง session ไว้เหมาะกับการให้ ผู้ใช้งานใช้ในกรณีไปล็อกอินเครื่องที่ไม่ใช่ของตัวเอง 139 | 140 | **ตัวอย่าง** 141 | 142 | Route::filter('basic.once', function() 143 | { 144 | return Auth::onceBasic(); 145 | }); 146 | 147 | 148 | ## การจัดการการลืมรหัสผ่าน 149 | การลืมรหัสผ่านและการสร้างใหม่ 150 | ### ส่งรหัสผ่านใหม่ 151 | 152 | laravel เตรียมการมาให้เราสามารถสร้างระบบการส่และเปลี่ยนรหัสผ่าน ให้เราโดยการให้ `User` model ทำการสืบทอด `Illuminate\Auth\Reminders\RemindableInterface`. 153 | 154 | **การใช้งาน RemindableInterface** 155 | 156 | class User extends Eloquent implements RemindableInterface { 157 | 158 | public function getReminderEmail() 159 | { 160 | return $this->email; 161 | } 162 | 163 | } 164 | 165 | ต่อมาเราก็ต้องสร้างตารางให้ระบบลืมรหัสผ่านก่อนโดย `php artisan auth:reminders` 166 | 167 | **สร้างตัว migration ของตารางลืมรหัส** 168 | 169 | php artisan auth:reminders 170 | 171 | php artisan migrate 172 | 173 | การส่งรหัสใช้เมทอด `Password::remind` 174 | 175 | **ตัวอย่างการใช้งาน** 176 | 177 | Route::post('password/remind', function() 178 | { 179 | $credentials = array('email' => Input::get('email')); 180 | 181 | return Password::remind($credentials); 182 | }); 183 | 184 | 185 | > **หมายเหตุ:** เราต้องสร้าง view ที่ชื่อ `auth.reminder.email`เพื่อรับ email เองนะครับ 186 | 187 | เราสามารถส่งข้อความเพิ่มเติมให้ผู้ใช้โดยส่งพารามิเตอร์ไป `$message` ไปในฟังก์ชัน `remind` 188 | 189 | return Password::remind($credentials, function($message, $user) 190 | { 191 | $message->subject('Your Password Reminder'); 192 | }); 193 | 194 | โดยค่าเริ่มต้นเเล้วเมทอด `remind` จะส่งกลับมาที่หน้าที่เรียกใช้ ถ้าเกิดข้อผิดพลาดขึ้น ตัวแปร `error`จะมีค่าขึ้นใน session ส่วนเมื่อสำเร็จตัวแปร `success` ก็จะปรากฏขึ้นมาใน session แทน หน้าตาของหน้า `auth.reminder.email` ควรเป็นแบบนี้ครับ 195 | 196 | @if (Session::has('error')) 197 | {{ trans(Session::get('reason')) }} 198 | @elseif (Session::has('success')) 199 | An e-mail with the password reset has been sent. 200 | @endif 201 | 202 | 203 | 204 | 205 | ### การรีเซตรหัสผ่าน 206 | 207 | การสร้าง route เพื่อรับการที่ผู้ใช้งานกดลิ้งทำการรีเซตรหัสผ่าน 208 | 209 | Route::get('password/reset/{token}', function($token) 210 | { 211 | return View::make('auth.reset')->with('token', $token); 212 | }); 213 | 214 | หน้า view ที่ทำการให้ผู้ใช้งานทำการเปลี่ยนรหัสผ่าน 215 | 216 | @if (Session::has('error')) 217 | {{ trans(Session::get('reason')) }} 218 | @endif 219 | 220 | 221 | 222 | 223 | 224 | 225 | ตัวอย่างการสร้าง route เพื่อทำการรับค่ารหัสผ่านใหม่ 226 | 227 | Route::post('password/reset/{token}', function() 228 | { 229 | $credentials = array('email' => Input::get('email')); 230 | 231 | return Password::reset($credentials, function($user, $password) 232 | { 233 | $user->password = Hash::make($password); 234 | 235 | $user->save(); 236 | 237 | return Redirect::to('home'); 238 | }); 239 | }); 240 | 241 | ถ้าการเปลี่ยนรหัสผ่านสำเร็จ `User` instance และรหัสผ่านใหม่จะถูกเก็บลงฐานข้อมูลและ ส่งกลับไปหน้า `home` 242 | 243 | 244 | ## Encryption 245 | 246 | Laravel เตรียมการเข้ารหัสแบบ AES-256 โดยส่วนเสริม mcrypt ของ PHP มาให้เเล้ว 247 | 248 | **กาเข้ารหัส** 249 | 250 | $encrypted = Crypt::encrypt('secret'); 251 | 252 | > **Note:** มั่นใจว่าเราเปลี่ยนค่า `key` ตรงที่ `app/config/app.php` ไม่งั้นการเข้ารหัสจะไม่ค่อยปลอดภัยครับ 253 | 254 | **การถอดรหัส** 255 | 256 | $decrypted = Crypt::decrypt($encryptedValue); 257 | 258 | 259 | 260 | **การกำหนดรูปแบบต่างๆ** 261 | 262 | Crypt::setMode('ctr'); 263 | 264 | Crypt::setCipher($cipher); 265 | -------------------------------------------------------------------------------- /session.md: -------------------------------------------------------------------------------- 1 | # Session 2 | 3 | 4 | 5 | ## การตั้งค่าเบื้องต้น 6 | 7 | ไฟล์ที่ใช้ตั้งค่าจะอยู่ที่ `app/config/session.php`.โดยชนิดของ session จะมีหลายชนิดนะครับแต่โดยเริ่มต้นแล้วจะเป็น `native` ส่วนการตั้งค่าอื่นๆ ก็จะเป็นเวลาที่จะให้ seesion มีชีวิตอยู่ ที่อยู่ของ seesion ชื่อของ cookie และอื่นๆ ครับ 8 | 9 | 10 | ##การใช้งาน 11 | 12 | **การสร้างค่าแล้วเก็บใน session** 13 | 14 | Session::put('key', 'value'); 15 | 16 | **ดึงค่าจาก Session** 17 | 18 | $value = Session::get('key'); 19 | 20 | **ดึงค่าเริ่มต้นของ session** 21 | 22 | $value = Session::get('key', 'default'); 23 | 24 | $value = Session::get('key', function() { return 'default'; }); 25 | 26 | **ตรวจว่ามีค่านี้ใน Session หรือไม่** 27 | 28 | if (Session::has('users')) 29 | { 30 | // 31 | } 32 | 33 | **ลบค่าออกจาก Session** 34 | 35 | Session::forget('key'); 36 | 37 | **ลบค่าทั้งหมด Session** 38 | 39 | Session::flush(); 40 | 41 | **สร้าง Session ID อีกครั้ง** 42 | 43 | Session::regenerate(); 44 | 45 | 46 | ## Flash Data 47 | 48 | หลายๆครั้งเราต้องฝากค่าไว้ใน session เพื่อนำไปใช้ในการทำงานต่อไป สามารถใช้เมทอด `Session::flash` ตัวอย่าง 49 | 50 | Session::flash('key', 'value'); 51 | 52 | **ทำการเรียกใช้ falsh message อีกครั้ง** 53 | 54 | Session::reflash(); 55 | 56 | **ทำการเรียกใช้งานอีกครั้งเฉพาะค่า** 57 | 58 | Session::keep(array('username', 'email')); 59 | 60 | 61 | ## การเก็บ session ในฐานข้อมูล 62 | 63 | เมื่อเราใช้ฐานข้อมูลเก็บ session เราต้องสร้างตารางขึ้นมาก่อน ด้วยคำสั่ง`Schema` ดังตัวอย่าง 64 | 65 | Schema::create('sessions', function($table) 66 | { 67 | $table->string('id')->unique(); 68 | $table->text('payload'); 69 | $table->integer('last_activity'); 70 | }); 71 | 72 | ตอนนี้เราก็ใช้คำสั่ง `php artisab session:table` เป็นอันจบครับ -------------------------------------------------------------------------------- /templates.md: -------------------------------------------------------------------------------- 1 | # Templates 2 | 3 | 4 | ## Controller Layouts 5 | 6 | เราใช้ตัวแปร `layout` เพื่อกำหนดเลเอาท์หลักให้กับ controller ครับ 7 | 8 | **ตัวอย่างการใช้งาน** 9 | 10 | class UserController extends BaseController { 11 | 12 | /** 13 | * The layout that should be used for responses. 14 | */ 15 | protected $layout = 'layouts.master'; 16 | 17 | /** 18 | * ส่งวิวเฉพาะไปให้เลเอาท์หลัก 19 | */ 20 | public function showProfile() 21 | { 22 | $this->layout->content = View::make('user.profile'); 23 | } 24 | 25 | } 26 | 27 | 28 | ## Blade Templating 29 | 30 | Blade template คือคลาสที่ใช้ในการเขียน html ขึ้นมาด้วย php ทำให้เราสามารถสร้าง html ที่มีโครงสร้างซับซ้อนได้ การจะใช้นั้นต้องตั้งชื่อไฟล์เป็น `ชื่อ view.blade.php` 31 | 32 | **ตัวอย่างที่ยังใช้ html อยู่** 33 | 34 | 35 | 36 | 37 | 38 | @section('sidebar') 39 | This is the master sidebar. 40 | @show 41 | 42 |
43 | @yield('content') 44 |
45 | 46 | 47 | 48 | **ใช้ blade ในการสร้างเลเอาท์ทั้งหมด** 49 | 50 | @extends('layouts.master') 51 | 52 | @section('sidebar') 53 | @parent 54 | 55 |

This is appended to the master sidebar.

56 | @stop 57 | 58 | @section('content') 59 |

This is my body content.

60 | @stop 61 | 62 | `extend` ใช้ในการดึงค่าจากเลเอาท์อื่นมาใช้ `@parent` ทำให้เราสามารถใช้ view อื่นแทรกเข้ามาได้ `@section` ก็ใช้งานโดยการแทรก html จากไฟล์อื่นเข้าไป 63 | 64 | 65 | ## การใช้งานฟังก์ชัน php ใน blade 66 | 67 | **การแสดงข้อมูล การแทรกข้อมูล** 68 | 69 | Hello, {{ $name }}. 70 | 71 | The current UNIX timestamp is {{ time() }}. 72 | 73 | ทีนี้เราก์ใช้ syntax แบบสั้นๆ ในการแสดงผลจาก server ได้เเล้ว 74 | 75 | Hello, {{{ $name }}}. 76 | 77 | 78 | **การใช้ if** 79 | 80 | @if (count($records) === 1) 81 | I have one record! 82 | @elseif (count($records) > 1) 83 | I have multiple records! 84 | @else 85 | I don't have any records! 86 | @endif 87 | 88 | @unless (Auth::check()) 89 | You are not signed in. 90 | @endunless 91 | 92 | **การใช้ Loops** 93 | 94 | @for ($i = 0; $i < 10; $i++) 95 | The current value is {{ $i }} 96 | @endfor 97 | 98 | @foreach ($users as $user) 99 |

This is user {{ $user->id }}

100 | @endforeach 101 | 102 | @while (true) 103 |

I'm looping forever.

104 | @endwhile 105 | 106 | **การแทรก Views** 107 | 108 | @include('view.name') 109 | 110 | **การแสดงภาษา** 111 | 112 | @lang('language.line') 113 | 114 | @choice('language.line', 1); 115 | 116 | **การทำคอมเม้น** 117 | 118 | {{-- This comment will not be in the rendered HTML --}} 119 | -------------------------------------------------------------------------------- /testing.md: -------------------------------------------------------------------------------- 1 | # Unit Testing 2 | 3 | Laravel สร้างขึ้นมาด้วยแนวคิดของการทดสอบเป็นเบื้องต้นอยู่เเล้วครับ โดยหลักแล้วจะสนับสนุนไลบราลี่ PHPUnit เป็นพื้นฐาน และ `phpunit.xml`ไฟล์ได้ถูกเตรียมการเอาไว้ให้แล้ว. Laravel เตรียมคลาส Symfony HttpKernel, DomCrawler, และ BrowserKit components ที่อนุญาตให้เราจำลองบราวเซอร์ขึ้นมาเเละเข้าไปแก้ไขไฟล์ html ได้ 4 | ตัวอย่างไฟล์อยู่ที่โฟลเดอร์ `app/tests` 5 | 6 | ## Defining & Running Tests 7 | 8 | การสร้างไฟล์สำหรับทดสอบนั้นเราจะไปสร้างที่โฟลเดอร์ `app/tests` สร้างคลาสที่สืบทอดคลาส `TestCase`. 9 | 10 | **ตัวอย่างคลาสสำหรับใช้ทดสอบ** 11 | 12 | class FooTest extends TestCase { 13 | 14 | public function testSomethingIsTrue() 15 | { 16 | $this->assertTrue(true); 17 | } 18 | 19 | } 20 | เราจะทำการทดสอบโดยรัน `phpunit` บน commandline 21 | 22 | > **หมายเหตุ:** ถ้าคุณประกาศเมทอด `setUp` มั่นใจว่าได้เรียก `parent::setUp`แล้ว 23 | 24 | 25 | ## สภาวะการตั้งค่าสำหรับการทดสอบ 26 | 27 | เมื่อใช้งาน unit tests, Laravel จะทำการเปลี่ยนการสภาวะการตั้งค่าให้ไปเป็น `testing`. และจะตัดการทำงานของ `session` และ `cache` หมายความว่าจะไม่มีแคชและ session เกิดขึ้นระหว่างการทดสอบ 28 | 29 | 30 | ## การเรียก Routes ในขณะทดสอบ 31 | 32 | 33 | **ตัวอย่างการเรียก Route ในขณะทำกาารทดสอบ** 34 | 35 | $response = $this->call('GET', 'user/profile'); 36 | 37 | $response = $this->call($method, $uri, $parameters, $files, $server, $content); 38 | 39 | เราสามารถตรวจสอบออปเจค `Illuminate\Http\Response` 40 | 41 | $this->assertEquals('Hello World', $response->getContent()); 42 | 43 | 44 | **ตัวอย่างการเรียก Controller ในขณะทดสอบ** 45 | 46 | $response = $this->action('GET', 'HomeController@index'); 47 | 48 | $response = $this->action('GET', 'UserController@profile', array('user' => 1)); 49 | 50 | เมทอด `getContent` จะส่งค่าเป็นตัวอักษรกลับคืนมา `View` เราสามารถเข้าถึงได้ด้วยตัวแปร `original` 51 | 52 | $view = $response->original; 53 | 54 | $this->assertEquals('John', $view['name']); 55 | 56 | ถ้าจะเรียก HTTPS route,เราต้องใช้เมทอด`callSecure` 57 | 58 | $response = $this->callSecure('GET', 'foo/bar'); 59 | 60 | ### DOM Crawler 61 | 62 | คลาส DOM Crawler ทำให้เราสามารถตรวจสอบ html ที่ถูกสร้างขึ้นมาระหว่างการทดสอบได้ ตัวอย่างการใช้ 63 | 64 | $crawler = $this->client->request('GET', '/'); 65 | 66 | $this->assertTrue($this->client->getResponse()->isOk()); 67 | 68 | $this->assertCount(1, $crawler->filter('h1:contains("Hello World!")')); 69 | 70 | 71 | ## Mocking Facades 72 | 73 | เมื่อเราทำการทดสอบ,เราจะทำการจำลองในการเรีกคลาส Facade ตัวอย่างเราจะทำการเรียก controller 74 | 75 | public function getIndex() 76 | { 77 | Event::fire('foo', array('name' => 'Dayle')); 78 | 79 | return 'All done!'; 80 | } 81 | 82 | เราสามารถจำลองคลาส`Event`โดยใช้เมทอด `shouldReceive` 83 | 84 | **การจำลองคลาส Facade** 85 | 86 | public function testGetIndex() 87 | { 88 | Event::shouldReceive('fire')->once()->with(array('name' => 'Dayle')); 89 | 90 | $this->call('GET', '/'); 91 | } 92 | 93 | > **หมายเหตุ:** คุณไม่ควรจำลองคลาส `Facade Request` ใช้เมทอด `call` ดีกว่าครับ 94 | 95 | 96 | ## Framework Assertions 97 | 98 | เมทอด `assert` ใช้ในการตรวจสอบว่าค่าที่ออกมาตรงกับที่เราคาดหวังไว้ไหม 99 | 100 | **คาดหวังว่าค่าที่ส่งมาจะไม่ผิดพลาด** 101 | 102 | public function testMethod() 103 | { 104 | $this->call('GET', '/'); 105 | 106 | $this->assertResponseOk(); 107 | } 108 | 109 | **คาดหวังว่าจะเป็น 403** 110 | 111 | $this->assertResponseStatus(403); 112 | 113 | **คาดหวังว่าฟังก์ชันจะส่งกลับไปที่ route** 114 | 115 | $this->assertRedirectedTo('foo'); 116 | 117 | $this->assertRedirectedToRoute('route.name'); 118 | 119 | $this->assertRedirectedToAction('Controller@method'); 120 | 121 | **คาดหวังว่าในหน้า view จะมีค่า** 122 | 123 | public function testMethod() 124 | { 125 | $this->call('GET', '/'); 126 | 127 | $this->assertViewHas('name'); 128 | $this->assertViewHas('age', $value); 129 | } 130 | 131 | **คาดหวังว่าใน session จะมีค่า** 132 | 133 | public function testMethod() 134 | { 135 | $this->call('GET', '/'); 136 | 137 | $this->assertSessionHas('name'); 138 | $this->assertSessionHas('age', $value); 139 | } 140 | 141 | 142 | ## Helper Methods 143 | 144 | คลาส `TestCase` มีเมทอดช่วยให้เราทำการทดสอบได้ง่ายๆ เยอะเลยครับ. 145 | 146 | เมทอด `be`ใช้ในการจำลองการล็อกอิน 147 | 148 | **ตัวอย่าง** 149 | 150 | $user = new User(array('name' => 'John')); 151 | 152 | $this->be($user); 153 | 154 | 155 | **ทำการเพิ่มข้อมูลลงฐานข้อมูลในขณะทดสอบ** 156 | 157 | $this->seed(); 158 | 159 | $this->seed($connection); 160 | 161 | -------------------------------------------------------------------------------- /validation.md: -------------------------------------------------------------------------------- 1 | # Validation 2 | 3 | คือการตรวจสอบค่าต่างๆ ที่ป้อนเข้ามา หรือระหว่างการทำงานของฟังก์ชันต่างๆ โดยจะแสดงข้อผิดพลาดให้เราด้วย โดยคลาสที่ทำหน้าที่นั้นชื่อ Validator ครับ 4 | 5 | 6 | ## การใช้งานเบื้องต้น 7 | 8 | **การใช้งานคลาส validator** 9 | 10 | $validator = Validator::make( 11 | array('name' => 'Dayle'), 12 | array('name' => 'required|min:5') 13 | ); 14 | 15 | อาเรย์ตัวแรกคือข้อมูลที่เราจะทำการตรวจนั้นเอง ตัวที่สองคือรูปแบบที่เราต้องการ 16 | การใช้เครื่องหมาย | การตรวจสอบออกเป็นหลายๆ แบบ 17 | 18 | **ใช้อาเรย์ในการกำหนดกฏ** 19 | 20 | $validator = Validator::make( 21 | array('name' => 'Dayle'), 22 | array('name' => array('required', 'min:5')) 23 | ); 24 | 25 | คลาส `Validator` จะสร้างเมทอด ชื่อ `fails` (หรือ `passes`) เพื่อตรวจสอบผล 26 | 27 | if ($validator->fails()) 28 | { 29 | // The given data did not pass validation 30 | } 31 | 32 | ถ้าไม่ผ่านเราสามารถดึงข้อความแสดงข้อผิดพลาดได้. 33 | 34 | $messages = $validator->messages(); 35 | 36 | เมทอด `failed` ใช้ในการเข้าถึงกฏที่เราตั้งไว้ 37 | 38 | $failed = $validator->failed(); 39 | 40 | 41 | 42 | ## การจัดการข้อความแสดงข้อผิดพลาด 43 | 44 | เมื่อเรียกเมทอด `messages` บนตัว `Validator` instance,เราจะได้รับ `MessageBag` instance ที่จะมีเมทอดให้เราจัดการข้อความ 45 | 46 | **แสดงข้อความแสดงข้อผิดพลาดเฉพาะตัวแรก** 47 | 48 | echo $messages->first('email'); 49 | 50 | **รับข้อความแสดงข้อผิดพลาดทั้งหมด** 51 | 52 | foreach ($messages->get('email') as $message) 53 | { 54 | // 55 | } 56 | 57 | **รับข้อความแสดงข้อผิดพลาดจากทุคอลัมน์** 58 | 59 | foreach ($messages->all() as $message) 60 | { 61 | // 62 | } 63 | 64 | **ตรวจว่ามีข้อความแสดงข้อผิดพลาดจากคอลัมน์ eamil ไหม** 65 | 66 | if ($messages->has('email')) 67 | { 68 | // 69 | } 70 | 71 | **รับข้อความแสดงข้อผิดพลาดโดยใส่รูปแบบให้ด้วย** 72 | 73 | echo $messages->first('email', '

:message

'); 74 | 75 | > **หมายเหตุ:** โดยเริ่มต้น, รูปแบบข้อความจะถูกจัดในรูปแบบที่นำไปใช้งานร่วมกับ twiiter bootstrap ได้. 76 | 77 | **รับข้อความแสดงข้อผิดพลาดทั้งหมดพร้อมใส่รูปแบบ** 78 | 79 | foreach ($messages->all('
  • :message
  • ') as $message) 80 | { 81 | // 82 | } 83 | 84 | 85 | ## การแสดงข้อความแสดงข้อผิดพลาดบน view 86 | 87 | ตัวอย่างนี้เราจะส่งข้อความแสดงข้อผิดพลาด ไปให้ view 88 | 89 | Route::get('register', function() 90 | { 91 | return View::make('user.register'); 92 | }); 93 | 94 | Route::post('register', function() 95 | { 96 | $rules = array(...); 97 | 98 | $validator = Validator::make(Input::all(), $rules); 99 | 100 | if ($validator->fails()) 101 | { 102 | return Redirect::to('register')->withErrors($validator); 103 | } 104 | }); 105 | 106 | ถ้าการตรวจสอบไม่ผ่านเราจะใช้เมทอด `withErrors` ส่งข้อความแสดงข้อผิดพลาด 107 | ขึ้นไปบน View ด้วย 108 | 109 | **ไม่ควรส่งข้อความแสดงข้อผิดพลาด ไปบน Route ทีเป็น method GET เพราะ laravel จะตรวจสอบข้อผิดพลาดบน session ทุกคำร้องขอ** 110 | 111 | เมื่อทำการรีไดเรคเราสามารถเข้าถึงข้อความแสดงข้อผิดพลาด โดยใชตัวแปร`$errors` ดังตัวอย่างครับ 112 | 113 | first('email'); ?> 114 | 115 | 116 | ## กฏในการตรวจสอบที่ laravel เตรียมไว้ 117 | 118 | 119 | 120 | #### accepted 121 | 122 | ค่าทีจะผ่านคือ _yes_, _on_, or _1_.เหมาะสำหรับใช้ในการตรวจสอบว่ายอมรับ "Terms of Service" ไหม 123 | 124 | 125 | #### active_url 126 | 127 | ตรวจสอบว่าลิ้งตายยัง โดยใช้ `checkdnsrr` ซึ่งเป็น PHP function. 128 | 129 | 130 | #### after:_date_ 131 | 132 | ตรวจสอบว่าค่าที่ส่งมาเป็นมีรูปแบบของเวลาหลักจากใช้ `strtotime` อยู่หลังสุดแปลงไหม 133 | 134 | 135 | #### alpha 136 | 137 | ตรวจสอบว่าค่าที่ส่งมาเป็นรูปแบบของตัวอักษรต่างๆ ไหม 138 | 139 | 140 | #### alpha_dash 141 | 142 | ตรวจสอบว่าค่าที่ส่งมาเป็นรูปแบบของตัวเลขที่มีเครื่องหมาย _ รวมอยู่ด้วยไหม 143 | 144 | 145 | #### alpha_num 146 | 147 | ตรวจสอบว่าค่าที่ส่งมาเป็นรูปแบบของตัวเลขไหม 148 | 149 | 150 | #### before:_date_ 151 | 152 | ตรวจสอบว่าค่าที่ส่งมาเป็นมีรูปแบบของเวลาหลักจากใช้ `strtotime` อยู่หน้าสุดไหม 153 | 154 | 155 | 156 | #### between:_min_,_max_ 157 | 158 | ตรวจสอบว่าค่าที่ส่งมาเป็นมีค่าอยู่ระหว่าง min กับ max ไหม 159 | 160 | 161 | 162 | #### confirmed 163 | 164 | ตรวจสอบว่าค่าที่ส่งมาเป็นมีรูปแบบของฟอร์มที่มีรูปแบบ ชื่อ_confirmation ยกตัวอย่างการ 165 | ตรวจสอบ `password`,ว่าตรงกับ`password_confirmation` ไหม 166 | 167 | 168 | #### date 169 | 170 | ตรวจสอบว่าค่าที่ส่งมาเป็นมีรูปแบบของเวลาหลักจากใช้ `strtotime` ไหม. 171 | 172 | 173 | #### date_format:_format_ 174 | 175 | ตรวจสอบว่าค่าที่ส่งมาเป็นมีรูปแบบของเวลาที่กำหนดไหม 176 | 177 | 178 | #### different:_field_ 179 | 180 | ค่าตรง _field_ ต้องมีค่าต่างจากค่าที่ป้อนเข้ามาถึงจะผ่าน 181 | 182 | 183 | #### email 184 | 185 | ตรวจสอบว่าค่าที่ส่งมาเป็นมีรูปแบบของ email 186 | 187 | 188 | #### exists:_table_,_column_ 189 | 190 | ฟอร์มที่อยู่ในการตรวจสอบต้องมีชื่อตรงกับคอลัมน์ในฐานข้อมูล 191 | 192 | **การใช้งานเบื้องต้น** 193 | 194 | 'state' => 'exists:states' 195 | 196 | **การใช้งานโดยใส่ค่าที่ต้องการตรวจไปหลายค่า** 197 | 198 | 'state' => 'exists:states,abbreviation' 199 | 200 | เราสามารถกำหนดเงื่อนไขให้กฏคล้ายๆการทำคิวรี้ ครับ 201 | 202 | 'email' => 'exists:staff,email,account_id,1' 203 | 204 | 205 | #### image 206 | 207 | ตรวจสอบว่าค่าที่ส่งมาเป็นรูปภาพมีนามสกุล(jpeg, png, bmp, or gif) ไหม 208 | 209 | 210 | #### in:_foo_,_bar_,... 211 | 212 | ตรวจสอบว่าค่าที่ส่งมามีค่าตรงกับค่าใน foo,bar ไหม 213 | 214 | 215 | #### integer 216 | 217 | ตรวจสอบว่าค่าที่ส่งมามีรูปแบบของเลขจำนวนเต็มไหม 218 | 219 | 220 | #### ip 221 | 222 | ตรวจสอบว่าค่าที่ส่งมามีรูปแบบของ IP address. 223 | 224 | 225 | #### max:_value_ 226 | 227 | ตรวจสอบว่าค่าที่ส่งมามีค่าน้อยกว่าค่าที่กำหนดไว้ 228 | 229 | 230 | #### mimes:_foo_,_bar_,... 231 | 232 | ตรวจสอบว่าค่าที่ส่งมามีรูปแบบของ mime type ตรงกับที่กำหนดไหม 233 | 234 | **ตัวอย่างการตรวจสอบนามสกุลของไฟล์** 235 | 236 | 'photo' => 'mimes:jpeg,bmp,png' 237 | 238 | 239 | #### min:_value_ 240 | 241 | ตรวจสอบว่าค่าที่ส่งมามีจำนวนน้อยกว่าไหมถ้ามีน้อยกว่าก็ไม่ผ่าน 242 | 243 | 244 | #### not_in:_foo_,_bar_,... 245 | 246 | ตรวจสอบว่าค่าที่ส่งมามีค่าตรงกับค่าที่ตั้งไว้ไหม ถ้ามีก็ไม่ผ่านครับ 247 | 248 | 249 | #### numeric 250 | 251 | ตรวจสอบว่าค่าที่ส่งมาเป็นตัวเลขไหม 252 | 253 | 254 | #### regex:_pattern_ 255 | 256 | ตรวจสอบว่าค่าที่ส่งมามีรูปแบบกับ regular expression ที่กำหนดไว้ไหม 257 | 258 | 259 | 260 | #### required 261 | 262 | ตรวจสอบว่าค่าที่ส่งมาเป็นค่าว่างไหม ถ้าเป็นก็ไม่ผ่านครับ 263 | 264 | 265 | #### required_if:_field_,_value_ 266 | 267 | ตรวจว่าค่าใน _field_ ต้องไม่ว่างและ ตรงกับ _value_ 268 | 269 | 270 | #### required_with:_foo_,_bar_,... 271 | 272 | ตรวจว่าฟิล _foo_ ต้องมีค่าหาก bar มีค่าด้วย 273 | 274 | 275 | #### required_without:_foo_,_bar_,... 276 | 277 | ตรวจว่าฟิล _foo_ ต้องมีค่าหาก bar ไม่มีค่า 278 | 279 | 280 | #### same:_field_ 281 | 282 | ตรวจว่าค่าที่ส่งเข้ามาซ้ำกับค่าที่กำหนดไว้ไหม 283 | 284 | 285 | #### size:_value_ 286 | 287 | ตรวจว่าค่าที่ส่งเข้ามาตรงกับที่กำหนดไว้ไหม กรณีเป็นคำจะตรวจสอบจำนวนคำ เป็นตัวเลขก็เทียบตามค่า เป็ไฟล์เทียบตามขนาดของไฟล์เป็นกิโลไบต์ 288 | 289 | 290 | #### unique:_table_,_column_,_except_,_idColumn_ 291 | 292 | ตรวจว่าค่าที่ส่งมาซ้ำกับในตารางไหม. 293 | 294 | **ตัวอย่างการใช้ตรวจว่าอีเมล์นี้มีในตาราง user ไหม** 295 | 296 | 'email' => 'unique:users' 297 | 298 | **ตัวอย่างการใช้ตรวจว่าอีเมล์นี้มีในตาราง user ตรงคอลัมน์ email-address ไหม** 299 | 300 | 'email' => 'unique:users,email_address' 301 | 302 | ตัวอย่างการใช้ตรวจว่าอีเมล์นี้มีในตาราง user ตรงคอลัมน์ email-address ไหม โดยไม่สนใจ id ที่มีค่าเท่ากับ 10 303 | 304 | 'email' => 'unique:users,email_address,10' 305 | 306 | 307 | #### url 308 | ตรวจว่าค่าเป็น url ไหม 309 | 310 | 311 | ## Custom Error Messages 312 | 313 | เราสามารถปรับแต่งข้อความที่แสดงข้อผิดพลาดได้ 314 | 315 | **ตัวอย่าง** 316 | 317 | $messages = array( 318 | 'required' => 'The :attribute field is required.', 319 | ); 320 | 321 | $validator = Validator::make($input, $rules, $messages); 322 | 323 | **การใช้ข้อความที่เรากำหนดร่วมกับ Place-Holders** 324 | 325 | $messages = array( 326 | 'same' => 'The :attribute and :other must match.', 327 | 'size' => 'The :attribute must be exactly :size.', 328 | 'between' => 'The :attribute must be between :min - :max.', 329 | 'in' => 'The :attribute must be one of the following types: :values', 330 | ); 331 | 332 | **กำหนดข้อความให้แต่ละคอลัมน์เลย** 333 | 334 | $messages = array( 335 | 'email.required' => 'We need to know your e-mail address!', 336 | ); 337 | 338 | บางกรณีเราต้องการกำหนดข้อความที่แสดงให้เป็นเฉพาะแต่ละภาษาไป ซึ่งเราต้องไปเพิ่มที่อาเรย์ชื่อ `custom` ใน `app/lang/xx/validation.php` ตาม 339 | ภาษาที่ไป 340 | 341 | **คัวอย่าง** 342 | 343 | 'custom' => array( 344 | 'email' => array( 345 | 'required' => 'We need to know your e-mail address!', 346 | ), 347 | ), 348 | 349 | 350 | 351 | ## การสร้างตัวตรวจสอบ 352 | 353 | เราสามารถสร้างฟังก์ชันในการตรวจสอบได้เองโดย laravel เตรียมเมทอด `Validator::extend` มาเพื่อการนั้นครับ 354 | 355 | **ตัวอย่าง** 356 | 357 | Validator::extend('foo', function($attribute, $value, $parameters) 358 | { 359 | return $value == 'foo'; 360 | }); 361 | 362 | 363 | ตัวอย่างข้างบนเรารับตัวแปรมาสามตัวครับ `$attribute` คือชื่อข้อมูลที่จะตรวจ `$value` ค่าของข้อมูล `$parameters` ค่าอื่นๆ 364 | 365 | You may also pass a class and method to the `extend` method instead of a Closure: 366 | 367 | Validator::extend('foo', 'FooValidator@validate'); 368 | 369 | มีอีกวิธีในการสร้างคลาสของเราเองโดยการสืบทอด `Illuminate\Validation\Validator` ทีนี้ฟังก์ชันต้องมีคำว่า `validate`นำหน้าด้วยนะครับ 370 | 371 | **ตัวอย่าง** 372 | 373 |