├── 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 | [](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 | 
11 |
12 |
13 |
14 |
15 |
16 | 1. จากนั้นเราจะ เรียกไฟล์ `autoload.php` จากโฟลเดอร์ `vendor` ขึ้นมา
17 | 
18 |
19 |
20 |
21 | 1. ที่เห็นชื่อยาวขนาดนี้เป็นเพราะถูกสุมมาจากการที่ใช้คำสั่ง`artisan dump autoload `เพื่อสร้าง รายชื่อของ `package` ใหม่นะครับ แต่ก่อนหน้านั้นเราจะทำการโหลดไฟล์ `package` ทั้งหมดก่อน
22 | โดยเรียกไฟล์ `autoload_real.php` ขึ้นมา
23 | 
24 |
25 |
26 |
27 | 1. ต่อมาใน ไฟล์ `vendor/composer/autoload_real.php` จะทำการเรียกไฟล์ `Classloader` มาทำการสร้างเป็นวัตถุชื่อ `$loader` แล้วก็
28 | 
29 |
30 |
31 | 1. เรียกไฟล์ `autoload_classmap` กับ `autoload_namespace`ขึ้นมาซึ่งในไฟล์ `autoload_classmap` จะเป็นรายชื่อของไฟล์ `package` ทั้งหมดที่อยู่ในโฟลเดอร์ `vendor` ส่วนในไฟล์ `autoload_namespace` จะเป็นรายชื่อของตัว `namespace ` ที่ใช้เรียก `root path` ของไฟล์ `package` นั้นครับ
32 | 
33 |
34 |
35 |
36 | 1. พอเรียกเสร็จก็จะส่งกลับมาที่ ไฟล์ `autoload` แล้วก็ส่งค่าต่อไปให้ `ClassLoader` ของ `laravel`
37 | 
38 | 1. ตามลงมาดูว่า `Classloader`ของ `laravel` มันทำยังไงต่อนะครับ
39 | ฟังก์ชัน `register`ทำการเรียกใช้ ฟังก์ชัน `load `
40 | 
41 |
42 |
43 |
44 | 1. ฟังก์ชัน `load`จะทำการเรียกโฟลเดอร์ `package` ที่มีตามรายชื่อในตัวแปร `class`ที่ส่งมาตอนแรก
45 | 
46 |
47 |
48 |
49 | 1. เท่านี้ก็เสร็จการโหลด `package` ในโฟลเดอร์ `vendor` ครับ อะแต่ยังไม่หมดนะครับ ยังเหลือ package ที่โฟลเดอร์ workbench เรียกใช้คลาส `Starter`เพื่อทำการลงทะเบียน `package` ในโฟลเดอร์ `workbench`
50 | 
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 | 
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 | 
76 |
77 | 1. กลับมาที่ ไฟล์ `start.php` ครับ ขั้นต่อมา เราจะทำการตรวจสถานะการทำงานของระบบนะครับ
78 | ว่าอยู่ในโหมดไหน ตรงนี้มีประโยชน์มากในกรณีเมื่อเรากำลังพัฒนาอยู่ก็ตั้งให้เป็น `development` ส่วนจะไปกำหนดที่ไหนค่อยมาพูดกันอีกทีครับ
79 | 
80 |
81 | 1. ทำการโหลดไฟล์ `path.php` ซึ่งจะเป็น `class `ใช้ในการกำหนดเส้นทางการเข้าหาโฟลเดอร์ต่างๆ
82 | 
83 |
84 | 1. ทำการเรียกใช้งานตัว `laravel` ละครับตรงนี้จะเป็นการ เรียกไฟล์ `start` ของตัว `laravel` ขึ้นมา
85 | 
86 |
87 | ----------
88 |
89 | ### ตอนที่ 3 Bootstrap
90 |
91 | 1. laravel เริ่มการตรวจว่ามีการติตตั้ง `Mcrypt` ไหม
92 | 
93 |
94 | 1. ต่อมาก็ตรวจสภาวะการตั้งค่าก่อนว่าเรากำลัง ตั้งให้อยู่ในสถานะการทอบสอบไหม
95 | 
96 |
97 | 1. คลาส `Facade` จะทำการเคลียร์ ตัวแทนของมัน
98 | แล้วก็สร้างขึ้นใหม่
99 | 
100 |
101 | 1. ทำการโหลดข้อมูลการตั้งค่าจากตัวแปร `$env` ขึ้นมาใส่ให้คลาส `Config` ครับ แล้วสร้างตัวแทนให้คลาส `Config`
102 | 
103 |
104 | 1. ทำการตั้งค่าวันเวลาโดยโหลดค่ามาจากตัวแปรในไฟล์ `app.php`
105 | 
106 |
107 | 1. โหลดค่าชื่อย่อจากที่ไฟล์ `app.php` มา
108 | 
109 |
110 | มาให้ฟังก์ชัน `getInstance` มาทำการลงทะเบียนไว้
111 | 
112 |
113 | 1. ทำการอนุญาตให้ใช้คำร้องขอชนิด `put` ใช้ทำการแก้ไขข้อมูล กับ `delete` ใช้ในการลบข้อมูล เพื่อใช้ตอนทำ `restful` ในกรณีที่ `firewall` ไม่อนุญาตุให้เมทอดสองอันนี้ผ่าน เราจึงจำเป็นต้องทำการเปลี่ยนส่วนหัวของเมทอด `post` ให้กลายเป็นสองเมทอดที่โดนบล็อก
114 | 
115 |
116 | 1. ทำการวมคลาสทุกตัวที่โหลดมาเข้าด้วยกัน `$config['providers']` คือรายชื่อคลาสที่อยู่ในไฟล์ `app.php`
117 | 
118 |
119 | 1. เรียกใช้ฟังก์ชัน `$app->boot()` เพื่อเริ่มต้นการทำงาน เเล้วเรียกไฟล์ `global.php` ซึ่งเป็นไฟล์ที่เราสามารถใช้กำหนดค่าเริ่มต้นเองได้
120 | 
121 |
122 | 1. รองสุดท้ายดึงไฟล์ที่เราใช้กำหนดสภาวะการตั้งค่าขึ้นมา
123 | 
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 |
{{ $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 |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('