<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                # 間接讀取數據 直接讀取數據雖然簡單易懂,但往往在大型的項目中卻并不適用。如果實現一個功能,我們把所有的代碼都寫在一個方法中,顯然當功能復雜時,代碼就會越來越長,越來越難以維護。這顯然不是我們想看到的。 基于此,我們有了數據庫M層,一個專門為我們處理數據表的文件。 ## M 數據模型層 沒有M層以前我們取數的過程是這樣的。 ![](https://box.kancloud.cn/2016-06-13_575e5bec70780.png) 有了M層以后,我們取數的過程變成了這樣。 ![](https://box.kancloud.cn/2016-06-13_575e5bec83b8d.png) 是的,你想的沒錯,在小型的項目,或是我們這個教程中,這樣做的確是畫蛇添足了。但是我們的目標,并不僅僅滿足于做小項目。后面你將會一點點的感受到分層的魅力。 ## 調用誰,你就要USE誰 我們再看前面寫過的代碼: ![](https://box.kancloud.cn/2016-06-13_575e5bec95ec4.png) 如果刪除或注釋掉第3行。 就會報如下錯誤: ![](https://box.kancloud.cn/2016-06-13_575e5becb7ceb.png) 報錯信息中提示這個類 'app\index\controller\DB' 沒有找到。 原因就是我們在用Db類以前,沒有告訴程序這個正確的Db類在哪個位置,怎么告訴呢?利用的就是USE。 那我們說,你怎么就知道要這么use呢? 我們先看一下,Db這個類到底在哪。 ![](https://box.kancloud.cn/cfa27f6809b7dd160a110dddfc174837_254x650.png) 其實它在哪并不要緊,PHP中有一個叫命名空間的東西,至于怎么工作的,有興趣的GOOGLE吧。我們只需要知道它叫命名空間就可以了。如下圖所示: ![](https://box.kancloud.cn/2016-06-13_575e5bed00748.png) 命名空間,可以簡單的理解為:我住哪兒。 我們看到Db這個類,它住在了`think`中,它的名字叫`Db`,所以別人想找它幫忙的時候,只需要`use think\Db;`就可以了。 當然了,我們自己寫的類,由于也有命名空間,別人也可以通過我們的類住在哪兒,叫什么名字,來use我們的文件。 其實想搞清楚命名空間這個神奇的東西并不容易,所以搞不太清楚沒有關系,我們現在只需要知道 **調用誰,就USE誰** ,就可以了。慢慢的,我們會一點點的明白什么是命名空間。 ### 調用M層,我們就要USE M層 #### 建立M層文件 上面我們是使用了Db這個類,這次我們放棄Db類。在實際的開發過程中,大多數的數據表都是固定的(有些項目需要動態生成數據表),所以我們也很少會去用這個Db類。基于此,我們對Db類的了解,到此為止。 這次我們引用think內置的一個類think\Model,這個類中封裝好了所有的數據庫操作方法。我們將采用繼承的方法,如果現在不太清楚什么是繼承,可以直接往下看,但我們有必要去學一學C++了。 代碼如下: ~~~ <?php // 簡單的原理重復記: namespace說明了該文件位于application\common\model 文件夾中 namespace app\common\model; use think\Model; // 導入think\Model類 /** * Teacher 教師表 */ // 我的類名叫做Teacher,對應的文件名為Teacher.php,該類繼承了Model類,Model我們在文件頭中,提前使用use進行了導入。 class Teacher extends Model { } ~~~ 我們再來鞏固一下namespace,這個叫做命名空間的東西。 app\common\model; 是指這個文件位于application文件夾下的common文件夾下的model文件夾中。 所以當我們看到以app打頭的命名空間時,也就相當于告訴了我們這個文件位于哪個位置。 類名必然與文件名相同。比如Teacher類,必須對應Teacher.php文件。 所以根據以上的代碼,我們應該能夠快速的定位到該代碼應該處于: `application\common\model\Teacher.php`文件中。 查看**application**目錄樹 ~~~ ├── command.php ├── common │?? └── model │?? └── Teacher.php ├── common.php ├── config.php ├── database.php ├── index │?? └── controller │?? ├── Index.php │?? └── Teacher.php ├── route.php └── tags.php ~~~ 最后我們是通過 extends 來繼承的,因此,不僅僅我們在調用這個類之前需要進行use,我們在繼承一個類之前也需要use。 #### 調用Teacher.php 模型文件 我們先回到C層,即controller文件夾下,對原Teahcer.php進行重新編輯,去除對Db類的調用。 > 我們需要記往一點,只有controller文件夾下的文件,才可以通過URL訪問的到。其它的文件,比如我們剛剛新建的這個M層的Teacher.php,是直接訪問不到的。 刪除冗余的代碼后如下: ~~~ <?php namespace app\index\controller; // 該文件的位于application\index\controller文件夾 /** * 教師管理 */ class Teacher { public function index() { echo 'hello teacher'; } } ~~~ 輸入URL進行測試結果顯示如下: ![](https://box.kancloud.cn/2016-06-13_575e5bed4c317.png) 下面,我們正式調用Teacher模型。 1、先use (導入) 2、再調用 示例代碼如下: ~~~ <?php namespace app\index\controller; // 該文件的位于application\index\controller文件夾 use app\common\model\Teacher; // 教師模型 /** * 教師管理 */ class Teacher { public function index() { $Teacher = new Teacher; dump($Teacher); } } ~~~ 經測試,我們將得到如下錯誤提示: ![](https://box.kancloud.cn/2016-06-13_575e5bed5fa87.png) ~~~ git checkout -f step3.2.4.1 ~~~ 執行上述命令后,上述示例代碼信息如下: ![](https://box.kancloud.cn/cd2587c989c11dcde5a2c738d5391514_653x307.png) 提示:不能重新聲明`app\index\controller\Teacher`這個類,原因是由于這個類已經存在。 > 每個班級里面只能有一個小明,如果存在兩個小明,那么他們肯定有一個是**大小明**,另一個是**小小明**。 在日常使用電腦時,也是如此。當我們嘗試在同一個文件夾中建立兩個同名文件(包含擴展名)時,就會報錯。 有人說,老師我們并沒有在同一個文件夾中建立`Teacher`呀,按上面的理論,應該不報錯才對。這里,就要說下use這條語句了,當它執行`use app\common\model\Teacher;`時,我們可以簡單理解為:將`application\common\model`文件夾下的`Teacher.php`文件中定義的`Teacher`類導入到當前文件。 此時,由于導入的類名叫做Teacher,然后我們自己的名字也叫做Teacher,就出現了名字發生沖突的錯誤。 所以簡單來說:上述出現錯誤的原因,是由于這兩個類起的名字是相同的。 ![](https://box.kancloud.cn/4eb08b4e6a8ba95f3543d6491935999f_436x352.png) #### 解決方法1 為導入的那個Teacher 改個名字 ~~~ <?php namespace app\index\controller; // 該文件的位于application\index\controller文件夾 // 導入app\common\model\Teacher模型,并給它重新起個名字:SmallTeacher use app\common\model\Teacher as SmallTeacher; // 教師模型 帶有別名 /** * 教師管理 */ class Teacher { public function index() { $SmallTeacher = new SmallTeacher; dump($SmallTeacher); } } ~~~ ~~~ git checkout -f step3.2.4.2 ~~~ 執行上述命令后,上述示例代碼信息如下: ![](https://box.kancloud.cn/2016-06-29_577343c45a825.png) #### 解決方法2,更改thinkphp的命名規則,不給他們發生沖突的機會。 1、修改config.php 在config.php 找到 controller_suffix 項,并配置為 true: ~~~ // 控制器類后綴 'controller_suffix' => true, ~~~ config.php 位置application根目錄下。 > 細心的你可能早就發現了一個問題:為什么這個文件就沒有命名空間呢? 是的,它沒有,但是我們也沒有看到里面有Class的字樣呀,既然它不是一個Class(類),沒有命名空間就是正常的。 2、修改原來C層的文件名 Teacher.php -> TeacherController.php 當然了,同為控制器的Index.php,也要修改成IndexController.php。由于類名與文件名相同,所以類名當然也要修改了。 修改后如圖所示: ![](https://box.kancloud.cn/d0dd7825d4501386228b71a5176a97cf_1086x329.png) 這時候,C層的類名字叫做TeacherController,M層的叫做Teacher,兩個名字不一樣了,當然也就不需要使用別名了。 刷新URL進行測試: 如果你見到如下錯誤: ***控制器不存在:Teacher*** 產生的原因有以下兩種: 1. 我們config.php中的配置信息沒有起作用,請檢查拼寫是否有錯誤,文件是否進行正常保存等。 2. 文件名或類名命名不正確。 > 我們在以后的學習中,還會遇到上述錯誤提示,查找問題原因的方向為:1. 命名空間 2. 文件位置 3. 文件名 4. 類名 。 需要重點檢查的項如下圖所示: ![](https://box.kancloud.cn/e71d9f52244643929c70b269f7ab49dd_1090x329.png) 上圖中的錯誤,你發現了嗎? 由于此次我們并沒有變動文件的位置,所以命名空間可以確定是沒有問題的。那么,如果有問題就應該出現在文件名和類名上了。 #### 正確的測試結果如下圖所示: ![](https://box.kancloud.cn/4fb88c6eef32448ab2e4acd73f147f38_666x395.png) 我們看到,第一行提示說在debug文件的169行。顯然,我們更希望看到的是在TeacherController文件的第12行,這是由于我們使用了thinkphp內置的dump()方法造成的。在以后的教程中,如果我們在其它的歷史項目中看到這個函數,知道它等于var_dump()就可以了。 > 在以后的項目或是教程中,我們將棄用dump()函數,一律改為var_dump()。 最后,我們去除原來的別名。 代碼如下: ~~~ <?php namespace app\index\controller; // 該文件的位于application\index\controller文件夾 use app\common\model\Teacher; // 教師模型 /** * 教師管理 */ class TeacherController { public function index() { $Teacher = new Teacher; var_dump($Teacher); } } ~~~ 測試結果: ![](https://box.kancloud.cn/b96fdad49533afeedcf9e4d018e31695_684x389.png) 使用`var_dump()`提示我們,現在發生的位置位于`TeacherController`的第12行。 同時我們還看到`$Teacher`變量的類型是一個`object`,這個對象的原型是`app\common\model\Teacher`。沒錯,的確是我們引入的那個`app\common\model\Teacher`。 ~~~ git checkout -f step3.2.4.3 ~~~ 執行上述命令后,上述示例代碼信息如下: ![](https://box.kancloud.cn/ec2dbb06785e65c966cefacd47df4d6b_1079x297.png) ## 主角登場 使用select()來獲取數據庫中的信息。 ~~~ <?php namespace app\index\controller; // 該文件位于application\index\controller文件夾 use app\common\model\Teacher; // 教師模型 /** * 教師管理 */ class TeacherController { public function index() { $Teacher = new Teacher; $teachers = $Teacher->select(); var_dump($teachers); } } ~~~ 測試結果: ![](https://box.kancloud.cn/9ef0204be7b536a78a71d0d245e2af9a_553x144.png) ~~~ git checkout -f step3.2.4.4 ~~~ 執行上述命令后,上述示例代碼信息如下: ![](https://box.kancloud.cn/eba80b6b4b6d342918bb8e0a4480c731_1112x329.png) 我們看到返回值是個數組,這個數組的第0項是一個對象,第1項也是個對象,這兩個對象都是基于`app\common\model\Teacher`這個類創建的。 我們并沒在`app\common\model\Teacher`中定義任何屬性,那么這些保護類型的私有屬性是怎么來的呢?這是由于它繼承了一個叫做`think\Model`的類。繼承就是這樣:你自己雖然沒有,但是你父類有就和你有是一樣的。在繼承中是這樣規定的,在父類中所有的protected和public的變量或**方法**,都是可以被子類直接使用。 變量我們看到了,那么我們還可以在這個對象上調用哪些方法呢? > `var_dump()` 函數可以查看對象中的屬性,但卻不顯示對象中存在的方法。 我們現在就查看一下`think\Model`(think開頭的類,位于thinkphp5/thinkphp/library/think文件夾下)中都有什么方法,然后調用一個試試。 ![](https://box.kancloud.cn/c8f967270b9c0029dc49612fc1f4882c_1203x669.png) 我們在Model.php文件中,同時按下 `Ctrl+P`,然后輸入`@getData`,找到獲取對象原始數據getData()方法,如下圖所示。 ![](https://box.kancloud.cn/af8c5bc6a0a33b42910601c4fb135599_633x469.png) getData()方法代碼如下: ~~~ /** * 獲取對象原始數據 如果不存在指定字段返回false * @access public * @param string $name 字段名 留空獲取全部 * @return mixed * @throws InvalidArgumentException */ public function getData($name = null) { if (is_null($name)) { return $this->data; } elseif (array_key_exists($name, $this->data)) { return $this->data[$name]; } else { throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name); } } ~~~ 在此,不得不說:**越是技術牛氣的人,代碼越是規范!** 想成為技術大牛嗎?從規范代碼做起! 修改C層代碼: ~~~ <?php namespace app\index\controller; use app\common\model\Teacher; // 教師模型 /** * 教師管理 */ class TeacherController { public function index() { $Teacher = new Teacher; $teachers = $Teacher->select(); // 獲取第0個數據 $teacher = $teachers[0]; // 調用上述對象的getData()方法 var_dump($teacher->getData()); } } ~~~ 測試結果如下: ![](https://box.kancloud.cn/9a4a511f4e62844fcece2323e72c7ae5_573x240.png) 為getData()傳參: ~~~ // 調用上述對象的getData()方法 var_dump($teacher->getData('name')); ~~~ 再測試,結果顯示如下: ![](https://box.kancloud.cn/3206fcd698b5987da23ee63380151b38_758x75.png) 增加另外兩個直接顯示數據的方式: ~~~ // 調用上述對象的getData()方法 var_dump($teacher->getData('name')); echo $teacher->getData('name'); return $teacher->getData('name'); ~~~ 測試結果如下: ![](https://box.kancloud.cn/4304e1df387836bd7247a12c7575ff96_755x107.png) #### thinkphp 模型與數據表的自動關聯 細心的你,發現我們并沒有指定要去查哪個表,系統自動的就將Teacher表中的數據返回給了我們。 > 這是由于當我們新建的 app\common\model\Teacher,繼承了think\Model, 在think\Model中,有個功能是自動關聯數據表。也就是說,我們起的類名叫做Teacher,它就自動關聯yunzhi_teacher這個表。為什么前面會自動加上yunzhi_ ? 再去找一下database.php吧。 是的,就這么神奇,數據表中的數據就這么過來了。 用Db類的select()方法和我們此處的 select() 方法,獲取到的雖然都是一個數組,但一個是數組中的子項還是數組,而另一個是數組中的子項卻是對象了。由于我們并不打算使用Db類,所以在此不對這兩者的區別做過多的闡述。我們只需要知道,我們是面向對象的編程思路,即:**一切皆對象** 就可以了。 ### 重構代碼 重新去寫自己的代碼就叫做重構,所以我們這里也叫重構,但我們重構的目的是越重構越清晰,而在這里重構的目的是希望大家對代碼有了更加深入的理解。 重構后代碼如下: ~~~ <?php namespace app\index\controller; use app\common\model\Teacher; // 教師模型 /** * 教師管理 */ class TeacherController { public function index() { $JiaoShiBiao = new Teacher; $SuoYouJiaoShi = $JiaoShiBiao->select(); // 獲取第0個數據 $jiaoShiZhangSan = $SuoYouJiaoShi[0]; // 調用上述對象的getData()方法 echo '教師姓名' . $jiaoShiZhangSan->getData('name') . '<br />'; return '重復一遍:教師姓名' . $jiaoShiZhangSan->getData('name'); } } ~~~ 測試結果如下: ![](https://box.kancloud.cn/fe4be06cf9c9a7eac2ca5143c038e891_346x101.png) 也就是說$xxxx中的xxxx是變量名,這個名字你隨便起,只要前后一致就可以。這些是由我們規定好的,它們在我們代碼中第一次出現的位置是表達式的最左側,所以我們想起什么名字,就起什么名字。 比如下圖中這三項,第一次出現的位置是等號的左邊,說明他們是我們定義的,我們當然有自主權了,起什么名字我們說了算。 ![](https://box.kancloud.cn/2016-06-13_575e5bef7f8d0.png) 但第一次出現的位置是等號的右邊的話,那就不一樣了。 這個是其他人規定好的,它怎么規定的,我們就需要怎么使用。 最簡單的,比如: ~~~ $JiaoShiBiao = new Teacher; ~~~ Teacher這個名字,是我們在use的時候規定好的,在我們的代碼中出現在了等號右邊,那么我們就必須按規則執行。 比如: ![](https://box.kancloud.cn/2016-06-13_575e5befa4317.png) 為了提升代碼的可讀性,我們必須統一代碼書寫的規范。 我們規定大家必須這樣寫: ~~~ <?php namespace app\index\controller; // 該文件的位于application\index\controller文件夾 use app\common\model\Teacher; // 教師模型 /** * 教師管理 */ class TeacherController { public function index() { // $Teacher 首寫字母大寫,說明它是一個對象,更確切一些說明這是基于Teacher這個模型被我們手工實例化得到的,如果存在teacher數據表,它將對應teacher數據表。 $Teacher = new Teacher; // $teachers 以s結尾,表示它是一個數組,數據中的每一項都是一個對象,這個對象基于Teahcer這個模型。 $teachers = $Teacher->select(); // 獲取第0個數據 $teacher = $teachers[0]; // 調用上述對象的getData()方法 var_dump($teacher->getData('name')); echo $teacher->getData('name'); return $teacher->getData('name'); } } ~~~ 測試結果如下: ![](https://box.kancloud.cn/bd0214b8fc84f6bb1a8252116a534808_755x107.png) ~~~ git checkout -f step3.2.4.5 ~~~ 執行上述命令后,上述示例代碼信息如下: ![](https://box.kancloud.cn/0de925eba2a32d4fe7edba5035d6eca2_1240x556.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看