setAttribute
在表單中建立日期,然後直接處理,而不用在controller裡面寫時間原來的在controller裡面寫時間
app/Http/Controllers/ArticlesController.php public function store(Request $requests){ $input = Request::$requests->all(); $input['publish_at']=Carbon::now(); //原來這裡是通過直接硬性寫時間進去 Articles::create($input); return redirect('/articles'); }
改為在表單中處理時間
app/Http/Controllers/ArticlesController.php public function store(Request $requests){ //現在取消掉硬性寫時間 Articles::create($requests->all()); return redirect('/articles'); }
(表單)
resources/views/articles/create.blade.php@extends('layout.app')@section('content') 建立文章
{!! Form::open(['url'=>'/articles/store']) !!} {!! Form::label('title', 'Title:') !!} {!! Form::text('title', null, ['class' => 'form-control']) !!} {!! Form::label('content', 'Content:') !!} {!! Form::textarea('content', null, ['class' => 'form-control']) !!} {!! Form::label('publish_at', 'publish_at:') !!} {!! Form::date('publish_at', date('Y-m-d'), ['class' => 'form-control']) !!} //這裡寫時間,由使用者選擇輸入 {!! Form::submit('發表文章',['class'=>'btn btn-primary form-control']) !!} {!! Form::close() !!}@stop
在資料庫裡顯示的情況
id title content publish_at created_at updated_at5 我是一篇新文章 你好 2016-05-21 00:00:00 2016-05-21 07:32:48 2016-05-21 07:32:48 //這裡的時間只有日期,而沒有時分
所以,引申出一個解決辦法,在model裡面寫方法,通過model跟資料庫的關聯,從而在寫入資料庫的時候進行時間格式轉換(同理可鑒其他資料的處理)
這就是setAttribute 用法
在model裡面寫,寫一個自動處理的function setattribute
app/Articles.phpclass Articles extends Model{ protected $fillable=['title','content','publish_at']; public function setPublishAtAttribute($date) //set + 欄位名 + attribute 組成的,laravel會自動判斷欄位名,並且名字要遵循駝峰命名法 { $this->attributes['publish_at'] = Carbon::createFromFormat('Y-m-d',$date); //調用model的attributes方法來設定 }}
資料庫可以看到資料已經產生,並且時間有時分。
id title content publish_at created_at updated_at6 我是第二篇文章 愛的颯颯大 2016-05-27 08:17:29 2016-05-21 08:17:29 2016-05-21 08:17:29
原來的setattribute是叫setattribute的,不過也支援這樣中間插入一個欄位,在debug的過程中也可以看到他的轉換過程
in Carbon.php line 425at Carbon::createFromFormat('Y-n-j G:i:s', 'Y-m-d-2016-05-27-21 8:21:00', null) in Carbon.php line 368at Carbon::create('Y-m-d', '2016-05-27', null, null, null, null, null) in Carbon.php line 383at Carbon::createFromDate('Y-m-d', '2016-05-27') in Articles.php line 14 at Articles->setPublishAtAttribute('2016-05-27') in Model.php line 2860 //這裡調用setPublishAtAttributeat Model->setAttribute('publish_at', '2016-05-27') in Model.php line 447 //這裡就轉變成setAttributeat Model->fill(array('_token' => '', 'title' => '我是第二篇文章', 'content' => '愛的颯颯大', 'publish_at' => '2016-05-27')) in Model.php line 281at Model->__construct(array('_token' => '', 'title' => '我是第二篇文章', 'content' => '愛的颯颯大', 'publish_at' => '2016-05-27')) in Model.php line 569at Model::create(array('_token' => '', 'title' => '我是第二篇文章', 'content' => '愛的颯颯大', 'publish_at' => '2016-05-27')) in ArticlesController.php line 31at ArticlesController->store(object(Request))
queryscope
將原來的硬性寫在controller的處理時間的方法進行修改
app/Http/Controllers/ArticlesController.php public function index(){ $articles = Articles::latest()->where('publish_at','>=',Carbon::now())->get(); //這裡通過直接寫時間處理方法來實現資料處理 return view('articles.index',compact('articles')); }
改為:
public function index(){// $articles = Articles::latest()->where('publish_at','< =',Carbon::now())->get(); $articles = Articles::latest()->publish()->get(); //創造一個新的方法,目的是更靈活也讓目前的代碼更加簡潔和容易理解, //例如這裡就是從articles裡擷取大概是最後一條資料然後過濾publish時間然後擷取最終資料的大概意思,不用再看where什麼的了 return view('articles.index',compact('articles')); }
然後在model articles裡面添加scope
app/Articles.php public function scopePublish($query){ //scope文法限制,scope+剛才的publish函數名字(需要駝峰法命名) $query->where('publish_at','< =',Carbon::now()); //固定是傳入一個$query,暫時的理解是一個資料查詢結果,然後使用where過濾資料 }
因為是使用的是model articles的執行個體,scope命名會讓laravel會執行一些自動資料查詢,所以能夠將資料查詢結果$query傳入,並且處理
科普知識:
latest()返回的是一個builder對象
Builder|Builder latest(string $column = 'created_at')Add an "order by" clause for a timestamp to the query.Parametersstring $column Return ValueBuilder|Builder
builder對象是一個特殊的資料對象,是laravel的資料庫管理的一個對象,一個builder裡麵包含了很多資料資訊,方便直接使用。
alls方法返回的是一個collection對象
static Collection|Model[] all(array|mixed $columns = array('*'))Get all of the models from the database.Parametersarray|mixed $columns Return ValueCollection|Model[]
這是collection的格式:
Collection {#136 ▼ #items: array:6 [▼ 0 => Articles {#137 ▼ #fillable: array:3 [] #connection: null #table: null #primaryKey: "id" #perPage: 15 +incrementing: true +timestamps: true #attributes: array:6 [▼ "id" => 6 "title" => "我是第二篇文章" "content" => "愛的颯颯大" "publish_at" => "2016-05-27 08:17:29" "created_at" => "2016-05-21 08:17:29" //collection裡面的資料是數組包含對象,所以方便調用。 "updated_at" => "2016-05-21 08:17:29" ] #original: array:6 [] #relations: [] #hidden: [] #visible: [] #appends: [] #guarded: array:1 [] #dates: [] #dateFormat: null #casts: [] #touches: [] #observables: [] #with: [] #morphClass: null +exists: true +wasRecentlyCreated: false } 1 => Articles {#138 } 2 => Articles {#139 } 3 => Articles {#140 } 4 => Articles {#141 } 5 => Articles {#142 } ]}
這是builder的格式:
Builder {#128 ▼ #query: Builder {#127 ▼ #connection: MySqlConnection {#123 } #grammar: MySqlGrammar {#124 } #processor: MySqlProcessor {#125} #bindings: array:6 [] +aggregate: null +columns: null +distinct: false +from: "articles" +joins: null +wheres: array:1 [▼ //builder裡麵包含的資料會存在這裡,不過不能直接使用,需要使用像get這樣的方法來轉換資料。 0 => array:5 [▼ "type" => "Basic" "column" => "publish_at" "operator" => ">=" "value" => Carbon {#129 ▼ +"date": "2016-05-21 09:08:10.000000" +"timezone_type": 3 +"timezone": "UTC" } "boolean" => "and" ] ] +groups: null +havings: null +orders: array:1 [] +limit: null +offset: null +unions: null +unionLimit: null +unionOffset: null +unionOrders: null +lock: null #backups: [] #bindingBackups: [] #operators: array:26 [] #useWritePdo: false } #model: Articles {#121 ▼ #fillable: array:3 [] #connection: null #table: null #primaryKey: "id" #perPage: 15 +incrementing: true +timestamps: true #attributes: [] #original: [] #relations: [] #hidden: [] #visible: [] #appends: [] #guarded: array:1 [] #dates: [] #dateFormat: null #casts: [] #touches: [] #observables: [] #with: [] #morphClass: null +exists: false +wasRecentlyCreated: false } #eagerLoad: [] #macros: [] #onDelete: null #passthru: array:11 [] #scopes: []}