摘要:個(gè)人網(wǎng)站最近剛寫了一個(gè)手機(jī)在線播放的電影站使用日常手記更新使用的的查詢作用域的本地作用域去自定義可復(fù)用的約束集合,方便鏈?zhǔn)秸{(diào)用什么是本地查詢作用域本地作用域允許我們定義通用的約束集合以便在應(yīng)用中復(fù)用。
關(guān)于作者
使用Laravel5.3 日常手記程序開發(fā)人員,不拘泥于語言與技術(shù),目前主要從事PHP和前端開發(fā),使用Laravel和VueJs,App端使用Apicloud混合式開發(fā)。合適和夠用是最完美的追求。
個(gè)人網(wǎng)站:http://www.linganmin.cn
最近剛寫了一個(gè)手機(jī)在線播放的H5電影站:http://www.ifilm.ltd
2017.03.01更新
使用laravel的ORM的查詢作用域的本地作用域去自定義可復(fù)用的約束集合,方便鏈?zhǔn)秸{(diào)用什么是本地查詢作用域
本地作用域允許我們定義通用的約束集合以便在應(yīng)用中復(fù)用。例如,你可能經(jīng)常需要獲取訪問量大于指定數(shù)量的文章,要定義這樣的一個(gè)作用域,只需簡單在對(duì)應(yīng) Eloquent 模型方法前加上一個(gè) scope 前綴,作用域總是返回查詢構(gòu)建器,下面來實(shí)現(xiàn)這個(gè)例子:
news 數(shù)據(jù)表結(jié)構(gòu)如下
我們只需要在News對(duì)應(yīng)模型文件中增加一個(gè)方法如下(pv為訪問量)
/** * @param $query * @param $value * @return mixed */ public function scopePv($query, $value) { return $query->where("pv",">",$value); }
有了以上模型方法,我們就可以在任何可能用到的地方使用ORM的鏈?zhǔn)秸{(diào)用查詢了,舉例子如下
Route::any("test",function(){ // 使用我么自己定義的本地作用域約束集合獲取新聞閱讀量大于10的數(shù)據(jù) return AppModelsNews::pv(10)->get(); });我們可以使用trait做的更通用
比如當(dāng)我們有三張新聞?lì)愊嚓P(guān)的數(shù)據(jù)分別是news,readings,deepnesses,表結(jié)構(gòu)不盡相同但有些字段是相同的,比如瀏覽量pv等,如果當(dāng)有需求為查看這三張表中pv大于100的時(shí)候,使用laravel自帶的ORM模型操作如下:
AppModelsNews::where("pv",">","100")->get(); AppModelsReading::where("pv",">","100")->get(); AppModelsDeepness::where("pv",">","100")->get();
可以看到,這樣寫會(huì)有不少的代碼冗余,所以我們可以按照上面的方法使用本地作用域為每個(gè)模型去構(gòu)建一個(gè)叫scopePv的方法,者樣就可以在查詢指定的閱讀量的時(shí)候直接使用pv方法,如下:
AppModelsNews::pv(100)->get(), AppModelsReading::pv(100)->get(), AppModelsDeepness::pv(100)->get(),
然而在每個(gè)模型中去構(gòu)建一個(gè)相同的方法也是會(huì)有代碼冗余,當(dāng)然你也可以在新建一個(gè)模型類的基類,在基類離去添加這個(gè)方法,然后每個(gè)模型再去繼承模型基類,但是這里推薦的是使用trait的方式
自 PHP 5.4.0 起,PHP 實(shí)現(xiàn)了一種代碼復(fù)用的方法,稱為 trait。
Trait 是為類似 PHP 的單繼承語言而準(zhǔn)備的一種代碼復(fù)用機(jī)制。Trait 為了減少單繼承語言的限制,使開發(fā)人員能夠自由地在不同層次結(jié)構(gòu)內(nèi)獨(dú)立的類中復(fù)用 method。Trait 和 Class 組合的語義定義了一種減少復(fù)雜性的方式,避免傳統(tǒng)多繼承和 Mixin 類相關(guān)典型問題。
我們可以在laravel項(xiàng)目的app目錄下新建一個(gè)叫Traits的文件夾,在里面可以創(chuàng)建各種trait文件,laravel框架中其實(shí)大量使用到了PHP的trait特性,比如模型的軟刪除SoftDeletes等
還是接著說上面的例子,為演示代碼我在appTraits目錄下創(chuàng)建了一個(gè)叫GeneralModelMethods.php的trait文件,
里面定義的代碼如下:
/** * Created by PhpStorm. * User: saboran * Date: 2017/3/2 * Time: 8:23 */ namespace AppTraits; trait GeneralModelMethods { public function scopePv($query, $value) { return $query->where("pv",">",$value); } }
定義完后只需在每個(gè)需要使用到的模型中使用關(guān)鍵字use一下這個(gè)trait文件后,就可以像上面在模型中定義這個(gè)本地約束集合一樣使用了
在appProvidersAppServiceProvider.php的register方法中加入如下代碼
// 設(shè)置模型工廠數(shù)據(jù)格式為中文 $this->app->bind("FakerGenerator",function(){ return Factory::create($locale = "zh_CN"); });
設(shè)置默認(rèn)語言后,可以在工廠模型中使用一些方法生成符合國內(nèi)格式的填充數(shù)據(jù),比如中文姓名,中國手機(jī)號(hào)碼等等,下面是一個(gè)簡單的用戶工廠
$factory->define(AppUser::class, function (FakerGenerator $faker) { return [ "mobile" => $faker->phoneNumber, // 可以生產(chǎn)中國手機(jī)號(hào)格式的手機(jī)換號(hào)碼 "username" => $faker->name, // 可以生產(chǎn)中文姓名 "realname" => $faker->word, "nickname" => $faker->word, "password" => bcrypt($faker->password), "email" => $faker->safeEmail, "avatar" => $faker->word, "gender" => $faker->word, "role_id" => $faker->randomNumber(), "status" => $faker->randomNumber(), "deleted_at" => $faker->dateTimeBetween(), ]; });
詳細(xì)模型工廠的使用方式,請(qǐng)移步 中文官方文檔
生成測(cè)試數(shù)據(jù)可以使用這個(gè)laravel擴(kuò)展包:mpociot/laravel-test-factory-helper
擴(kuò)展包GitHub地址:https://github.com/mpociot/la...
一套流程走下來,總結(jié)如下:
先執(zhí)行 php artisan make:migration create_xxxx_table --create=xxx生成所需的所有表的遷移文件
在各遷移文件中寫入相應(yīng)字段和索引,不包含外鍵
多帶帶創(chuàng)建一個(gè)增加外鍵的遷移文件,比如php artisan make:migration add_foreign_key,在里面增加所有表的外鍵關(guān)系
為什么這樣做呢,而不是在每個(gè)表的遷移文件中創(chuàng)建對(duì)應(yīng)外鍵呢?因?yàn)椋谧詈髨?zhí)行php artisan migrate生成遷移文件時(shí)是按照創(chuàng)建遷移文件的順序去創(chuàng)建數(shù)據(jù)表,這就會(huì)出現(xiàn)一個(gè)問題,比如有一張角色表和一張用戶表,用戶表的role_id外鍵連接到角色表的id,這樣如果我們?cè)趧?chuàng)建遷移文件時(shí)先創(chuàng)建用戶的遷移文件,后創(chuàng)建角色的遷移文件,那么在執(zhí)行php artisan migrate的時(shí)候,就會(huì)報(bào)錯(cuò),提示外鍵無法創(chuàng)建,無法創(chuàng)建是因?yàn)槟莻€(gè)字段的外鍵的所屬表還不存在,而為了避免這種問題出現(xiàn),比較好的解決方法,就是先將所有遷移文件創(chuàng)建好,最后再添加一個(gè)遷移文件去給所有需要增加外鍵的字段創(chuàng)建外鍵關(guān)系,這個(gè)時(shí)候,所有數(shù)據(jù)表都已經(jīng)存在,也就不會(huì)有上面所說的問題出現(xiàn)
使用擴(kuò)展或者手動(dòng)創(chuàng)建對(duì)應(yīng)數(shù)據(jù)表的Model文件
為什么要自定義驗(yàn)證規(guī)則,因?yàn)長aravel框架本身給我們提供的驗(yàn)證規(guī)則是有限的,很多時(shí)候我們需根據(jù)自己的實(shí)際需求去增加對(duì)應(yīng)的驗(yàn)證方法,比如我們現(xiàn)在需要增加一個(gè)驗(yàn)證中國手機(jī)號(hào)碼格式的方法,如下:
增加驗(yàn)證規(guī)則方式如下在AppServiceProvider.php中的boot方法中定義一個(gè)驗(yàn)證規(guī)則,驗(yàn)證規(guī)則格式如下:
Validator::extend("foo", function($attribute, $value, $parameters, $validator) { // do something to deal $value ... // 返回處理后的值 return $value == "foo"; });下面是增加一個(gè)中國手機(jī)號(hào)碼格式驗(yàn)證規(guī)則
Validator::extend("mobile",function($attribute,$value,$parameters,$validator){ return preg_match("/^1(3[0-9]|4[57]|5[0-35-9]|7[0135678]|8[0-9])d{8}$/",$value); });
關(guān)于trait附上一篇安正超大神的文章和PHP中文文檔對(duì)trait的介紹注:當(dāng)我們自己創(chuàng)建的驗(yàn)證規(guī)則過多時(shí),boot方法中就會(huì)顯得特別臃腫,違反了Laravel一貫優(yōu)雅的寫法,所以當(dāng)我們需要增加多個(gè)驗(yàn)證規(guī)則時(shí),我們可以去創(chuàng)建一個(gè)trait文件,在里面創(chuàng)建一個(gè)方法用來創(chuàng)建這些驗(yàn)證規(guī)則,然后在AppServiceProvider.php中use過來,并在boot方法中調(diào)用即可,關(guān)于trait后面詳細(xì)說
安正超博客 我所理解的trait
PHP中文文檔 Trait實(shí)現(xiàn)代碼復(fù)用方法
一個(gè)還不錯(cuò)的模型生成擴(kuò)展包,支持從數(shù)據(jù)庫生成模型各個(gè)表之間的關(guān)系,支持自定義 namespace 和生成的Model路徑
使用場景大致為使用migration建好遷移文件,執(zhí)行php artisan migrate生成數(shù)據(jù)表之后,從數(shù)據(jù)表生成模型文件
擴(kuò)展包 GitHub地址,readme里面有詳細(xì)使用說明。
使用配置文件定義生成路徑和命名空間可以省去每次在命令行指定生成路徑和命名空間,方法如下:
在laravel的配置文件目錄創(chuàng)建文件eloquent_model_generator.php,在該配置文件中覆蓋擴(kuò)展包里面設(shè)置的默認(rèn)路徑
return [ "model_defaults" => [ "namespace" => "SomeOtherNamespace", // 設(shè)置命名空間 "base_class_name" => "SomeOtherClassName", // 設(shè)置模型繼承的基類 "output_path" => "/full/path/to/output/directory", // 設(shè)置模型的輸出目錄 "no_timestamps" => true, // 設(shè)置時(shí)間戳 "date_format" => "U", // 設(shè)置時(shí)間格式化格式 "connection" => "other-connection", // 設(shè)置數(shù)據(jù)庫連接 ], ];
下面是一個(gè)我自己使用到的設(shè)置
return [ "model_defaults" => [ "namespace" => "AppModels", "base_class_name" => IlluminateDatabaseEloquentModel::class, "output_path" => "appModels", "no_timestamps" => null, "date_format" => null, "connection" => null, ], ];
GitHub地址
laravel-admin 是一個(gè)可以快速幫你構(gòu)建后臺(tái)管理的工具,它提供的頁面組件和表單元素等功能,能幫助你使用很少的代碼就實(shí)現(xiàn)功能完善的后臺(tái)管理功能。而且該包還有詳細(xì)的中文文檔(雖然寫的不是那么完美),下面說一說文檔上沒有寫的一些東西和自己填的坑
關(guān)于無限極分類官方文檔地址 數(shù)據(jù)模型樹,如果根據(jù)他文檔上這樣去配置之后直接去訪問當(dāng)分類沒有子分類時(shí)會(huì)發(fā)現(xiàn)是報(bào)錯(cuò)的,原因是該包的模板文件branch.blade.php中一個(gè)判斷寫的并不嚴(yán)謹(jǐn),源文件中代碼如下
@if(isset($branch["children"]))@foreach($branch["children"] as $branch) @include($branchView, $branch) @endforeach
@endif
isset($branch["children"])并不能判斷到當(dāng)$branch["children"]為空時(shí)去阻止執(zhí)行下面的代碼,而當(dāng)$branch["children"]為空時(shí),下面的遍歷便會(huì)出錯(cuò),所以我們要將isset($branch["children"])改為!empty($branch["children"])
無限極分類做select下拉框數(shù)據(jù)無限極分類做select下拉框數(shù)據(jù)時(shí)應(yīng)該在option()方法中傳遞分類的自帶的方法Category::selectOptions(),如下為實(shí)例
$form->select("parent_id","上級(jí)分類")->options(Category::selectOptions());關(guān)于列的editalbe
在index方法展示數(shù)據(jù)時(shí),如果想使用點(diǎn)擊更改,最好將editable()放在鏈?zhǔn)秸{(diào)用的最后,這樣就可以在editable()使用display()將數(shù)據(jù)處理成想要的格式
下面裝個(gè)例子是處理性別,數(shù)據(jù)庫中存儲(chǔ)規(guī)則是:f代表女生,m代表男生,空代表未知性別,所以展示的鏈?zhǔn)秸{(diào)用如下:
// 鏈?zhǔn)秸{(diào)用處理性別展示 $grid->gender()->display(function ($gender){ // 閉包函數(shù)傳遞當(dāng)前字段值 $data = [ "f"=>"女", "m"=>"男", ""=>"未知" ]; // 根據(jù)字段值返回顯示的中文名稱 return $data[$gender]; // 使用editable()方法實(shí)現(xiàn)列可編輯 })->editable("select", ["" => "未知性別", "m" => "男", "f" => "女"]);關(guān)于導(dǎo)出Excel文件亂碼,
因?yàn)橹形牡腤indows操作系統(tǒng)微軟默認(rèn)設(shè)置的字符編碼都是gbk,包括office和cmd控制臺(tái)等等,而我們數(shù)據(jù)庫里一般存的都是utf-8編碼,所以在導(dǎo)出數(shù)據(jù)時(shí)一定要將從數(shù)據(jù)庫獲取到的數(shù)據(jù)轉(zhuǎn)碼,根據(jù)該擴(kuò)展官方文檔導(dǎo)出數(shù)據(jù)的使用方法,只需增加一行轉(zhuǎn)碼即可,代碼如下
namespace AppAdminExtensions; use EncoreAdminGridExportersAbstractExporter; class CustomExporter extends AbstractExporter { /** * {@inheritdoc} */ public function export() { $titles = []; $filename = $this->getTable() . ".csv"; $data = $this->getData(); if (!empty($data)) { $columns = array_dot($this->sanitize($data[0])); $titles = array_keys($columns); } $output = implode(",", $titles) . " "; foreach ($data as $row) { $row = array_only($row, $titles); $output .= implode(",", array_dot($row)) . " "; } $headers = [ "Content-Encoding" => "UTF-8", "Content-Type" => "text/csv;charset=UTF-8", "Content-Disposition" => "attachment; filename="$filename"", ]; $output = iconv("UTF-8","GBK",$output); response(rtrim($output, " "), 200, $headers)->send(); exit; } /** * Remove indexed array. * * @param array $row * * @return array */ protected function sanitize(array $row) { return collect($row)->reject(function ($val, $_) { return is_array($val) && !Arr::isAssoc($val); })->toArray(); } }
安小下同學(xué)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/22447.html
摘要:前言開發(fā)爬蟲是一件有趣的事情。的可配置爬蟲是基于的,因此天生是支持并發(fā)的。遵守協(xié)議這個(gè)默認(rèn)是開啟的。的可配置爬蟲降低了爬蟲的開發(fā)時(shí)間,增加了爬蟲開發(fā)效率,完善了工程化水平,將爬蟲工程師從日常的繁瑣配置工作中解放出來。 前言 開發(fā)爬蟲是一件有趣的事情。寫一個(gè)程序,對(duì)感興趣的目標(biāo)網(wǎng)站發(fā)起HTTP請(qǐng)求,獲取HTML,解析HTML,提取數(shù)據(jù),將數(shù)據(jù)保存到數(shù)據(jù)庫或者存為CSV、JSON等格式,再...
摘要:前言開發(fā)爬蟲是一件有趣的事情。的可配置爬蟲是基于的,因此天生是支持并發(fā)的。的可配置爬蟲降低了爬蟲的開發(fā)時(shí)間,增加了爬蟲開發(fā)效率,完善了工程化水平,將爬蟲工程師從日常的繁瑣配置工作中解放出來。前言 開發(fā)爬蟲是一件有趣的事情。寫一個(gè)程序,對(duì)感興趣的目標(biāo)網(wǎng)站發(fā)起HTTP請(qǐng)求,獲取HTML,解析HTML,提取數(shù)據(jù),將數(shù)據(jù)保存到數(shù)據(jù)庫或者存為CSV、JSON等格式,再用自己熟悉的語言例如Python對(duì)...
摘要:合適和夠用是最完美的追求。比如從頁面去請(qǐng)求的資源。它允許瀏覽器向跨源服務(wù)器,發(fā)出請(qǐng)求,從而克服了只能同源使用的限制。定義在中的路由都是無狀態(tài)的,并且會(huì)應(yīng)用中間件組。 關(guān)于作者 程序開發(fā)人員,不拘泥于語言與技術(shù),目前主要從事PHP和前端開發(fā),使用Laravel和VueJs,App端使用Apicloud混合式開發(fā)。合適和夠用是最完美的追求。 個(gè)人網(wǎng)站:http://www.linganm...
摘要:合適和夠用是最完美的追求。比如從頁面去請(qǐng)求的資源。它允許瀏覽器向跨源服務(wù)器,發(fā)出請(qǐng)求,從而克服了只能同源使用的限制。定義在中的路由都是無狀態(tài)的,并且會(huì)應(yīng)用中間件組。 關(guān)于作者 程序開發(fā)人員,不拘泥于語言與技術(shù),目前主要從事PHP和前端開發(fā),使用Laravel和VueJs,App端使用Apicloud混合式開發(fā)。合適和夠用是最完美的追求。 個(gè)人網(wǎng)站:http://www.linganm...
閱讀 1291·2021-09-22 15:00
閱讀 3309·2019-08-30 14:00
閱讀 1220·2019-08-29 17:27
閱讀 1220·2019-08-29 16:35
閱讀 689·2019-08-29 16:14
閱讀 2042·2019-08-26 13:43
閱讀 2117·2019-08-26 11:35
閱讀 2309·2019-08-23 15:34