0%

Laravel From Scratch 筆記

參考影片
Laravel From Scratch

1. Initial Setup

官方文件上面寫
請確定把 ~/.composer/vendor/bin 路徑放置於你的 PATH 裡,這樣你的系統才能找到 laravel 執行檔。
是這個意思

~/.bashrc
1
export PATH="~/.composer/vendor/bin:$PATH"

就能使用laravel new blog比composer安裝還快

2. Your First View and Route

return view(page.about);=return view(page/about);

3. View Data and Blade

route.php
1
2
3
4
5
6
7
8
Route:get('/', function(){
$people = ['hi','hihi'];
//很多方法,推最後一種
return View::make();
return view('welcome', compact('people'));
return view('welcome')->with('people',$people);
return view('welcome', ['people'=>$people]);
});
welcome.blade.php
1
2
3
4
5
6
7
8
9
@if (empty($people))
no people
@else
something else
@endif
@foreach ($people as $person)
<li>{{ $person }}</li>
@endforeach

4. Routing to Controllers

php artisan可以看到所有指令,並用它來產生controller

5. Layout Files

可以@yield('content') @yield('footer') @yield('header')很多區塊

6. How to Manage Your CSS and JS

灌好nodejs之後
全域安裝gulp的npm套件 # sudo npm install --global gulp
安裝Laravel Elixir # sudo npm install
# gulp

1
2
3
4
5
6
出現錯誤的話
https://laracasts.com/discuss/channels/general-discussion/gulp-notify-error-in-notifier-error-in-plugin-gulp-notify-not-found-notify-send
From the VM, this worked for me:
sudo apt-add-repository ppa:izx/askubuntu
sudo apt-get update
sudo apt-get install libnotify-bin

1
<link rel="stylesheet" href="{{ elixir('css/app.css') }}">搭配
gulpfile.js
1
2
3
elixir(function(mix) {
mix.sass('app.scss').version('css/app.css');
});

結論:
resources/assets/sass/......寫很多scss或純css檔案
然後編譯至public/css/底下合成一個檔案(view只需引用一個檔案)(使用asset('css/app.css'))
再使用mix.version()來加上獨特的雜湊值,以防止檔案被快取(使用elixir('css/app.css'))

7. Fetching Data

1
Route:put('xxx','Controller@update');

config/database.php可看到可使用的資料庫(編碼注意!),可把default的mysql換掉
看說明php artisan help make:migration
命名方式就說你要幹麻
php artisan help make:migration create_cards_table
php artisan help make:migration add_username_to_users_table

這個方式可以幫你打scheme
php artisan help make:migration create_cards_table --create=cards

互動式工具
php artisan tinker然後可以輸入
DB::table('messages')->get();
$card = App\Card::first();
$note = new App\Note; $note->body='something' $note->card_id=1; $note->save();
等等

重要!:namespace概念在12:00左右,use很重要
如果沒有用use會自動套用namespace的路徑,有用use才會套用use的路徑

如果table叫做cards,model習慣叫做Card

記得要取一樣的名字
Route::get('messages/{ABCDEFG}', 'MessageController@show');

1
2
3
4
5
public function show(Message $ABCDEFG) // ($id)
{
// $message = Message::find($id);
return $message;
}

8. Defining Relationships With Eloquent

有了Relationships就很容易create and save them
$card->notes()->save($note);
$card->notes()->create(['body'=>'XDD']);

在model中加入protected $fillable = ['body'];才可被填

9. Forms

return redirect('foo/'); 跳轉
return back(); 回到上一頁

以下寫法都相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public function store(Request $request, Message $message)
{
// 1
$note = new Note;
$note->body = $request->body;
$message->notes()->save($note);
// 2
$note = new Note(['body => $request->body']);
$message->notes()->save($note);
// 3
$message->notes()->save(
new Note(['body => $request->body'])
);
// 4
$message->notes()->create([
'body' => $request->body
])
// 5
$message->notes()->create([$request->all()]);
return back();
}

最厲害的是

1
2
3
4
5
6
7
8
9
10
11
12
13
model
public function addNote()
{
return $this->notes()->save($note);
}
controller
public function store(Request $request, Message $message)
{
$message->addNote(
new Note($request->all())
);
return back();
}

10. Updating Records and Eager Loading

更新方法
Route::patch('notes/{note}', 'NotesController@update');

dd('something_return')可以拿來debug

把上一次migrate取消
php artisan migrate:rollback

清除所有資料表以及其資料並全部重新migrate
php artisan migrate:refresh

Eager Loading
抓取留言的回覆的使用者

不一樣唷
$card = Card::with('notes')->get(); // ret an array
$card = Card::with('notes')->find(1); // ret an object

$card = Card::with('notes.user')->find(1); 等同於 $card->load('notes.user');,Eager Loading !


顯示留言的回覆 會回傳陣列
$message = Message::with('notes')->get(); return $message;

anytime call chaining can't call all() anymore so change to get()

