laravel5.4新特性
http://www.cnblogs.com/webskill/category/1067140.html
laravel 5.4 新特性
component and slot
使用:
1.component panel
<article class="message"> <div class="message-header"> <p>Hello World</p> <button class="delete" aria-label="delete"></button> </div> <div class="message-body"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. <strong>Pellentesque risus mi</strong>, tempus quis placerat ut, porta nec nulla. Vestibulum rhoncus ac ex sit amet fringilla. Nullam gravida purus diam, et dictum <a>felis venenatis</a> efficitur. Aenean ac <em>eleifend lacus</em>, in mollis lectus. Donec sodales, arcu et sollicitudin porttitor, tortor urna tempor ligula, id porttitor mi magna a neque. Donec dui urna, vehicula et sem eget, facilisis sodales sem. </div> </article>
2.其中header和body需要傳入變量
<article class="message"> <div class="message-header"> <p>{{$title}}</p> <button class="delete" aria-label="delete"></button> </div> <div class="message-body"> {{$content}} </div> </article>
3.views.components.index 中 需要引用component模版panel
@component('components.panel')
@slot('title')
hello world
@endslot
@slot('content')
have a nice day
@endslot
@endcomponent
4.如果要傳入默認content
panel.blade.php修改如下:
<article class="message"> <div class="message-header"> <p>{{$title}}</p> <button class="delete" aria-label="delete"></button> </div> <div class="message-body"> {{$slot}} </div> </article>
index.blade.php修改如下
@component('components.panel')
@slot('title')
hello world
@endslot
have a nice day
@endcomponent
//可多來幾個:
@component('components.panel')
@slot('title')
hello world
@endslot
have a nice day123
@endcomponent
5.還可以這樣給默認值:title默認為laravel
panel.blade.php修改如下:
<article class="message">
<div class="message-header">
<p>{{$title ?? 'laravel'}}</p>
<button class="delete" aria-label="delete"></button>
</div>
<div class="message-body">
{{$slot}}
</div>
</article>
index.blade.php修改如下
@component('components.panel')
have a nice day
@endcomponent
laravel 郵件
本文使用qq郵箱
env郵件配置:
MAIL_FROM_ADDRESS = 17******[email protected]
MAIL_FROM_NAME = listen~
MAIL_DRIVER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=465
MAIL_USERNAME=17*******[email protected]
MAIL_PASSWORD= ****** //這個是你的qq授權碼
MAIL_ENCRYPTION=ssl
MAIL_ENCRYPTION=ssl
創建郵件類
php artisan make:mail welcomeToMiya
修改welcomeToMiya.php視圖
public function build() { return $this->view('email.welcome'); }
使用
//發送郵件 Route::get('/mail',function(){ \Illuminate\Support\Facades\Mail::to('[email protected]')->send(new \App\Mail\welcomeToLaravist()); });
傳參 修改 welcomeToMiya.php
public $user; public function __construct(User $user) { $this->user = $user; }
傳參 修改 web.php
//發送郵件 Route::get('/mail',function(){ $user = \App\User::find(1); \Illuminate\Support\Facades\Mail::to('[email protected]')->send(new \App\Mail\welcomeToLaravist($user)); });
發郵件還可以這樣:
public function sendTo($user,$subject,$view,$data){
//也可以使用Mail::send
Mail::send($view,$data,function ($message) use ($user,$subject){
$message->to($user->email)->subject($subject);
});
}
使用sendcloud:
參考github: https://github.com/NauxLiu/Laravel-SendCloud
notification 通知
= mail篇 ### =
public function via($notifiable)
{
return ['mail'];
}
1.新建notification類
php artisan make:notification PostNotification
2.設置路由
//notification 註意默認發送到user模型中的email郵箱賬號 所以要確認user郵箱可用
Route::get('/notification',function(){
$user = \App\User::find(1);
$post = \App\Post::find(2);
$user->notify(new \App\Notifications\PostNotification($post));
});
3.訪問/notification 收到郵件
4.常用設置方法 PostNotification.php
public function toMail($notifiable)
{
return (new MailMessage)
->subject('A post published'.$this->post->title) //自定義主體
->success() //定義按鈕顏色
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
=database篇 ### =
將通知都存儲在數據庫裏
1.修改PostNotification.php
public function via($notifiable)
{
//return ['mail'];
return ['database'];
}
2.創建notification遷移文件
php artisan notifications:table
php artisan migrate
3.PostNotification.php 中可添加 toDatabase方法 如果沒寫的話默認用的是toArray方法
4.修改web.php
5.查看當前用戶下的notifications
6.新建一個notification
php artisan make:notification UserSubscribe
7.UserSubscribe.php 修改如下
public function via($notifiable)
{
return ['database'];
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
'subscribed_at' => Carbon::now()
];
}
8.修改web.php
//notification
Route::get('/notification', function () {
$user = \App\User::find(1);
$post = \App\Post::find(2);
//$user->notify(new \App\Notifications\PostNotification($post));
$user->notify(new \App\Notifications\UserSubscribe());
});
9.再次查看當前用戶的notifications
10.列出未讀notifications並標識為已讀
web.php
//notification
Route::get('/show-notification', function () {
return view('notifications.index');
});
//標識未讀
Route::delete('user/notification',function (){
Auth::user()->unreadNotifications->markAsRead();
return redirect()->back();
});
notifications.index.blade
@extends('app')
@section('content')
<h1>我的通知:</h1>
<ul>
@foreach(Auth::user()->unreadNotifications as $notification)
@include('notifications/'.snake_case( class_basename($notification->type) ))
@endforeach
</ul>
<form action="/user/notification" method="POST">
{{csrf_field()}}
{{method_field('DELETE')}}
<input type="submit" value="標識已讀">
</form>
@stop
user_subscribe.blade.php
<h2>user</h2>
{{$notification->data['subscribed_at']['date']}}
post_notification.blade.php
<h2>post</h2>
<li>{{$notification->data['title']}}</li>
標識某條已讀
$user->refresh()->unreadNotifications->where('id','57bb0e0e-8d35-4da8-850b-121a5317c9b9')->first()->markAsRead();
總結:
database
- php artisan make:notification someNotification
- 對於需要傳入的參數做修改 例如依賴模式 Post $post
- php artisan notification:table
- 獲取notification $user->notifications
- 標識已讀 所有的 $user->unreadNotifications->markAsRead()
單條標識:$user->refresh()->unreadNotifications->where(‘id‘,‘57bb0e0e-8d35-4da8-850b-121a5317c9b9‘)->first()->markAsRead();
laravel 郵件使用markdown
php artisan make:mail lessonPublished --markdown="emails.published"
這個命令不僅創建了email類文件 還生成了視圖文件 並把視圖也寫好了 return $this->markdown(‘emails.published‘‘)
可根據需要修改 也可修改email markdown模版 php artisan vendor:publish
發送郵件
Route::get("sendmail",function(){
$email = new \App\Mail\LessionPublished(\App\User::first());
Mail::to(\App|User::first())->send($email);
})
toggle
toggle方法主要用於多對多關系中,attach detach 比如點贊 收藏
1.user表
2.post表 title content
3.中間表 favoriate user_id post_id
4.user中定義關系
public function favorites(){
return $this->belongsToMany(Post::class,'favoriates'); //第二個參數中間表
}
5.關聯關系
做法一:
在tinker中操作
$user = App\User::find(1);
$post = App\Post::find(2);
$user->favorite()->attach($post);
查看結果:$user->refresh()->favorite
//取消收藏
$user->favorite()->detach($post);
做法二:toggle 不用去判斷用戶有沒有收藏該文章 用戶收藏了則取消收藏 反之則收藏
$user->favorite()->toggle($post);
實時facade
創建一個目錄叫services
創建一個weibo類<?php namespace App\Services; class weibo { protected $http; public function __construct(Http $http) { $this->http = $http; } public function publish($status){ $this->http->post($status); } }
創建一個Http類
<?php
namespace App\Services;
class Http
{
public function __construct()
{
}
public function post($status){
return dd('I post a post'.$status);
}
}
路由修改
use Facades\App\Services\weibo;
//facade
Route::get('facade',function (){
weibo::publish('這是一條微博');
});
現在訪問就有了:"I post a post這是一條微博"
事件監聽
方法一:
web.php
Event::listen('eloquent.created: App\post',function(){
dump('A post was created');
});
Route::get('/event53',function(){
\App\post::create(['title'=>'Title','content'=>'My Body']);
});
方法二:
註釋掉
Event::listen('eloquent.created: App\post',function(){
dump('A post was created');
});
post模型中定義事件
<?php
namespace App;
use App\Events\PostWasPublished;
use Illuminate\Database\Eloquent\Model;
class post extends Model
{
protected $guarded = array();
protected $events = [
'created' => PostWasPublished::class
];
}
修改EventServiceProvider.php 中的$listen屬性 創建事件和事件監聽文件
protected $listen = [
'App\Events\PostWasPublished' => [
'App\Listeners\PostWasPublishedListener',
],
];
執行 php artisan event:generate
** 還可以依賴註入 **
App\Events\PostWasPublished.php
public $post;
public function __construct($post)
{
$this->post = $post;
}
App\Listeners\PostWasPublishedListener.php
public function handle(PostWasPublished $event)
{
dump($event->post->toArray());
}
方法三:普通路由觸發event
app/Providers/EventServiceProvider.php
protected $listen = [
'App\Events\UserSignUp' => [
'App\Listeners\UserSignUpListener',
],
];
UserSignUp.php
use App\User;
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
UserSignUpListener.php
public function handle(UserSignUp $event)
{
dd($event->user->name);
}
web.php
Route::get('/eventroute',function(){
$user = \App\User::find(1);
event(new \App\Events\UserSignUp($user));
});
console command
php artisan make:command hello
進入app/console/commands/hello.php
修改singniture和handle
protected $signature = 'lara:hello';
public function handle()
{
$this->info('hello my girl');
}
app/console/kernel.php $commands屬性修改 添加剛才的類
App\Console\Commands\hello::class
傳參:php artisan lara:hello alice
protected $signature = 'lara:hello{name=Bool}'; //? 可有可無
protected $signature = 'lara:hello{name=Bool}'; //? 可有可無
public function handle()
{
$this->info('hello my girl '.$this->argument('name'));
}
默認值:protected $signature = ‘lara:hello{name=Bool}‘;
定時任務
新建一個test.sh
#!/bin/bash
echo "hello world";
php test.php
test.php
this is a test for crontab
$ cronatab -e
* * * * * /var/www/test.sh 2>&1 >> /var/www/test.log
laravel 定時任務:
$ php artisan make:conmmand logInfo
修改 ap/console/command/logInfo.php
protected $description = 'log Info';
public function handle()
{
Log::info('It works');
}
kernel中註冊 app/console/kernel.php
protected $commands = [
//
hello::class,
logInfo::class
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('log:info')
->everyMinute();
}
$ crontab -e
* * * * * php /var/www/lara/leaning/artisan schedule:run >> /dev/null 2>&1
middleware
php artisan make:middleware isAdminMiddleware
user表增加is_admin字段 值為 Y/N
模型user.php
public function isAdmin(){
return $this->is_admin == 1;
}
修改isAdminMiddleware
public function handle($request, Closure $next)
{
info( $request->user()); //等價於 Auth::user()
if($request->user() && $request->user()->isAdmin()){
return $next($request);
}
return redirect('/');
}
web.php
Auth::loginUsingId(2);
Route::group(['prefix'=>'admin','middleware'=>'isAdmin'],function (){
Route::get('users',function (){
return 'admin only';
});
});
controller中可以這樣設置
public function __construct(){
$this->middleware('admin',['only'=>['store','update']]);
}
app/Http/Kernel.php
protected $routeMiddleware = [
'isAdmin' => isAdminMiddleware::class
];
}
視圖綁定變量
app下新建一個類 Status
<?php
namespace App;
class Status
{
public function total(){
return 45;
}
}
路由以前的做法是這樣
Route::get('/status',function(\App\Status $status){
return view('status',compact('status'));
});
status.blade.php
<h1>Status</h1>
{{$status->total()}}
模板綁定變量這樣寫:
路由:不傳遞任何變量
Route::get('/status',function(){
return view('status');
});
模板中註入變量:status.blade.php
@inject('status','App\Status')
本地化Model Factory
tinker:
factory(User::class,5)->create() //會寫庫
//或
factory(User::class,5)->make() //不會寫庫
App/Providers/AppServiceProvider.php
use Faker\Generator as FakerGenerator;
use Faker\Factory as FakerFactory;
public function boot()
{
$this->app->singleton(FakerGenerator::class,function (){
return FakerFactory::create('zh_CN');
});
}
再次用tinker生成的數據就是中文的了
DB::table(‘users‘)->truncate() 會將user表的數據全部刪除
分頁
路由:
Route::get('/lessons',function(){
$lessons = \App\Lesson::paginate(15);
return view('lessons',compact('lessons'));
});
模板
@extends('app')
@section('content')
<h1>Lessons</h1>
@foreach($lessons->chunk(3) as $row)
<div class="row">
@foreach($row as $lesson)
<div class="col-md-4">
<h2>{{ $lesson->title }}</h2>
<img style="width:100%; " src="{{$lesson->imageUrl}}" alt="">
<div class="body">
{{$lesson->intro}}
</div>
</div>
@endforeach
</div>
@endforeach
{!! $lessons->render() !!}
{{ $lessons->appends(['type'=>'article'])->links('vendor.pagination.bootstrap-4') }}
@stop
分頁兩種方式都可以
{!! $lessons->render() !!}
{{ $lessons->appends([‘type‘=>‘article‘])->links(‘vendor.pagination.bootstrap-4‘) }}
造測試數據 給article分配userId
$factory->define(\App\Article::class, function (Faker\Generator $faker) {
$userIds= \App\User::pluck('id')->toArray();
return [
'title' => $faker->sentence,
'content' => $faker->paragraph,
'user_id' => $faker->randomElements($userIds)[0]
];
});
find 可以傳入 id 也可以傳入數組
App\User::find([2,3])
with eager loading
user.php
public function posts(){
return $this->hasMany(Post::class)
}
路由:獲取當前用戶下的所有post
這裏的post只的就是對應的關系
$posts = \App\User::with('posts')->get()
多態關聯
應用場景:評論屬於文章 屬於lesson
php artisan make:model comment -m
comment migration
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->integer('commentable_id');
$table->string('commentable_type');
$table->text('body');
$table->timestamps();
});
}
comment.php 模型
class comment extends Model
{
public function commentable(){
return $this->morphTo();
}
}
post.php 模型
use App\comment;
class post extends Model
{
protected $guarded = array();
protected $events = [
'created' => PostWasPublished::class
];
public function comments(){
return $this->morphMany(comment::class,'commentable');
}
}
lesson.php 模型
class Lesson extends Model
{
protected $guarded = array();
public function comments(){
return $this->morphMany(comment::class,'commentable');
}
}
使用:
給某個lesson添加評論
$lesson = App\Lesson::find(1); $lesson->unguard(); $lesson->comments()->create(["body"=>"nice lesson"]);
通過評論來查看屬於哪個post
$comment = App\comment::find(1); $comment->commentable
有用的小方法
- dd( $article->created_at->diffForHumans() ); //幾分鐘前
- Config::get(‘database.default‘);
- app(‘config‘)[‘database‘][‘default‘]
- Hash::make(‘password‘)
- app(‘hash‘)->make(‘password‘)
- config(‘services‘)
- \Auth::login($user) //自動登錄
- Auth::check() //檢查是否登錄
- 密碼;bcrypt(str_random(16))
- model中設置 $hidden = [‘title‘] //有時您可能想要限制能出現在數組或 JSON 格式的屬性數據,比如密碼字段。只要在模型裏增加 hidden 屬性即可
acl權限
AuthServiceProvider.php
public function boot()
{
$this->registerPolicies();
Gate::define('show-post',function ($user,$article){
return $user->id ### $article->user_id;
});
}
controller.php 測試當前用戶是否有權限(當前post的id是否是當前用戶)訪問當前post,如果沒權限訪問則報錯403
public function show($id){
$article = Article::findOrFail($id);
//dd( $article->created_at->diffForHumans() );
//12 minits ago 如果需要中文可以
//可以在app/Providers/AppServiceProvider.php的boot()方法加上:
//\Carbon\Carbon::setLocale('zh');
if(Gate::denies('show-post',$article)){
abort(403,'sorry');
};
//也可以這麽寫
// $this->authorize('show-post',$article);
return view('articles.show',compact('article'));
}
如果要在blade中運用 則全部註釋掉
public function show($id){
$article = Article::findOrFail($id);
//dd( $article->created_at->diffForHumans() );
//12 minits ago 如果需要中文可以
//可以在app/Providers/AppServiceProvider.php的boot()方法加上:
//\Carbon\Carbon::setLocale('zh');
//if(Gate::denies('show-post',$article)){
//abort(403,'sorry');
//};
//也可以這麽寫
// $this->authorize('show-post',$article);
return view('articles.show',compact('article'));
}
模版中使用
@extends('app')
@section('content')
<h2>{{$article->title}}</h2>
<div>{{$article->content}}</div>
@can('show-post',$article)
<a href="">編輯</a>
@endcan
@stop
使用policy
policy的使用是為了更方便的創建用戶權限規則 避免了在AuthServiceProvider中定義一長串的規則
php artisan make:policy ArticlePolicy
添加policy 規則:
public function editArticle($user,$article){
return $user->id ### $article->user_id;
}
AuthServiceProvider.php中註冊該ArticlePolicy
protected $policies = [
'App\Article' => 'App\Policies\ArticlePolicy',
];
控制器使用:
if(Gate::denies('editArticle',$article)){
abort(403,'sorry');
};
模版中使用:
@extends('app')
@section('content')
<h2>{{$article->title}}</h2>
<div>{{$article->content}}</div>
@can('editArticle',$article)
<a href="">編輯</a>
@endcan
@stop
用戶權限
php artisan make:model Permission
php artisan make:model Role
php artisan make:migration create_roles_table --create=roles
編輯遷移文件:
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');//admin.member
$table->string('label')->nullable();//註冊會員
$table->timestamps();
});
Schema::create('permissions', function (Blueprint $table) {
$table->increments('id');
$table->string('name');//admin.member
$table->string('label')->nullable();//註冊會員
$table->timestamps();
});
Schema::create('permission_role', function (Blueprint $table) {
$table->integer('permission_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->foreign('permission_id')
->references('id')
->on('permissions')
->onDelete('cascade');
$table->foreign('role_id')
->references('id')
->on('roles')
->onDelete('cascade');
$table->primary(['permission_id','role_id']);
});
Schema::create('role_user', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('role_id')
->references('id')
->on('roles')
->onDelete('cascade');
$table->primary(['user_id','role_id']);
});
}
定義關系:
role.php
public function permissions(){
return $this->belongsToMany(Permission::class);
}
public function givePermission(Permission $permission){
return $this->permissions()->save($permission);
}permission.php
public function roles(){ return $this->belongsToMany(Role::class); }
user.php
public function roles(){ return $this->belongsToMany(Role::class); } public function hasRole($role){ //如果傳入的是字符串 if( is_string($role) ){ return $this->roles->contains('name',$role); } //如果傳入的是collection intersect 只的是 $role 和 $this->roles()有沒有交集 return !!$role->intersect( $this->roles )->count(); }
tinker 創建一個role 一個permission 並把permission指派給這個role
$role->givePermission($permission) 也可以直接 $role->permissions()->save($permission) $user->roles()->save($role) 給用戶分配角色 $user->roles()->detach($role) 刪除角色
authServiceProvider.php
public function boot()
{
$this->registerPolicies();
foreach ( $this->getPermission() as $permission ){
Gate::define( $permission->name,function (User $user) use($permission){
return $user->hasRole($permission->roles);
});
}
}
protected function getPermission(){
return Permission::with('roles')->get();
}
blade中這樣使用:
@can('edit')
<a href="">編輯edit</a>
@endcan
service container:
class Barz{}
class Foo{
public $bar;
public function __construct(Barz $barz)
{
$this->bar = $barz;
}
}
//如果有app綁定的優先找綁定的
App::bind('Foo',function (){
dd(12);
return new Foo(new BarZ());
});
Route::get('container',function (Foo $foo){
dd($foo);
});
App綁定後路由裏不再需要依賴註入
Route::get('container1',function (){
dd(app('Foo'));
});
service實戰 向IOC 容器添加自己的類
- 添加一個自己的類
App\Services\Billing\Stripe.php
<?php
namespace App\Services\Billing;
class Stripe
{
public function charge(){
dd('charged') ;
}
}
新建一個provider
php artisan make:provider BillingServiceProvider
註入服務 BillingServiceProvider.php , 註意要在app.php中註入這個provider
public function register() { $this->app->bind('billing',function(){ return new Stripe(); }); }
訪問 兩種方法均可:
Route::get('container2',function (){ dd(app('billing')->charge()); }); //或 Route::get('container2',function (\App\Services\Billing\Stripe $stripe){ dd($stripe->charge()); });
結合interface
重構代碼:
定義接口:App\Billing\BillingInterface.php
public function charge(array $data);定義類:App\Biling\PingBilling.php
class PingBilling implements BillingInterface{ public function charge($data){ //todo } }
聲明serviceprovider 把PingBilling這個類放到ioc container中 BillingServiceProvider
$this->app->bind(‘billing‘,‘App\Biling\PingBilling‘)
- app.php 添加 BillingServiceProvider
控制器中調用 app(‘billing‘)->charge($data)
=facade### =
每個facade例如 Route 類 返回的其實都是個字符串,關鍵是繼成了Facade類, Facade有個 __callStatic 方法,在一個類中執行一個不存在的靜態方法時 該方法會被觸發
Facade.php
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot();
if (! $instance) {
throw new RuntimeException('A facade root has not been set.');
}
return $instance->$method(...$args);
}
__callStatic 執行了 $instance = static::getFacadeRoot(); 生成一個實例,解析的結果是 app(‘mailer‘)
public static function getFacadeRoot()
{
//static::getFacadeAccessor() 指的就是 mailer, 這句解析的結果就是 app('mailer') 其實就是Mailer這個類,到這裏就必然有個provider綁定mailer 可在provider中查找
return static::resolveFacadeInstance(static::getFacadeAccessor());
}
目標:我希望我創建一個AjaxResponse的facade,這樣能直接在controller中這樣使用:
\AjaxResponse::success();
返回
{
code: "0"
result: {
}
}
步驟:
step1: 在app/Services文件夾中創建類
<?php namespace App\Services; class AjaxResponse { protected function ajaxResponse($code, $message, $data = null) { $out = [ 'code' => $code, 'message' => $message, ]; if ($data !== null) { $out['result'] = $data; } return response()->json($out); } public function success($data = null) { $code = ResultCode::Success; return $this->ajaxResponse(0, '', $data); } public function fail($message, $extra = []) { return $this->ajaxResponse(1, $message, $extra); } }
這個AjaxResponse是具體的實現類
step2: 創建provider
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class AjaxResponseServiceProvider extends ServiceProvider { public function register() { $this->app->singleton('AjaxResponseService', function () { return new \App\Services\AjaxResponse(); }); } }
這裏我們在register的時候定義了這個Service名字為AjaxResponseService
step3:在app/Facades文件夾中創建類
<?php namespace App\Facades; use Illuminate\Support\Facades\Facade; class AjaxResponseFacade extends Facade { protected static function getFacadeAccessor() { return 'AjaxResponseService'; } }
step4:好了,下面我們只需要到app.php中掛載上這兩個東東就可以了
<?php return [ ... 'providers' => [ ... 'App\Providers\RouteServiceProvider', 'App\Providers\AjaxResponseServiceProvider', ], 'aliases' => [ ... 'Validator' => 'Illuminate\Support\Facades\Validator', 'View' => 'Illuminate\Support\Facades\View', 'AjaxResponse' => 'App\Facades\AjaxResponseFacade', ], ];
使用name和email登錄
postLogin 方法:
$field = filter_var($request->input('username'), FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
$request->merge([$field => $request->get('username')]);
if(Auth::guard('admin')->attempt( $request->only($field, 'password'),
$request->remember)
){
//if successful,then intend the user to their intended location
return redirect()->intended(route('admin.dashboard'));
}else{
//if unsuccessful,then redirect back to the login with the form data
return redirect()->back()->withInput($request->only('username','remember'));
}
api
$lessons = Lesson::all();
\Response::json([
'status' => 'success',
'status_code' => 200,
'data' => $lessons->toArray()
]);
= 字段映射 ### =
$lessons = Lesson::all();
\Response::json([
'status' => 'success',
'status_code' => 200,
'data' => $this->transform($lessons->toArray())
]);
public function transform($lessons){
return array_map(function($lesson){
return [
'title' => $lesson['title'],
'content' => $lesson['body'],
'is_free' => (boolean)$lesson['free']
];
},$lessons);
}
註意 這個transform 是處理 collection的數據 all()
如果要處理elequent model 比如 Lesson::find(1)這樣的數據需要這麽處理transform方法,collection 用transformCollection方法:
public function transformCollection($lessons){
return array_map([$this,'transform'],$lessons);
}
public function transform($lesson){
return [
'title' => $lesson['title'],
'content' => $lesson['body'],
'is_free' => (boolean)$lesson['free']
];
}
= 代碼重構 ### =
比如有個article也需要使用transform
新建一個類 App\Transformer\Transformer.php
<?php namespace App\Transformer; abstract class Transformer { /** * @param $items * @return array */ public function transformCollection($items){ return array_map([$this,'transform'],$items); } /** * @param $item * @return mixed */ public abstract function transform($item);//抽象方法不用寫大括號 }
新建LessonTransform 並繼承Transformer類 App\Transformer\LessonTransform .php
<?php
namespace App\Transformer; class LessonTransformer extends Transformer { /** * @param $lesson * @return array */ public function transform($lesson){ return [ 'title' => $lesson['title'], 'content' => $lesson['intro'] ]; } }
Lesson控制器中依賴註入 並調用Transformer中的方法
protected $lessonTransformer;
public function __construct(LessonTransformer $lessonTransformer) { $this->lessonTransformer = $lessonTransformer; } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $lessons = Lesson::all(); return \Response::json([ 'status' => 'success', 'status_code' => 200, 'data' => $this->lessonTransformer->transformCollection($lessons->toArray()) ]); } public function show($id) { $lesson = Lesson::find($id); return \Response::json([ 'status' => 'success', 'status_code' => 200, 'data' => $this->lessonTransformer->transform($lesson) ]); }
= 錯誤提示 ### =
1.新建一個ApiController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ApiController extends Controller
{
protected $statusCode = 200;
/**
* @return int
*/
public function getStatusCode(): int
{
return $this->statusCode;
}
/**
* @param int $statusCode
*/
public function setStatusCode(int $statusCode)
{
$this->statusCode = $statusCode;
return $this;
}
public function responseNotFound( $message = 'Not Found' ){
return $this->responseError($message);
}
private function responseError($message){
return $this->response([
'status' => 'fail',
'status_code' => $this->getStatusCode(),
'message' => $message
]);
}
public function response($data){
return \Response::json($data);
}
}
2.控制器:LessonController.php 集成ApiController.php
public function show($id)
{
$lesson = Lesson::find($id);
if( !$lesson ) {
return $this->setStatusCode(500)->responseNotFound();
}
return $this->response([
'status' => 'success',
'data' => $this->lessonTransformer->transform($lesson)
]);
}
這時候訪問 transformer/2689 就會返回ApiController中的錯誤信息
{
"status": "fail",
"status_code": 404,
"message": "Not Found"
}
= postman禁用token ### =
app\kernel.php 註釋掉verifyCsrfToken.php
api驗證有三種:
= auth.basic 基礎驗證### =
控制器構造方法中:
public function __construct(){
$this->middleware('auth.basic',['only'=>['store','update']]);
}
laravel 有用的小方法
[http://www.cnblogs.com/webskill/p/7463488.html ]
laravel package
根目錄下新建目錄 packages/Laravist/Hasher/src
composer 自動加載 並 設置命名空間
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\": "app/",
"Laravist\Hasher\":"package/Laravist/Hasher/src/"
}
},src下新建一個類:Md5Hasher.php
<?php namespace Laravist\Hasher; class Md5hasher { public function make($value,array $options = []){ $salt = isset($options['salt']) ? $options['salt'] : ''; return hash('md5',$value.$salt); } public function check($value,$hashvalue,array $options = []){ $salt = isset($options['salt']) ? $options['salt'] : ''; return hash('md5',$value.$salt) ### $hashvalue; } }
加載這個類:
php artisan make:provider Md5HashProvider 移到 src下Md5HashProvider 中註冊使用方法:
public function register() { $this->app->singleton('md5hash',function (){ return new Md5hasher(); }); }
tinker中使用
app('md5hasher')->make('password')
自定義錯誤提示
resources/lang/en/validation.php
找到custom
將
‘custom‘ => [
‘attribute-name‘ => [
‘rule-name‘ => ‘custom-message‘,
],
],
改成:
‘custom‘ => [
‘name‘ => [
‘required‘ => ‘用戶名不能為空‘,
],
],
使用第三方插件 markdown
hyperDown github上 找到Parser.php app下新建文件 App\Markdown\Parser.php 註意命名空間
App\Markdown\Markdown.php
<?php namespace App\Markdown; class Markdown { protected $parser; public function __construct(Parser $parser) { $this->parser = $parser; } public function markdown($text){ $html = $this->parser->makeHtml($text); return $html; } } composer dump-autoload
控制器中使用
protected $markdown; public function __construct(Markdown $markdown) { $this->markdown = $markdown; $this->middleware('auth',['only'=>['create','store','edit','update']]); } public function show($id) { $discussion = Discussion::findOrFail($id); $html = $this->markdown->markdown($discussion->body) ; return view('forum.detail',compact('discussion','html')); }
view中使用
{!! $html !!}
storage
圖片上傳使用 storage_path(‘app/public‘) 這種的時候 默認圖片上傳到 storage/app/public 下面 , 需要 php artisan storage:link 鏈到 public目錄下
模糊查詢
$topics = \App\Topic::select(['id','name'])
->where('name','like','%'.$request->query('q').'%')
->get();
helper
App下建 Support/hellper.php
比如 Auth::guard(‘api‘)->user()->id 用的非常多,把它做成helper
helper.php
<?php
if(!!function_exists('user')){
function user($driver=null){
if ($driver){
return app('auth')->guard($driver)->user();
}
return app('auth')->user();
}
}
composer.json
"autoload": {
"files":[
"App/Support/helper.php"
],
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
可直接在控制器或blade中使用 user() 或者 user(‘api‘)
with 和 wherehas
with: 選擇所有的model, 每個model 關聯的translations 根據條件進行過濾,結果只有 title like $query 的translations不為空, 其他model的translations為空
return $this->model->with([
'translations' => function($q)use($query){
$q->where('title','like',"%{$query}%")
->select('product_id','title');
}
])
wherehas: 選出滿足條件的 model, 不是所有的model
$this->model->whereHas('translations', function($q)use($query){
$q->where('title', 'like', "%{$query}%");
})->get();
laravel5.4新特性