ThinkPHP8開(kāi)發(fā)規(guī)范完整版_第1頁(yè)
ThinkPHP8開(kāi)發(fā)規(guī)范完整版_第2頁(yè)
ThinkPHP8開(kāi)發(fā)規(guī)范完整版_第3頁(yè)
ThinkPHP8開(kāi)發(fā)規(guī)范完整版_第4頁(yè)
ThinkPHP8開(kāi)發(fā)規(guī)范完整版_第5頁(yè)
已閱讀5頁(yè),還剩35頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

ThinkPHP8開(kāi)發(fā)規(guī)范PHP版本選擇如果是新的項(xiàng)目,目前應(yīng)該盡量選擇PHP8.2+作為你的PHP版本,可以擁有更好的性能,ThinkPHP8.0版本的最低版本要求是PHP8.0。有些PHP擴(kuò)展可能不支持PHP的高版本,這個(gè)時(shí)候你要做出選擇,使用低版本還是尋求更好的擴(kuò)展解決方案?;久?guī)范ThinkPHP遵循PSR-2命名規(guī)范以及PSR-4自動(dòng)加載規(guī)范,并注意如下規(guī)范:如果你沒(méi)有遵循某些規(guī)范,可能會(huì)導(dǎo)致部分功能的異常。類(包括接口、rait)文件名和類名保持一致,并且使用首字母大寫的駝峰命名;函數(shù)文件、配置文件、路由定義文件等文件名使用小寫規(guī)范;無(wú)論類還是普通文件都使用.php后綴;目錄名統(tǒng)一使用小寫規(guī)范,并且使用單數(shù)規(guī)范;模板文件使用小寫規(guī)范;配置參數(shù)名統(tǒng)一使用小寫規(guī)范;常量定義統(tǒng)一使用大寫規(guī)范;環(huán)境變量定義統(tǒng)一使用大寫規(guī)范;\hThinkPHP知識(shí)庫(kù)函數(shù)的命名使用小寫字母和下劃線(小寫字母開(kāi)頭)的方式,例如get_client_ip;方法的命名使用駝峰法(首字母小寫),例如getUserName;屬性的命名使用駝峰法(首字母小寫),例如tableName、instance;特例:以雙下劃線__打頭的函數(shù)或方法作為魔術(shù)方法,例如__call和__callStatic;使?統(tǒng)?的IDE以及代碼規(guī)范配置或者插件項(xiàng)目團(tuán)隊(duì)?wèi)?yīng)當(dāng)盡量使用統(tǒng)一的IDE作為開(kāi)發(fā)工具,并規(guī)范一致的代碼規(guī)范配置項(xiàng),如果使用的第三方代碼規(guī)范及自動(dòng)完成插件。如果團(tuán)隊(duì)成員較多而無(wú)法完全統(tǒng)一,最低限度,項(xiàng)目代碼風(fēng)格必須遵循PSR-1和PSR-2規(guī)范。助?函數(shù)助手函數(shù)的初衷是為了簡(jiǎn)化代碼和更方便記憶,但如果不是很清楚助手函數(shù)的內(nèi)部實(shí)現(xiàn)原理,很容易導(dǎo)致濫用,由于現(xiàn)代的IDE提示和自動(dòng)完成功能之強(qiáng)大,助手函數(shù)的作用非常有限,而且只會(huì)用助手函數(shù)對(duì)于框架的原理認(rèn)識(shí)較淺,因此建議是掌握助手函數(shù)的內(nèi)部實(shí)現(xiàn)原理后再來(lái)決定在項(xiàng)目規(guī)范中是否需要使用助手函數(shù),以及如何使用。畢竟有些場(chǎng)景下,助手函數(shù)是非常簡(jiǎn)單實(shí)用的,例如:publicfunctiongetUser($id){$user=User::getOrEmpty($id);returnjson($user);}產(chǎn)品交付給客戶的時(shí)候,有些時(shí)候助手函數(shù)能夠讓客戶自定義模板的時(shí)候更方便。如果你需要額外定義或者覆蓋原有的助手函數(shù),可以直接在應(yīng)用的common.php公共文件中定義。配置規(guī)范線上環(huán)境和本地測(cè)試環(huán)境應(yīng)該使用一致的配置文件,差異化的配置使用環(huán)境變量方式處理。本地環(huán)境可以通過(guò)定義.env文件(注意添加到忽略文件列表)來(lái)模擬環(huán)境變量。在你需要差異化配置的參數(shù)中使用env函數(shù)定義,例如:\hThinkPHP知識(shí)庫(kù)然后在環(huán)境變量中或者本地.env中定義DB_HOST=2盡量不要在配置文件以外使用env函數(shù)獲取配置參數(shù)。統(tǒng)一使用config函數(shù)獲取配置參數(shù)。除了定義配置文件之外,避免使用動(dòng)態(tài)配置功能,保持僅讀取配置參數(shù)的良好習(xí)慣。如果需要提高配置文件的性能,可以考慮使用Yaconf擴(kuò)展。安裝composertopthink/think-yaconf?志規(guī)范日志記錄建議直接使用PSR-3規(guī)范提供的接口方法記錄,例如:Log::record('測(cè)試日志','error');Log::record('測(cè)試日志','info');應(yīng)當(dāng)改為L(zhǎng)og::error('測(cè)試日志');Log::info('測(cè)試日志');支持的方法包括debug, info, notice, warning, error, critical, alert,emergency以及用于SQL日志記錄的sql方法。默認(rèn)情況下,日志是延時(shí)寫入的,如果要實(shí)時(shí)寫入日志信息,可以使用write方法Log::wirte('測(cè)試日志','info');確保設(shè)置日志的最大數(shù)量限制,避免日志空間過(guò)大導(dǎo)致存儲(chǔ)空間占滿。\hThinkPHP知識(shí)庫(kù)超過(guò)設(shè)置的數(shù)量后,最早的日志將會(huì)被自動(dòng)清理。如果需要把日志接入阿里云,可以設(shè)置為單一日志文件,具體可以參考\h:thinkphp日志接入阿里\h云日志系統(tǒng)規(guī)范部署請(qǐng)務(wù)必把你的WEB根目錄指向public目錄而不是應(yīng)用根目錄,并且不要隨意更改入口文件的位置。public目錄下面不要放除了入口文件和資源文件以外的其它應(yīng)用文件。保持測(cè)試環(huán)境和部署環(huán)境的?致性在開(kāi)發(fā)過(guò)程中,應(yīng)該盡量保持你的測(cè)試環(huán)境和正式部署環(huán)境的一致性,包括運(yùn)行環(huán)境和版本,無(wú)論在本地測(cè)試環(huán)境還是部署環(huán)境,都應(yīng)當(dāng)統(tǒng)一使用域名方式訪問(wèn),本地可以使用測(cè)試域名,例如你的正式部署域名為,那么本地測(cè)試環(huán)境可以使用thinkphp或者thinkphp.test作為測(cè)試域名,避免使用localhost或者這種測(cè)試地址。對(duì)于有多個(gè)域名的部署應(yīng)用,本地也要盡量模擬多個(gè)域名。關(guān)閉調(diào)試模式在部署到生產(chǎn)環(huán)境的時(shí)候,確保你已經(jīng)關(guān)閉了調(diào)試模式,可以通過(guò)修改環(huán)境變量的方式關(guān)閉調(diào)試模式。APP_DEBUG=false無(wú)論是本地開(kāi)發(fā)還是生產(chǎn)環(huán)境部署,都建議保持統(tǒng)一的配置文件,然后通過(guò)修改環(huán)境變量的方式(本地開(kāi)發(fā)可以通過(guò)定義.env文件)設(shè)置區(qū)別部分。關(guān)閉調(diào)試模式后,系統(tǒng)的健康狀態(tài)和運(yùn)行監(jiān)控主要依靠日志或者你使用的監(jiān)控服務(wù)。所以,要養(yǎng)成定時(shí)檢查日志和運(yùn)行狀態(tài)的習(xí)慣。部署忽略清單項(xiàng)目根目錄下面有一個(gè).gitignore文件,用于定義提交版本庫(kù)的時(shí)候哪些文件或者目錄需要忽略,設(shè)置忽略的文件不會(huì)被同步到遠(yuǎn)程服務(wù)器,只是用于本地開(kāi)發(fā)。\hThinkPHP知識(shí)庫(kù)/.idea/.vscode/vendor*.log.env項(xiàng)目使用的核心框架以及composer安裝的擴(kuò)展,不應(yīng)當(dāng)被同步到版本庫(kù)中,只需要同步composer.json以及composer.lock文件。然后在服務(wù)器端進(jìn)行composer更新。做好應(yīng)?優(yōu)化?作參考\h如何有效提高ThinkPHP的應(yīng)用性能一文做好相關(guān)優(yōu)化工作。使?持續(xù)集成/持續(xù)部署構(gòu)建你的項(xiàng)?如果條件允許,請(qǐng)使用\h持續(xù)集成/持續(xù)部署,并添加自動(dòng)化測(cè)試。\hTravisCI或\h者PHPCI都是不錯(cuò)的選擇。編寫項(xiàng)?文檔每個(gè)項(xiàng)目都應(yīng)該在根目錄添加readme.md文件,并遵循Markdown規(guī)范寫作,對(duì)項(xiàng)目做簡(jiǎn)要的說(shuō)明(尤其是目錄和代碼規(guī)范),如果項(xiàng)目比較復(fù)雜,可以附上一個(gè)項(xiàng)目詳細(xì)說(shuō)明或者規(guī)范的文檔地址(托管到\h頂想云知識(shí)管理上是一個(gè)很好的選擇),如果你的項(xiàng)目是前后端完全分離開(kāi)發(fā)的話,應(yīng)該事先規(guī)劃好后臺(tái)的API接口,然后創(chuàng)建一個(gè)API文檔,便于指導(dǎo)前端開(kāi)發(fā)人員進(jìn)行接口調(diào)用,以及方便在線調(diào)試。路由規(guī)范所有的路由規(guī)則是不支持普通URL參數(shù)的,必須是PATHINFO地址。路由定義文件不一定是route.php,事實(shí)上可以是任何文件名。如果你開(kāi)啟了路由強(qiáng)制模式,那么未定義的路由訪問(wèn)將會(huì)拋出異常。統(tǒng)一使用路由方法注冊(cè)路由而不要再使用返回?cái)?shù)組配置,路由規(guī)則不區(qū)分大小寫,因此統(tǒng)一使用小寫定義。盡量避免使用閉包定義路由規(guī)則(注意不要和分組路由的閉包定義搞混淆),優(yōu)先使用資源路由定義,在不適用資源路由的情況下也要多使用路由分組,不僅可以簡(jiǎn)化路由定義和提高性能,也\hThinkPHP知識(shí)庫(kù)大部分情況下,建議開(kāi)啟全局路由完整匹配,個(gè)別不需要完整匹配的路由規(guī)則可以在定義的時(shí)候使用completeMatch方法單獨(dú)關(guān)閉。Route::get('user/<name>','user/info')->completeMatch(false);如果需要使用偽靜態(tài)地址,可以全局配置URL訪問(wèn)后綴,對(duì)于個(gè)別特殊后綴的路由可以在路由定義的時(shí)候單獨(dú)指定。Route::get('hello/<name>','index/hello')->ext('htm');明確你的路由變量規(guī)則,不要忽略路由變量的規(guī)則定義,避免可能的解析錯(cuò)誤。例如,當(dāng)你的路由變量中使用了小數(shù)點(diǎn)或者斜線的情況,必須嚴(yán)格定義你的變量規(guī)則。優(yōu)先在路由定義的時(shí)候指定中間件、進(jìn)行數(shù)據(jù)驗(yàn)證和請(qǐng)求緩存等操作,原則就是在路由里面能做的事情盡量提前不要等到控制器里面才執(zhí)行。為了方便查看當(dāng)前項(xiàng)目定義的路由規(guī)則,可以使用下面的指令生成路由規(guī)則查看文件。phpthinkroute:list然后可以在runtime目錄下的route_list.php可以查看所有的路由列表。關(guān)閉路由如果某個(gè)應(yīng)用需要關(guān)閉路由功能,可以在應(yīng)用的app.php配置文件中定義'with_route' => false,但需要注意的是,即使關(guān)閉路由,也會(huì)走默認(rèn)路由(即控制器/操作)解析,因此路由全局中間件仍然有效。明確定義請(qǐng)求類型盡量明確定義路由的請(qǐng)求類型,提高路由解析的效率。推薦使用:\hThinkPHP知識(shí)庫(kù)替代:Route::rule('hello/:name','index/hello');不需要添加開(kāi)頭斜線除了首頁(yè)外,其它路由規(guī)則定義不需要添加開(kāi)頭的斜線。推薦使用:Route::get('hello/:name','index/hello');不建議使用:Route::get('/hello/:name','index/hello');除非是首頁(yè)路由Route::get('/','index/index');或者直接訪問(wèn)分組名的情況Route::group('blog',function(){Route::get('/','index/blog');Route::get(':id$','blog/read');Route::get(':id/edit$','blog/edit');});多使?路由分組可能的情況下,盡可能多使用路由分組??梢猿浞掷梅纸M的匹配機(jī)制提高路由解析性能。推薦使用\hThinkPHP知識(shí)庫(kù)Route::get(':id/edit$','blog/edit');});不建議使用Route::get('blog/:id$','blog/read');Route::get('blog/:id/edit$','blog/edit');路由分組傳入額外參數(shù)可以統(tǒng)一給分組路由傳入額外的參數(shù)Route::group('blog',function(){Route::get(':id$','blog/read');Route::get(':id/edit$','blog/edit');})->ext('html')->pattern(['id'=>'\d+'])->append(['group_id'=>1]);上面的分組路由統(tǒng)一傳入了group_id參數(shù),該參數(shù)的值可以通過(guò)Request類的param方法獲取。路由變量定義規(guī)范對(duì)于新版的路由變量定義來(lái)說(shuō),不再區(qū)分普通變量和組合變量,哪怕你使用:name方式定義,內(nèi)部也會(huì)統(tǒng)一轉(zhuǎn)換成<name>這種方式,因此為了提高路由解析性能,建議統(tǒng)一使用:Route::group('blog',function(){Route::get('<id>$','blog/read');Route::get('<id>/edit$','blog/edit');});盡量明確定義路由變量的規(guī)則Route::group('blog',function(){Route::get('<id>$','blog/read');\hThinkPHP知識(shí)庫(kù)路由變量規(guī)則采用正則表達(dá)式方式定義,但無(wú)需在開(kāi)頭添加^或者在最后添加$,也無(wú)需使用模式修飾符,系統(tǒng)會(huì)自動(dòng)添加。不能使用$_GET方法或者Request類的get方法獲取路由變量,而應(yīng)該使用param方法或者參數(shù)綁定。如果開(kāi)啟了路由合并解析的話,分組下面的多個(gè)路由規(guī)則是通過(guò)一次解析匹配完成的,如果路由規(guī)則較多性能會(huì)有大幅提升。變量分隔符你可以很隨意的使用路由變量分隔符,只要注意不要和你的變量規(guī)則沖突。Route::get('item/<date><name>-<id>','product/item')->pattern(['date'=>'\d{8}','name'=>'\w+','id'=>'\d+']);默認(rèn)路由變量規(guī)則默認(rèn)情況下,如果你沒(méi)有定義變量規(guī)則,則使用\w+作為變量規(guī)則Route::get('hello/<name>','index/hello');其實(shí)等同于Route::get('hello/<name>','index/hello')->pattern(['name' => '\w+',]);如果你希望改變默認(rèn)的路由變量規(guī)則,可以在應(yīng)用配置文件中設(shè)置//默認(rèn)的路由變量規(guī)則'default_route_pattern'=>'[a-z0-9\-\_\.]+',路由完全匹配\hThinkPHP知識(shí)庫(kù)所以Route::get('hello/:name','index/hello');可以匹配下面的URL地址hello/thinkhello/think/thinkphphello/think/thinkphp/demo但如果添加了路由完全匹配后Route::get('hello/:name$','index/hello');上面的三個(gè)URL地址中就只會(huì)匹配hello/think建議你開(kāi)啟全局路由完全匹配//路由完全匹配'route_complete_match'=>true,如果有個(gè)別路由仍然希望不要完全匹配,你可以使用Route::get('hello/:name','index/hello')->completeMatch(false);關(guān)閉當(dāng)前路由規(guī)則(或者路由分組)的完整匹配。定義路由標(biāo)識(shí)路由標(biāo)識(shí)的作用只是用于URL地址生成,而且默認(rèn)會(huì)使用當(dāng)前的路由地址作為路由標(biāo)識(shí)。\hThinkPHP知識(shí)庫(kù)如果指定了路由標(biāo)識(shí)的話,url方法的用法就需要調(diào)整為:Route::get('hello/:name','index/hello')->name('hello');echourl('hello',['name'=>'think']);如果你希望簡(jiǎn)化URL地址的生成調(diào)用,可以在項(xiàng)目規(guī)范中強(qiáng)制統(tǒng)一規(guī)范,而不要使用URL地址這種默認(rèn)標(biāo)識(shí),使用路由標(biāo)識(shí)的優(yōu)勢(shì)是即使路由地址發(fā)生了變化,也無(wú)需改變url方法的代碼。??法定義路由參數(shù)出于語(yǔ)義化考慮,路由參數(shù)建議使用方法而不是參數(shù)。推薦使用(支持IDE)Route::get('new/:id','News/read')->ext('html')->https();不建議使用:Route::get('new/:id','News/read')->option(['ext'=>'html','https'=>true]);MISS路由一旦你設(shè)置了全局的MISS路由,相當(dāng)于開(kāi)啟了強(qiáng)制路由模式。Route::miss('public/miss');MISS路由可以針對(duì)不同路由分組(或者域名)設(shè)置,也可以針對(duì)不同的請(qǐng)求類型設(shè)置,Route::group('blog',function(){Route::get(':name$','blog/read');...Route::miss('blog/error','get');\hThinkPHP知識(shí)庫(kù)Route::group('user',function(){Route::get(':id','user/info');...Route::miss('user/error');});控制器規(guī)范為了避免命名沖突,可以在路由配置文件中統(tǒng)一開(kāi)啟控制器類庫(kù)后綴。'controller_suffix' =>true,優(yōu)先使用資源控制器,可以通過(guò)命令行快速生成一個(gè)資源控制器類phpthinkmake:controllerBlog控制器建議繼承一個(gè)公共的控制器類,便于統(tǒng)一調(diào)整和增加通用邏輯。默認(rèn)安裝后,系統(tǒng)提供了一個(gè)app\BaseController實(shí)例基礎(chǔ)控制器類,你可以根據(jù)自己項(xiàng)目的需求進(jìn)行調(diào)整,包括改變命名空間。對(duì)于控制器操作方法的攔截以及統(tǒng)一處理應(yīng)當(dāng)使用中間件獨(dú)立操作,原來(lái)的初始化方法已經(jīng)廢棄??刂破髦虚g件不需要繼承任何的基礎(chǔ)控制器類即可使用,僅僅需要你定義middleware屬性即可??刂破鞯拇a應(yīng)當(dāng)盡量少,以確保邏輯清晰和可讀性。并始終保持controller層作為訪問(wèn)控制器層的名稱。請(qǐng)求數(shù)據(jù)的驗(yàn)證操作統(tǒng)一使用驗(yàn)證器進(jìn)行驗(yàn)證。操作方法中的對(duì)象使用依賴注入,其它的必要參數(shù)使用參數(shù)自動(dòng)綁定。不要在操作方法中輸出除了調(diào)試信息之外的任何內(nèi)容,而是通過(guò)return返回需要輸出的內(nèi)容。操作方法中始終明確響應(yīng)輸出的類型,默認(rèn)的return方式使用的是HTML輸出類型。命名規(guī)范\hThinkPHP知識(shí)庫(kù)數(shù)據(jù)表和字段采用小寫加下劃線方式命名,例如think_user表和user_name字段,禁止使用駝峰、中文或者拼音作為數(shù)據(jù)表及字段命名。主鍵統(tǒng)一使用id;外鍵統(tǒng)一使用resource_id形式(例如user_id);模型數(shù)據(jù)字段統(tǒng)一使用小寫+下劃線命名,和數(shù)據(jù)表字段規(guī)范一致;數(shù)據(jù)表統(tǒng)一添加系統(tǒng)時(shí)間字段(create_time和update_time),并使用datetime類型;使用軟刪除并添加時(shí)間字段delete_time,類型和系統(tǒng)時(shí)間字段保持一致;模型類應(yīng)該繼承一個(gè)統(tǒng)一的公共類,便于調(diào)整和統(tǒng)一設(shè)置;模型類應(yīng)當(dāng)通過(guò)定義autoWriteTimestamp屬性明確時(shí)間字段類型;查詢規(guī)范不要在數(shù)據(jù)庫(kù)配置文件以外的地方配置或者動(dòng)態(tài)設(shè)置數(shù)據(jù)庫(kù)連接信息,包括模型內(nèi)部。盡量不使用原生SQL查詢,而應(yīng)當(dāng)使用查詢構(gòu)造器。不要使用任何數(shù)據(jù)庫(kù)工具創(chuàng)建、修改數(shù)據(jù)表和填充數(shù)據(jù),應(yīng)當(dāng)使用\h數(shù)據(jù)遷移并同步版本庫(kù)給所有成員。每次數(shù)據(jù)查詢都用Db類或者模型類的靜態(tài)方法。避免在模型方法中直接寫復(fù)雜的查詢條件,而應(yīng)當(dāng)使用查詢范圍或者搜索器統(tǒng)一定義后調(diào)用。用查詢表達(dá)式方式替代傳統(tǒng)的數(shù)組查詢。查詢數(shù)據(jù)的處理統(tǒng)一使用獲取器定義,而不要直接處理數(shù)據(jù)。對(duì)寫入數(shù)據(jù)需要額外處理的話統(tǒng)一使用修改器。對(duì)于使用了SQL函數(shù)的用法,使用fieldRaw、orderRaw和whereRaw/whereExp替代field、order和where用法。僅在使用字符串查詢條件,以及調(diào)用whereExp和whereRaw方法的時(shí)候需要使用手動(dòng)參數(shù)綁定,其余情況下都會(huì)自動(dòng)進(jìn)行參數(shù)綁定,禁止手動(dòng)調(diào)用bind方法。\hThinkPHP知識(shí)庫(kù)查詢值為Null的數(shù)據(jù)查詢值為Null的數(shù)據(jù)應(yīng)當(dāng)使用whereNull或者whereNotNull方法//查詢email為空,并且name不為空的用戶數(shù)據(jù)User::whereNull('email')->whereNotNull('name')->select();使?快捷?法對(duì)于一些常用的查詢,盡量使用系統(tǒng)封裝的快捷查詢方法,例如:User::whereIn('id',[1,2,3])->whereLike('name','think%')->select();相當(dāng)于下面的查詢User::where('id','in',[1,2,3])->where('name','like','think%')->select();更多的方法可以參考官方手冊(cè)或者使用IDE的自動(dòng)提示。獲取字段值和列數(shù)據(jù)對(duì)于一些簡(jiǎn)單的數(shù)據(jù)獲取,你完全不需要查詢整個(gè)表的數(shù)據(jù),例如查詢某個(gè)字段(滿足條件的)值或者列數(shù)據(jù)。//獲取id為10的用戶名稱User::where('id',10)->value('name');//獲取狀態(tài)為1的用戶名稱列表User::where('status',1)\hThinkPHP知識(shí)庫(kù)//獲取分?jǐn)?shù)大于80的用戶分?jǐn)?shù)列表,以用戶ID為索引User::where('score','>',80)->column('score','id');聚合查詢?nèi)绻愕膍in/max查詢的是一個(gè)字符串類型字段,記得加上第二個(gè)參數(shù)并傳入false。//獲取name字段的最大值User::max('name',false);時(shí)間區(qū)間查詢時(shí)間查詢主要用于時(shí)間字段的區(qū)間查詢,whereTime方法的優(yōu)勢(shì)是支持自動(dòng)識(shí)別時(shí)間字段類型并進(jìn)行轉(zhuǎn)換處理。//大于某個(gè)時(shí)間User::whereTime('birthday','>=','2008-10-1')->select();//小于某個(gè)時(shí)間User::whereTime('birthday','<','2000-10-1')->select();//時(shí)間區(qū)間查詢User::whereBetweenTime('birthday','1990-10-1','2000-10-1')->select();//不在某個(gè)時(shí)間區(qū)間User::whereNotBetweenTime('birthday','1970-10-1','2000-10-1')->select();年/?/?/周查詢對(duì)于年/月/日/周的時(shí)間查詢,推薦使用whereYear/whereMonth/whereDay/whereWeek方法查詢,例如://查詢本月注冊(cè)的用戶Db::name('user')->whereMonth('create_time')\hThinkPHP知識(shí)庫(kù)//查詢上月注冊(cè)用戶Db::name('user')->whereMonth('create_time','lastmonth')->select();//查詢2018年6月注冊(cè)的用戶Db::name('user')->whereMonth('create_time','2018-06')->select();//查詢當(dāng)天注冊(cè)的用戶Db::name('user')->whereDay('create_time')->select();//查詢昨天注冊(cè)的用戶Db::name('user')->whereDay('create_time','yesterday')->select();//查詢2018年6月1日注冊(cè)的用戶Db::name('user')->whereDay('create_time','2018-06-01')->select();時(shí)間表達(dá)式查詢高級(jí)的時(shí)間表達(dá)式查詢可以使用PHP的\h相對(duì)時(shí)間格式,例如://查詢兩天以內(nèi)的博客Blog::whereTime('create_time','-2days')->select();//查詢昨天中午后發(fā)的博客Blog::whereTime('create_time','yesterdaynoon')->select();更多的時(shí)間表達(dá)式查詢你可以自由發(fā)揮。時(shí)間字段范圍查詢\hThinkPHP知識(shí)庫(kù)//查詢有效期內(nèi)的活動(dòng)Event::whereBetweenTimeField('start_time','end_time')->select();//查詢沒(méi)有開(kāi)始或者已經(jīng)過(guò)期的活動(dòng)Event::whereNotBetweenTimeField('start_time','end_time')->select();字段比較可以直接比較兩個(gè)字段的大小進(jìn)行查詢User::whereColumn('update_time','>','create_time')->select();User::whereColumn('score1','>','score2')->select();如果需要比較兩個(gè)字段相同,可以使用User::whereColumn('score1','score2')->select();條件查詢應(yīng)當(dāng)使用條件查詢替代在組裝查詢條件的時(shí)候?qū)懘罅康膇f和else。User::when($condition,function($query){//滿足條件后執(zhí)行$query->where('score','>',80)->limit(10);})->select();并且支持不滿足條件的分支查詢,并且支持多次調(diào)用when方法。User::when($condition,function($query){//滿足條件后執(zhí)行\(zhòng)hThinkPHP知識(shí)庫(kù)//不滿足條件執(zhí)行$query->where('score','>',60);})->select();JSON查詢?nèi)绻愕淖侄晤愋褪褂玫氖荍SON類型,那么可以直接使用框架提供的JSON查詢支持。User::where('info->nickname','ThinkPHP')->find();注意,需要在模型里面定義JSON字段屬性。<?phpnamespaceapp\index\model;usethink\Model;classUserextendsModel{//設(shè)置json類型字段protected$json=['info'];}如果使用Db查詢的話,可以改為$user=Db::name('user')->json(['info'])->where('info->nickname','ThinkPHP')->find();SQL函數(shù)查詢?nèi)绻枰獙?duì)某個(gè)字段使用SQL函數(shù)表達(dá)式查詢,可以使用User::whereExp('nickname',"=CONCAT(name,'-',id)")->whereRaw('LEFT(nickname,5)=?',['think'])\hThinkPHP知識(shí)庫(kù)注意whereExp和whereRaw方法的區(qū)別,前者是對(duì)某個(gè)字段使用SQL函數(shù)表達(dá)式,后者是整個(gè)查詢就是一個(gè)SQL函數(shù)表達(dá)式。字段遞增/遞減可以使用://博客的閱讀數(shù)遞增1評(píng)論數(shù)遞減2Blog::where('id',10)->inc('read_count')->dec('comment_count',2)->save();新版已經(jīng)取消了延時(shí)更新功能。指定字段值排序如果你需要按照指定字段的值的順序來(lái)排序,可以使用User::where('status',1)->orderField('id',[1,2,3])->select();從主庫(kù)讀取如果你使用了數(shù)據(jù)庫(kù)的主從分離,當(dāng)剛寫入數(shù)據(jù)后,數(shù)據(jù)庫(kù)的主從同步可能還沒(méi)來(lái)得及同步,這個(gè)時(shí)候立刻查詢數(shù)據(jù)可能會(huì)出錯(cuò),你可以使用下面的方法從主庫(kù)讀取。$user=User::create($data);$user->readMaster()->select();你可以全局配置數(shù)據(jù)寫入后自動(dòng)讀取主庫(kù)\hThinkPHP知識(shí)庫(kù)獲取?增ID使用Db類的insert方法或者模型的save方法返回的不是自增主鍵,不過(guò)你可以使用。$userId=Db::name('user')->insertGetId($data);如果使用模型的話,自增主鍵的值會(huì)自動(dòng)賦值給模型對(duì)象,可以直接獲取。$user=User::create($data);echo$user->id;模型查詢?yōu)榭盏奶幚砟P筒樵償?shù)據(jù)不存在的話返回值為Null,所以必須要添加返回值判斷然后進(jìn)行數(shù)據(jù)處理,建議使用下面的方法查詢,如果數(shù)據(jù)不存在則返回空的模型對(duì)象。//始終返回模型對(duì)象$user=User::where('id',10)->findOrEmpty();?動(dòng)分批寫入如果你需要一次寫入大量數(shù)據(jù),建議使用limit方法自動(dòng)分批多次寫入。//自動(dòng)分批多次寫入數(shù)據(jù)庫(kù)每次最多寫入1000條Db::name('user')->limit(1000)->insertAll($dataList);如果是使用模型的話,建議直接使用saveAll方法而不需要limit方法。$user=newUser;$user->saveAll($dataList);\hThinkPHP知識(shí)庫(kù)對(duì)于大量數(shù)據(jù)的處理操作,建議使用chunk分批處理方法。//每次處理100個(gè)數(shù)據(jù)User::chunk(100,function($users){foreach($usersas$user){//處理數(shù)據(jù)}});游標(biāo)查詢對(duì)于內(nèi)存開(kāi)銷比較大的應(yīng)用,在做大量數(shù)據(jù)查詢和處理的時(shí)候,建議使用cursor方法進(jìn)行游標(biāo)查詢,可以利用PHP的生成器特性,減少內(nèi)存占用。$cursor=User::cursor();foreach($cursoras$user){//處理數(shù)據(jù)}關(guān)聯(lián)查詢關(guān)聯(lián)方法定義應(yīng)該始終使用小駝峰規(guī)范,但關(guān)聯(lián)查詢的時(shí)候支持駝峰或者小寫加下劃線方法,但區(qū)別在于關(guān)聯(lián)屬性的名稱不同。是否需要模型分層一般情況下,僅僅使用Model層已經(jīng)夠用,但如果項(xiàng)目比較大,建議對(duì)模型進(jìn)行分層,例如使用數(shù)據(jù)層、邏輯層和服務(wù)層等等,視項(xiàng)目需求而定,原則就是避免某一層過(guò)大導(dǎo)致結(jié)構(gòu)雜亂,盡量讓各個(gè)層分工明確,各司其職。請(qǐng)求變量過(guò)濾永遠(yuǎn)不要相信用戶的輸入,這是一句至理名言。盡可能的過(guò)濾請(qǐng)求變量能有效防范大部分的漏洞和隱患??蚣芙ㄗh的獲取請(qǐng)求變量的方法是Request類的param方法(如非必要不要再使用get或者post方法獲取,更不要使用原生的$_GET/$_POST等方法獲?。?。\hThinkPHP知識(shí)庫(kù)$name=$request->param('name');//在這里可以根據(jù)你的業(yè)務(wù)需求進(jìn)行更嚴(yán)謹(jǐn)?shù)倪^(guò)濾//例如$name=$request->param('name','','htmlentities,strtolower');//或者使用驗(yàn)證器進(jìn)行專門的驗(yàn)證}對(duì)于有明確類型的請(qǐng)求變量,可以在使用param方法的時(shí)候使用類型強(qiáng)制轉(zhuǎn)換,例如:publicfunctionindex(Request$request){//強(qiáng)制轉(zhuǎn)換字符串?dāng)?shù)據(jù)$name=$request->param('name/s');//強(qiáng)制轉(zhuǎn)換整型數(shù)據(jù)$name=$request->param('id/d');//強(qiáng)制轉(zhuǎn)換浮點(diǎn)型數(shù)據(jù)$name=$request->param('score/f');}或者直接使用方法參數(shù)獲取請(qǐng)求變量publicfunctionindex(string$name){//在這里可以根據(jù)你的業(yè)務(wù)需求進(jìn)行更嚴(yán)謹(jǐn)?shù)倪^(guò)濾//或者使用驗(yàn)證器進(jìn)行專門的驗(yàn)證}如果你需要對(duì)所有數(shù)據(jù)進(jìn)行處理,可以設(shè)置全局的過(guò)濾方法。對(duì)不同的應(yīng)用需求設(shè)置default_filter過(guò)濾規(guī)則(默認(rèn)沒(méi)有任何過(guò)濾規(guī)則),常見(jiàn)的安全過(guò)濾函數(shù)包括stripslashes、htmlentities、htmlspecialchars和strip_tags等,請(qǐng)根據(jù)業(yè)務(wù)場(chǎng)景選擇最合適的過(guò)濾方法。如果需要獲取多個(gè)數(shù)據(jù),建議使用only方法指定需要獲取的變量名稱,避免有些不懷好意的數(shù)據(jù)提交導(dǎo)致權(quán)限問(wèn)題。\hThinkPHP知識(shí)庫(kù)//指定表單數(shù)據(jù)名稱$data=$request->only(['name','title']);}當(dāng)你使用數(shù)據(jù)庫(kù)或者模型操作寫入數(shù)據(jù)的時(shí)候,也可以指定字段,避免非法和不希望的字段寫入數(shù)據(jù)庫(kù)。//模型User::a

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論