不用出現陣列 只要出現一則就好
$message = Message::with('notes')->find(1); return $message;

11. Validation and More

約莫50行,告訴我們可以用validatemethod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Validate the given request with the given rules.
*
* @param \Illuminate\Http\Request $request
* @param array $rules
* @param array $messages
* @param array $customAttributes
* @return void
*/
public function validate(Request $request, array $rules, array $messages = [], array $customAttributes = [])
{
$validator = $this->getValidationFactory()->make($request->all(), $rules, $messages, $customAttributes);
if ($validator->fails()) {
$this->throwValidationException($request, $validator);
}
}

約莫100行,告訴我們當驗證出錯時會回傳
$error:withErrors($errors, $this->errorBag());
withInput($request->input())代表錯誤時會回傳填的內容可以使用 old(‘html-name’) 存取
按下送出時不會全部要重填

vendor/laravel/framework/src/Illuminate/Foundation/Validation/ValidatesRequests.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Create the response for when a request fails validation.
*
* @param \Illuminate\Http\Request $request
* @param array $errors
* @return \Illuminate\Http\Response
*/
protected function buildFailedValidationResponse(Request $request, array $errors)
{
if (($request->ajax() && ! $request->pjax()) || $request->wantsJson()) {
return new JsonResponse($errors, 422);
}
return redirect()->to($this->getRedirectUrl())
->withInput($request->input())
->withErrors($errors, $this->errorBag());
}

有一堆validate的rule可以參考
https://laravel.com/docs/5.2/validation#available-validation-rules
ex:'email_field'=> 'email|unique:users' email欄位須遵守email格式並且不重複於users table

config/app.php
裡面的providers
如果有App\Providers\RouteServiceProvider::class
就不用加web group
預設都有加,舊版才沒加吧
App/Http/Kernel.php有描述web能防甚麼

csrf_token()會被轉成一串數字
csrf_filed()會變轉成input type=hidden value=一串數字

教學從這邊好像就沒延續了QQ

13. Authenticate Your Users

# composer create-project --prefer-dist laravel/laravel makeauth
# php artisan make:auth
會自動加上Route::auth();,Route::get('/home', 'HomeController@index');
它的功能可以在/vendor/laravel/framework/src/Illuminate/Routing/Router.php中的auth()看見

env
1
DB_CONNECTION=sqlite

# touch database/database.sqlite

config/database.php
1
2
3
4
可以看到路徑
'database' => env('DB_DATABASE', database_path('database.sqlite')),
改成
'database' => database_path('database.sqlite'),

# php artisan migrate
# php artisan serve

Mail local測試

env
1
MAIL_DRIVER=log

config/mail.php
1
2
改成想要ㄉ
'from' => ['address' => null, 'name' => null],

密碼信寄出去後
storage\logs\laravel.log可以看到log

14. Understanding Middleware

app\Http\Kernel.php
1
2
3
4
5
6
7
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];

實作詳細app\Http\Middleware\Authenticate.php

do on controller
1
2
3
4
5
6
public function __construct()
{
$this->middleware('auth'); 所有方法都要登入
$this->middleware('auth', ['only' => ['index']]); 只有index要登入
$this->middleware('auth', ['except' => ['index']]); 只有index不用登入
}
do on route
1
Route::get('/home', 'HomeController@index')->middleware('auth');

這個是global middleware
CheckForMaintenanceMode
# php artisan down 變成維修頁面
# php artisan up 正常


想加個admin:
php artisan make:middleware MustBeAdministrator

app\Http\Middleware\MustBeAdministrator.php
1
2
3
4
5
$user = $request->user();
if ($user && $user->username == 'XDD') {
return $next($request);
}
abort(404, 'No way.');
app\Http\Kernel.php
1
2
加在想加的地方
'admin' => \App\Http\Middleware\MustBeAdministrator::class

15. Flashing to the Session

1
2
3
4
5
6
7
8
Route::get('/flash', function () {
Session::flash('status', 'hihi');
return redirect('/');
});
@if (Session::has('status'))
<h3>{{ Session::get('status') }}</h3>
@endif

return redirect('/');===return Redirect::to('/');
session(['foo' => 'bar']);===Session::put('foo', 'bar');
session('foo')===Session::get('foo'); // bar

session()->flash('status', 'hihi');

製造helpers file

composer.json
1
2
3
4
5
"autoload": {
"files": {
"app/helpers.php"
}
},

# composer dump-autoload

16. Automatic Resolution and the Service Container

bind,singleton;make

17. Bootstrapping With Service Providers

php artisan make:provider FooProvider
app/Providers/FooProvider

1
2
3
4
5
6
7
public function boot() {
DB::listen(function($query) {
var_dump($query->sql, $query->bindings);
});
}
public function regitster(){
}

config/app.php
‘provider’可加入

16. Conclusion

APP_ENV=production
看了13天才看完,真累XDD. Today 2016/05/27
Thanks, Jeffrey!