#輕松學會Laravel-高級篇
###Composer快速入門
>Composer官網:[https://getcomposer.org/](https://getcomposer.org/)
>Composer中文網:[http://www.phpcomposer.com](http://www.phpcomposer.com)
###通過composer.phar安裝Composer
局部安裝:將composer.phar文件復制到任意目錄(比如項目根目錄下),然后通過`php composer.phar`指令即可以使用Composer了
全局安裝:
composer下載:https://getcomposer.org/composer.phar
```
chmod u+x composer.phar
mv composer.phar /bin/composer
```
###Composer中國全量鏡像
>http://pkg.phpcomposer.com/
查看當前的鏡像地址
```
composer config -gl
```
Packagist 鏡像用法:
全局配置
```
composer config -g repo.packagist composer https://packagist.phpcomposer.com
// 還原初始配置
composer config -g repo.packagist composer https?://packagist.org
```
單個項目配置
打開命令行窗口(windows用戶)或控制臺(Linux、Mac 用戶),進入你的項目的根目錄(也就是 composer.json 文件所在目錄),執行如下命令:
```
composer config repo.packagist composer https://packagist.phpcomposer.com
```
注:如果沒有composer.json文件,需要新建一個composer.json文件,還需要在里面寫一對{}號,不然執行這個命令會報錯
###使用Composer
```
mkdir demo
cd demo
composer init
composer config repo.packagist composer https://packagist.phpcomposer.com
```
搜索(search)
```
composer search monolog
```
展示(show)
```
composer show --all monolog/monolog
```
申明依賴(require)
vi composer.json
```
"require": {
"monolog/monolog":"1.21.*",
"symfony/http-foundation": "^3.2"
},
```
安裝(install)
```
composer install
```
更新(update)
vi composer.json
```
"require": {
"monolog/monolog":"1.21.*"
},
```
composer update
###使用Composer安裝Laravel
通過Composer Create-Project 命令安裝 Laravel
```
composer search laravel
composer show --all laravel/laravel
composer create-project laravel/laravel --prefer-dist blog
composer create-project laravel/laravel shop --prefer-dist "5.3.*" // 安裝某個具體版本
```
Laravel 安裝器
```
// 使用 Composer 下載 Laravel 安裝包
composer global require "laravel/installer"
// 再將 ~/.composer/vendor/bin 路徑加到 PATH
echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc
// 重啟一下
reboot
// 測試Laravel 安裝器是否安裝成功
laravel
// 安裝laravel
laravel new laravel2
// 下載最新的開發版本
laravel new test --dev
```
###Artisan基本用法
查看所有可用的Artisan的命令(list)
```
php artisan
php artisan list
```
查看命令的幫助信息(help)
php artisan help make:controller
```
composer create-project laravel/laravel laravel53 --prefer-dist "5.3.*"
// 創建控制器
php artisan make:controller StudentController
// 創建模型
php artisan make:model Student
// 創建中間件
php artisan make:middleware Activity
```
###Laravel中的用戶認證(Auth)
```
// 生成Auth所需文件
php artisan make:auth
// 執行遷移
php artisan migrate
```
通過訪問 http://192.168.99.100:8080/home 就可以進行注冊登錄了,如果訪問出現了樣式問題,只需要將 resources/views/layouts/app.blade.php 文件中引入css和引入js的路徑改為如下即可:
```
{{ asset('css/app.css') }}
{{ asset('js/app.js') }}
```
###Laravel中的數據遷移
######新建遷移文件
通過 `php artisan make:migration create_students_table` 來新建遷移文件。--table和--create參數可以用來指定數據表名稱,以及遷移文件是否要建立新的數據表
生成模型的同時生成遷移文件 `php artisan make:model Student -m`
######下面咱們以students表來新建一個遷移文件
表結構如下
```
create table if not exists students(
id int auto_increment primary key,
name varchar(255) not null default '' comment '姓名',
age int unsigned not null default 0 comment '年齡',
sex int unsigned not null default 10 comment '性別',
created_at int not null default 0 comment '新增時間',
updated_at int not null default 0 comment '修改時間'
)engine=innodb default charset utf8 auto_increment=1001 comment='學生表';
```
```
php artisan make:migration create_students_table --create=students
php artisan make:model Student -m
```
2017_02_03_033958_create_students_table.php
```
// 編輯(自定義)遷移文件
public function up()
{
Schema::create('students', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('age')->unsigned()->default(0);
$table->integer('sex')->unsigned()->default(10);
$table->integer('created_at')->default(0);
$table->integer('updated_at')->default(0);
});
}
```
生成數據表
```
php artisan migrate
```

###Laravel中的數據填充
創建一個填充文件,并完善填充文件
```
php artisan make:seeder StudentTableSeeder
```
執行單個填充文件
```
php artisan db:seed --class=StudentTableSeeder
```
批量執行填充文件
```
php artisan db:seed
```
數據填充實例
```
php artisan make:seeder StudentTableSeeder
```
database/seeds/StudentTableSeeder.php
```
public function run()
{
DB::table('students')->insert([
['name'=>'zhangsan', 'age'=>18],
['name'=>'lishi', 'age'=>20]
]);
}
```
```
php artisan db:seed --class=StudentTableSeeder
```
database/seeds/DatabaseSeeder.php
```
public function run()
{
// $this->call(UsersTableSeeder::class);
// 批量執行填充,需要先引入一下
$this->call(StudentTableSeeder::class);
}
```
```
php artisan db:seed
```



###Laravel中的文件上傳
Laravel的文件系統是基于Frank de Jonge的Flysystem擴展包,提供了簡單的接口,可以操作本地端空間、Amazon、S3、Rackspace Cloud Storage,可以非常簡單的切換不同保存方式,但仍使用相同的API操作
配置文件位置:config/filesystems.php
文件上傳實例
config/filesystems.php
```
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'visibility' => 'public',
],
'uploads' => [
'driver' => 'local',
'root' => storage_path('app/uploads')
],
's3' => [
'driver' => 's3',
'key' => 'your-key',
'secret' => 'your-secret',
'region' => 'your-region',
'bucket' => 'your-bucket',
],
],
```
routes/web.php
```
Route::any('/upload', 'StudentController@upload');
```
app/Http/Controller/StudentController
```
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class StudentController extends Controller
{
public function upload(Request $request){
if($request->isMethod('POST')){
$file = $request->file('source');
// 判斷文件是否上傳成功
if($file->isValid()){
// 獲取原文件名
$oriFileName = $file->getClientOriginalName();
// 獲取文件的擴展名
$ext = $file->getClientOriginalExtension();
// 獲取文件的mime類型
$type = $file->getClientMimeType();
// 臨時文件的絕對路徑
$realPath = $file->getRealPath();
$filename = date('Y-m-d H-i-s') . '-'. uniqid() . '.' . $ext;
$bool = Storage::disk('uploads')->put($filename, file_get_contents($realPath));
var_dump($bool);
}
exit;
}
return view('student.upload');
}
}
```
resources/views/student/upload.blade.php(復制的是 Laravel中的用戶認證(Auth)小節生成的login.blade.php)
```
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">文件上傳</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="file" class="col-md-4 control-label">請選擇文件</label>
<div class="col-md-6">
<input id="file" type="file" class="form-control" name="source" required>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-primary">
確認上傳
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
```

###Laravel中的郵件發送
配置文件:config/mail.php
Mail::raw() 發送純文本格式 Mail::send() 發送html格式
第一種發送方式
.env
```
MAIL_DRIVER=smtp
MAIL_HOST=smtp.163.com
MAIL_PORT=465
MAIL_USERNAME=jiezeal@163.com
MAIL_PASSWORD=Internet678
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=jiezeal@163.com
MAIL_FROM_NAME='jiezeal'
```
routes/web.php
```
Route::any('/mail', 'StudentController@mail');
```
app/Http/Controller/StudentController
```
use Mail;
public function mail(){
// 第一種發送方式 發送純文本
Mail::raw('郵件內容', function ($message){
$message->from('jiezeal@163.com', 'jiezeal');
$message->subject('郵件主題');
$message->to('jiezeal@foxmail.com');
});
}
```

第二種發送方式
app/Http/Controller/StudentController
```
public function mail(){
// 第二種發送方式 發送html
Mail::send('student.mail', ['name' => 'jiezeal', 'age' => 18], function ($message){
$message->subject('郵件主題');
$message->to('jiezeal@foxmail.com');
});
}
```
resources/views/student/mail.blade.php
```
<h1>Hello {{ $name }} {{ $age }}</h1>
```

###Laravel中的緩存使用
配置文件位置:config/cache.php
routes/web.php
```
Route::any('/cache1', 'StudentController@cache1');
Route::any('/cache2', 'StudentController@cache2');
```
app/Http/Controller/StudentController
```
use Illuminate\Support\Facades\Cache;
public function cache1(){
// put() 保存對象到緩存中
Cache::put('key1', 'val1', 10);
// add() 也是添加緩存 如果key1存在則添加失敗,不存在則添加成功
$bool = Cache::add('key1', 'val1', 10);
var_dump($bool);
$bool = Cache::add('key2', 'val2', 10);
var_dump($bool);
// forever() 永久的保存對象到緩存中
Cache::forever('key3', 'val3');
// has() 判斷key是否存在
if(Cache::has('key3')){
$val = Cache::get('key3');
var_dump($val);
}else{
echo 'No';
}
}
public function cache2(){
// get() 從緩存中獲取對象
$val = Cache::get('key1');
var_dump($val);
$val = Cache::get('key2');
var_dump($val);
$val = Cache::get('key3');
var_dump($val);
// 獲取并刪除緩存
$val = Cache::pull('key2');
var_dump($val);
// forget() 從緩存中刪除對象
$bool = Cache::forget('key3');
var_dump($bool);
}
```
###Laravel中的錯誤與日志
######Debug模式
配置文件位置:config/app.php
>進行本地開發時,應該配置APP_DEBUG環境變量為true,在上線環境,這個值應該永遠為false
HTTP異常
>有些異常描述來自服務器的HTTP錯誤碼。例如,這可能是一個“頁面未找到”錯誤(404),“認證失敗錯誤”(401)亦或是程序出錯造成的400錯誤
日志
>Laravel日志工具基于強大的Monolog庫,提供了single、daily、syslog和errorlog日志模式,以及debug、info、notice、warning、error、critical和alert七個錯誤級別
routes/web.php
```
Route::any('/error', 'StudentController@error');
```
app/Http/Controller/StudentController
```
use Illuminate\Support\Facades\Log;
public function error(){
$name = 'zhangsan';
var_dump($name);
return view('student.error');
$student = null;
if($student == null){
// 對應 resource/views/errors/503.blade.php
abort('503');
// 對應 resource/views/errors/500.blade.php
abort('500');
}
Log::info('這是一個info級別的日志');
Log::warning('這是一個warning級別的日志');
Log::error('這是一個error級別的日志', ['name' => 'zhangsan', 'age' => 18]);
}
```


對應的是 resource/views/errors/404.blade.php

###Laravel中的隊列應用
Laravel隊列服務為各種不同的后臺隊列提供了統一的API,允許推遲耗時任務(例如發送郵件)的執行,從而大幅提高web請求速度
配置文件位置:config/queue.php
主要步驟
遷移隊列需要的數據表
```
php artisan queue:table
php artisan migrate
```
編寫任務類
```
php artisan make:job SendEmail
```
app/SendEmail.php
```
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Mail;
class SendEmail implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
protected $email;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($email)
{
$this->email = $email;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
Mail::raw('隊列測試', function ($message){
$message->subject('隊列測試');
$message->to($this->email);
});
}
}
```
routes/web.php
```
Route::any('/queue', 'StudentController@queue');
```
app/Http/Controller/StudentController
```
public function queue(){
dispatch(new SendEmail('jiezeal@foxmail.com'));
}
```
推送任務到隊列
瀏覽器訪問 http://192.168.99.100:8080/queue
運行隊列監聽器
```
php artisan queue:listen
```
處理失敗任務
```
php artisan queue:failed-table
php artisan migrate
// 查看執行失敗的任務
php artisan queue:failed
// 重新執行(ID為1)的那一條失敗的任務
php artisan queue:retry 1
// 重新執行所有失敗的任務
php artisan queue:retry all
// 刪除(ID為4)的那一條失敗的任務
php artisan queue:forget 4
// 刪除所有執行失敗的任務
php artisan queue:flush
```
