ThinkPHP學習之CURD操作(一)

來源:互聯網
上載者:User

寫在前面

這周開始學習ThinkPHP,將學習的日記記錄下來。不僅僅學習怎麼用TP,也要從源碼上來學習TP架構。

日記每天都寫,但不一定都放到網上。希望自己能夠堅持下去。

閑話少說,既然是閱讀源碼,關於TP的建立,配置等一系列操作就不去說了,官方文檔有佷詳細的介紹。

要同學想要學習TP的可以點擊 ThinkPHP3.2.3快速入門 學習,大家一起進步。

CURD操作

什麼是CURD操作?實際上是對資料庫增刪改查的簡稱。包括了create、update、read、delete四個基本操作。在TP中對CURD操作的實現是add,save,select,update。

開啟Think/Library/Model.class.php,可以在其中找到這四個操作。接下來就開始來查看源碼,知道啟動並執行流程,才能夠更好的運用這四個操作。

CUED操作之add方法

add方法用於資料添加,是TP對create操作的實現。注意一點的是,TPModel中也有create方法,但並不是CURD操作的一種,而是對即將插入資料庫的資料的處理方法。

參數分析

add方法有三個參數(不必須傳遞),如下

$data 預設值'' 需要進行插入資料庫的資料$option 預設值array() 運算式參數 其中儲存著 所有進行過的連貫操作$replace 預設值false 是否在插入資料庫時進行replace操作

傳回值可能是bool(false)或資料庫受影響的行數或主索引值。從傳回值看出該操作是必須位於連貫操作的末尾,可以看成一連套組合技中的終結技。

流程分析

我對add方法的執行流程分成了四步

  • 首先,檢測資料是否為空白
  • 其次,進行資料處理與運算式分析
  • 以上都通過 進行資料插入 返回插入結果
  • 對返回的結果進行分析

步驟一假設進行使用者註冊操作,插入資料表User,使用add方法進行操作。user欄位為:

主鍵 user_id暱稱 user_name密碼 password郵箱 email

前台POST資料:

array(    'user_name'     => 'xiamsahfw',    'password'      => 'adhe99211' ,    'confrim'       => 'adhe99211' ,    'email'         => '221131@qq.com',    'hid'           => 'register'              );

在UserController類中的操作:

$data = I('post.');$User = M('User');$User->create($data);$User->add();

在add操作中,並沒有給add傳遞任何參數,但在$User->create($data)中傳遞了該值,在該操作中就會自動將資料添加到Model中的$this->data中,而add會自動引用該值。

同時create方法會將自動將傳遞的參數與資料表的欄位進行對比,將不屬於表中的欄位刪除。

步驟二之後,add方法就會調用_facade方法對$data進行資料處理,其實在這裡是二次處理$data資料,因為在create方法以及對資料進行過處理。如果在UserController中並沒有調用create方法,而是直接傳遞$data到add方法,那麼_facade就會把'confrim' => 'adhe99211' ,'hid' => 'register'刪除,變成:

array(     'user_name'     => 'xiamsahfw',     'password'      => 'adhe99211' ,     'email'         => '221131@qq.com'                );

為了可能的連貫操作,add會調用_parseOptions進行運算式分析。在運算式分析後即使沒進行任何連貫操作,在返回的值也存在兩個元素:

Array ([table] => user[model] => User)

table表示操作的資料表,model表示操作的模型名。

如果之前存在連貫操作,如where,group by等也會在該項顯示。此外,傳遞連貫操作到add方法,也會和已經存在的操作進行合并。

步驟三以上其實都是資料插入的準備工作,準備工作完成就能夠進行資料插入了。當然資料插入不屬於Model的功能,在TP中需要調用Think\Driver.class.php中的insert方法。

insert方法接受三個參數

$data$option$replace

前兩個參數是處理過的資料以及組合後的連貫動作表達式,第三個參數表示在插入資料庫時,是否進行replace操作,預設為false。在這個方法中會將傳遞的資料與連貫動作表達式進行組合,形成正式的sql語句,並執行sql語句。最後返回執行結果。

步驟四雖然得到了返回結果,add並不是直接將結果返回,而是返回分析後的結論。insert返回的結果,可能有:

失敗 => false成功 => 返回受影響的行數

但是實際進行中,我們可能會不僅想要得到一個插入成功的結論,而是想要得到插入後的主索引值。在add方法中會對返回結果進行判斷,從而返回受影響的行數(多條資料插入)或主索引值(一條資料)或false。

題外話:在進行資料插入之前我注意到有這麼一行代碼。

if(false === $this->_before_insert($data,$options)) {    return false;}

這裡TP沒有做任何注釋,尋找之後,發現是一個空方法,解釋為 插入資料前的回調方法

// 插入資料前的回調方法protected function _before_insert(&$data,$options) {}

將這個方法列印出來,結果為NULL

var_dump($this->_before_insert($data,$options));  // NULL

百度一下也沒找到想要的答案,我對TP的官方文檔並沒有看完,可能官方會有用法的介紹。這裡很糾結,我猜測是在子類繼承時,可以實現這個方法進行某些特殊操作(很大可能)。與之相同的還有_after_insert方法。

總結

寫了一大串,也不知道寫的是不是很清晰,但是我的確是對這個方法熟悉了很多。這個方法雖然可以不傳遞參數,但如果之前沒進行create還是會出錯的,雖然內部整合了資料處理,但不是很完善,比如對資料沒能進行轉義,也不能夠對資料欄位進行驗證,需要我們自己進行調用其它方法等等。知道了add的運行原理,自然能夠很好的運用它,同時對自己封裝模型類時也有了很大啟發。

今天就寫到這兒,下一篇準備寫CURD中的read,也就是TP中的select。

博主大三狗,正在努力學習中,文中有錯漏之處難免,歡迎指正,歡迎批評。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.