<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                #1.此框架架構模式遵循的是mvc思想 - M:model模型 - V:view視圖 - C:controller控制器 #2.mvc目錄結構創建 - 創建項目目錄php_mvc ```cpp |-core 框架核心目錄 | |-App.class.php URL重寫類 | |-Controller.class.php 所有控制器的基類 | |-MyException.class.php 用戶自定義的錯誤異常類 | |-Model.class.php 數據庫操作類 業務邏輯層 |-config 配置 | |-constants.php 項目常量文件 |-app 前臺 | |-public 前臺公共文件(js、css) | |-controllers 存放所有的控制器目錄 | |-Home.class.php | |-Test.class.php | |-models 存放所有的model類 | |-views 存放所有的頁面 | | |-index index目錄 | | | |-index.php 前臺首頁頁面 | | |-error 錯誤目錄 | | | |-error.php 錯誤頁面 |-web 后臺 | |-public 后臺公共文件(js、css) | |-controllers 存放所有的控制器目錄 | |-Home.class.php 后臺首頁控制器 | |-models 存放所有的model類 | |-views 存放所有的頁面 | |-index.php 項目后臺入口文件,單一入口 | |-.htaccess 后臺分布式配置文件 |-index.php 項目前臺入口文件,單一入口 |-.htaccess 分布式配置文件 ``` #3.單一入口 一般來說,在大部分項目中都是采用單一入口的方式,符合php的規范。 所謂單一入口就是在整個項目運行的過程中,需要加載的類和方法或者模板都是通過index.php來加載的。 這樣做的主要原因是為了安全。此外單一入口不代表只有一個入口,最外層的index.php是我們前臺的入口文件。web目錄下的index.php是我們后臺的入口文件。 #4.URL路由之pathinfo路由 我們常見pathinfo地址如下: ```cpp localhost/php_mvc/index.php?controller=home&method=index ``` 這個路由地址,是運行前臺的index.php入口,并且傳遞了兩個參數controller和method controller表示執行哪個控制器,method表示執行哪個方法。上面這條url就是要執行home控制器的index方法。 我們現在就要實現在前臺index.php接受這兩個參數,當沒有這兩個參數時,默認執行home控制器中的index方法。然后引入相應的類,加載指定控制器中的指定方法,實例化控制器類,調用控制器中的方法。 ```cpp |-index.php 項目前臺入口文件,單一入口 <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/24 * Time: 下午5:15 */ echo "<meta charset='utf-8'>"; require_once 'app/controllers/Home.class.php'; require_once 'app/controllers/Test.class.php'; //接受兩個參數 controller控制器名稱 method控制器中的方法 $controller = isset($_GET['controller']) ? $_GET['controller'] : 'home'; $method = isset($_GET['method']) ? $_GET['method'] : 'index'; //加載指定控制器中的制定方法 //實例化控制器類 $c = new $controller; //調用控制器中的方法 $c->$method(); ``` ```cpp |-app 前臺 | |-controllers 存放所有的控制器目錄 | |-Home.class.php <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/24 * Time: 下午5:44 */ class Home { public function index(){ echo "這里是home控制器里的index方"; } } ``` ```cpp |-app 前臺 | |-controllers 存放所有的控制器目錄 | |-Test.class.php <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/24 * Time: 下午5:44 */ class Test { public function index(){ echo "這里是test控制器的index方法"; } } ``` 下面的前兩個url在瀏覽器中應該是一樣的結果 ```cpp localhost/php_mvc/index.php localhost/php_mvc/index.php?controller=home&method=index localhost/php_mvc/index.php?controller=test&method=index ``` #5.隱藏index.php 我們開始對url進行重寫,首先為了先把index.php給隱藏,創建分布式配置文件 ```cpp |-.htaccess 分布式配置文件 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FIELNAME} !-d RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] ``` 然后在你的httpd.conf文件中把下列配置項開啟,也就是前面的#號刪掉 ```cpp #LoadModule rewrite_module modules/mod_rewrite.so ``` 這樣我們就把url進行了重寫,我們可以進行測試,修改文件 ```cpp |-index.php 項目前臺入口文件,單一入口 <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/24 * Time: 下午5:15 */ echo $_GET['url']; ``` 然后在瀏覽器中輸入 ```cpp http://localhost/php_mvc/test/index/id/13 ``` 如果這時在瀏覽器中顯示如下,則表示成功 ```cpp test/index/id/13 ``` 也就是把index.php后面的內容全部都輸出出來了。 #6.URL路由之重寫URL路由 剛才已經成功獲取到了url,然后我們要對url進行解析,我們建立一個新的類文件來處理,這個類文件要實現的功能是:得到控制器的名稱、得到方法名、其他參數并保存。組裝得到控制器的路徑,判斷控制器文件是否存在,存在則實例化,然后判斷方式是否存在,存在則執行方法,如果控制器文件或者方法不存在則執行相應地異常報錯。 ```cpp |-core | |-App.class.php URL重寫類 <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/25 * Time: 上午10:53 */ class App { protected static $controller = 'Home';//控制器名 protected static $method = 'index';//方法名 protected static $pams = array();//其他參數 /** * url重寫路由的url地址解析方法 */ protected static function paseUrl(){ if(isset($_GET['url'])){ $url = explode('/',$_GET['url']); //得到控制器 if(isset($url[0])){ self::$controller = $url[0]; unset($url[0]); } //得到方法名 if(isset($url[1])){ self::$method = $url[1]; unset($url[1]); } //判斷是否有其他參數 if(isset($url)){ self::$pams = array_values($url); } } } /** * 項目的入口方法 * @throws Exception */ public static function run(){ self::paseUrl(); //得到控制器的路徑 $url = 'app/controllers/'.self::$controller.'.class.php'; //判斷控制器文件是否存在 if(file_exists($url)){ $c = new self::$controller; }else{ throw new Exception('控制器不存在'); } //執行方法 if(method_exists($c,self::$method)){ $m = self::$method; $c->$m(); }else{ throw new Exception('方法不存在'); } } } ``` 在入口文件這里,我們要在執行run方法,并捕獲異常情況,如有異常則輸出 ```cpp |-index.php 項目前臺入口文件,單一入口 <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/24 * Time: 下午5:15 */ echo "<meta charset='utf-8'>"; require_once 'core/App.class.php'; require_once 'app/controllers/Test.class.php'; require_once 'app/controllers/Home.class.php'; try{ App::run(); throw new Exception(); }catch(Exception $e){ echo $e->getMessage(); } ``` 此時我們在瀏覽器中輸入 ```cpp http://localhost/php_mvc/home/index/id/13 ``` 那么在瀏覽器中展示如下,表示成功 ```cpp 這里是home控制器里的index方法 ``` 如果我們在瀏覽器中輸入一個不存在的控制器,比如 ```cpp http://localhost/php_mvc/article/index/id/13 ``` 那么在瀏覽器將中展示出異常信息 ```cpp 控制器不存在 ``` #7.自動加載類文件 在一個正常的項目中,會用到很多的類文件,我們就要寫很多航require的語句,這樣會讓代碼的冗余度加大,所以為了處理這個情況,php中有一個方法是自動加載類函數,自動加載方法。所以我們需要一個方法去實現加載指定的類文件。具體目標有 - 明確指明改項目中所有類存放目錄地址,這里就是控制器controllers,模型model,核心core這三個地方 - 判斷類文件在哪個目錄中,在找到后require過來,如果都不存在那么異常報錯 - 為什么不用__autoload方法來加載類文件,如果項目中前后臺都有autoload方法,可能會產生重定義錯誤。所以我們直接自己定義自動加載類的方法,然后在入口文件處通過spl_autoload_register將我們的類文件進行加載。 ```cpp |-core 框架核心目錄 | |-App.class.php URL重寫類 <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/25 * Time: 上午10:53 */ class App { /** * 自動加載類方法 * @param $className * @throws Exception */ public static function myAutoloader($className){ //控制器類文件目錄 $controller = 'app/controllers/'.$className.'.class.php'; //模型類文件目錄 $model = 'app/models/'.$className.'.class.php'; //核心類文件目錄 $core = 'core/'.$className.'.class.php'; if(file_exists($controller)){ require_once $controller; }else if(file_exists($model)){ require_once $model; }else if(file_exists($core)){ require_once $core; }else{ throw new Exception('類文件不存在'); } } } ``` ```cpp |-index.php 項目前臺入口文件,單一入口 <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/24 * Time: 下午5:15 */ echo "<meta charset='utf-8'>"; require_once 'core/App.class.php'; //注冊一個 spl_autoload_register(array('App','myAutoloader')); try{ App::run(); throw new Exception(); }catch(Exception $e){ echo $e->getMessage(); } ``` 此時我們在瀏覽器中輸入 ```cpp http://localhost/php_mvc/home/index ``` 如果展示如下,則表示自動加載類已經成功 ```cpp 這里是home控制器里的index方法 ``` 特別注意,創建類的時候,類的名稱和文件的名稱要是一致的。 #8.解析URL參數 在剛才的app.class.php類parseurl方法中,我們已經獲取到了url的參數,我們繼續在run方法中對這個參數進行判斷,是否存在多余的參數,如果有參數,那么我們要傳遞參數,否則就不傳遞參數。 對于要傳遞的參數,我們要判斷有幾個參數,鍵值是否合法。 是否大于0,是否是偶數,for循環,不滿足的都報錯“非法參數” ```cpp |-core 框架核心目錄 | |-App.class.php URL重寫類 /** * 項目的入口方法 * @throws Exception */ public static function run(){ self::paseUrl(); //得到控制器的路徑 $url = 'app/controllers/'.self::$controller.'.class.php'; //判斷控制器文件是否存在 if(file_exists($url)){ $c = new self::$controller; }else{ throw new Exception('控制器不存在'); } //執行方法 if(method_exists($c,self::$method)){ $m = self::$method; $new_pams = array(); $num = count(self::$pams); //傳遞參數,判斷是否有參數 if($num > 0){ //判斷傳遞的參數的數量是否是2的倍數 if($num % 2 == 0){ //將參數進行處理 for($i=0;$i<$num;$i+=2){ $new_pams[self::$pams[$i]] = self::$pams[$i+1]; } }else{ throw new Exception('非法參數!'); } } $c->$m($new_pams); }else{ throw new Exception('方法不存在'); } } ``` ```cpp |-app 前臺 | |-controllers 存放所有的控制器目錄 | |-Home.class.php <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/24 * Time: 下午5:44 */ class Home { public function index($data = array()){ echo "這里是home控制器里的index方法"; echo "<pre>"; print_r($data); } } ``` 此時我們就已經將多余的參數都傳遞到指定的控制器的方法中了。在瀏覽器中輸入 ```cpp http://localhost/php_mvc/home/index/cityname/shanghai/id/7 ``` 如果瀏覽器中顯示如下,則表示成功 ```cpp 這里是home控制器里的index方法 Array ( [cityname] => shanghai [id] => 7 ) ``` #9.創建控制器基類 控制器基類要實現的功能就是,實現加載相應的頁面的方法并且傳遞數據到頁面中。 為什么要創建控制器基類呢,在mvc中,工作原理是,網站首頁->Home控制器->index方法->查詢需要的所有數據->將數據發送到(view層)->展示給用戶 我們新建一個controller基類,實現加載相應頁面的方法,首先判斷頁面是否存在,如果存在那么則引入。并且傳遞數據到相應的頁面中。 ```cpp |-core 框架核心目錄 | |-Controller.class.php 所有控制器的基類 <?php /** * 所有控制器的基類 * User: find35.com * Date: 15/12/26 * Time: 上午9:53 */ class Controller { /** * 加載指定的模板頁面 * @param $page * @param array $data */ public function show($page,$data=array()){ $url = "app/views/".$page.".php"; //判斷頁面是否存在 if(file_exists($url)){ require_once $url; } } } ``` 之后讓所有其他的類,繼承此基類。調用show方法來加載view層。 ```cpp |-app 前臺 | |-controllers 存放所有的控制器目錄 | |-Home.class.php <?php /** * 前臺首頁控制器 * User: find35.com * Date: 15/12/24 * Time: 下午5:44 */ class Home extends Controller { public function index($data = array()){ //加載首頁頁面 $this->show('index/index',$data); } } ``` 我們新建一個view層的模板文件,在隨便里面寫點東西 ```cpp |-app 前臺 | |-views 存放所有的頁面 | | | |-index.php 前臺首頁頁面 <?php /** * 前臺首頁頁面 * User: find35.com * Date: 15/12/26 * Time: 下午1:09 */ echo "前臺首頁"; echo '<pre>'; print_r($data); echo '</pre>'; ``` 此時在瀏覽器中輸入 ```cpp http://localhost/php_mvc/home/index/cityname/shanghai/id/7 ``` 顯示如下,則表示成功 ```cpp 前臺首頁Array ( [cityname] => shanghai [id] => 7 ) ``` #10.mvc工作流 mvc中是通過控制器,調用里面具體的方法,來實現我們要加載哪些的模板。這些都是在控制器里進行的,并且我們可以對數據庫進行操作。 #11.錯誤處理 在項目中,當報錯時,會加載相應的錯誤頁面。當我們throw一個異常的時候,將自定義的錯誤頁面進行加載。 首頁創建一個自定義的錯誤異常的模板 ```cpp |-app 前臺 | |-views 存放所有的頁面 | | |-error 錯誤目錄 | | | |-error.php 錯誤頁面 <?php /** * 錯誤頁面 * User: find35.com * Date: 15/12/26 * Time: 下午7:46 */ echo "<h2>這里是自定義的異常報錯模板:".$msg."<h2>"; ``` 然后我們開始創建一個自定義的錯誤類 ```cpp |-core 框架核心目錄 | |-MyException.class.php 用戶自定義的錯誤異常類 <?php /** * 用戶自定義的錯誤異常類 * User: find35.com * Date: 15/12/26 * Time: 下午7:48 */ class MyException extends Exception { /** * 錯誤頁面加載 * @param $msg */ public function showError($msg){ $err_dir = 'app/views/error/error.php'; //判斷錯誤頁面是否存在 if(file_exists($err_dir)){ require $err_dir; } } } ``` 然后我們開始在項目中使用它,首先在app類中使用 ```cpp |-core 框架核心目錄 | |-App.class.php URL重寫類 <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/25 * Time: 上午10:53 */ class App { protected static $controller = 'Home';//控制器名 protected static $method = 'index';//方法名 protected static $pams = array();//其他參數 /** * url重寫路由的url地址解析方法 */ protected static function paseUrl(){ if(!empty($_GET['url'])){ $url = explode('/',$_GET['url']); //得到控制器 if(isset($url[0])){ self::$controller = $url[0]; unset($url[0]); } //得到方法名 if(isset($url[1])){ self::$method = $url[1]; unset($url[1]); } //判斷是否有其他參數 if(isset($url)){ self::$pams = array_values($url); } } } /** * 項目的入口方法 * @throws Exception */ public static function run(){ self::paseUrl(); //得到控制器的路徑 $url = 'app/controllers/'.self::$controller.'.class.php'; //判斷控制器文件是否存在 if(file_exists($url)){ $c = new self::$controller; }else{ throw new MyException('控制器不存在'); } //執行方法 if(method_exists($c,self::$method)){ $m = self::$method; $new_pams = array(); $num = count(self::$pams); //傳遞參數,判斷是否有參數 if($num > 0){ //判斷傳遞的參數的數量是否是2的倍數 if($num % 2 == 0){ //將參數進行處理 for($i=0;$i<$num;$i+=2){ $new_pams[self::$pams[$i]] = self::$pams[$i+1]; } }else{ throw new MyException('非法參數!'); } } $c->$m($new_pams); }else{ throw new MyException('方法不存在'); } } /** * 自動加載類方法 * @param $className * @throws Exception */ public static function myAutoloader($className){ //控制器類文件目錄 $controller = 'app/controllers/'.$className.'.class.php'; //模型類文件目錄 $model = 'app/models/'.$className.'.class.php'; //核心類文件目錄 $core = 'core/'.$className.'.class.php'; if(file_exists($controller)){ require_once $controller; }else if(file_exists($model)){ require_once $model; }else if(file_exists($core)){ require_once $core; }else{ throw new MyException('類文件不存在'); } } } ``` 最后我們在入口文件中也是用它 ```cpp |-index.php 項目前臺入口文件,單一入口 <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/24 * Time: 下午5:15 */ echo "<meta charset='utf-8'>"; require_once 'core/App.class.php'; //注冊一個 spl_autoload_register(array('App','myAutoloader')); try{ App::run(); throw new MyException(); }catch(MyException $e){ $e->showError(($e->getMessage())); } ``` 此時我們在瀏覽器中輸入 ```cpp http://localhost/php_mvc//home2/index ``` 如果返回的如下,則表示成功 ```cpp 這里是自定義的異常報錯模板:控制器不存在 ``` #12.項目后臺mvc架構 其實后臺和前臺差不多,在web下也有一個index.php文件,然后也需要隱藏index.php,所以我們直接將.htaccess也拿過來。 ```cpp |-web 后臺 | |-.htaccess 后臺分布式配置文件 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FIELNAME} !-d RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] ``` 然后后臺入口文件和前臺的入口文件內容也差不多,只是引入文件的路徑需要調整。還有就是我們要區分前后臺,根據前后臺定義的變量APP來判斷。前臺入口文件也需要定義 define('APP','app'); ```cpp |-web 后臺 | |-index.php 項目后臺入口文件,單一入口 <?php /** * 項目后臺入口文件 * User: find35.com * Date: 15/12/27 * Time: 下午3:12 */ echo "<meta charset='utf-8'>"; require_once '../core/App.class.php'; //注冊一個 define('APP','web'); spl_autoload_register(array('App','myAutoloader')); try{ App::run(); }catch(MyException $e){ $e->showError(($e->getMessage())); } ``` 然后我們也需要根據入口文件傳遞的APP來調整app.class.php文件里面的路徑。 ```cpp |-core 框架核心目錄 | |-App.class.php URL重寫類 <?php /** * Created by PhpStorm. * User: find35.com * Date: 15/12/25 * Time: 上午10:53 */ class App { protected static $controller = 'Home';//控制器名 protected static $method = 'index';//方法名 protected static $pams = array();//其他參數 /** * url重寫路由的url地址解析方法 */ protected static function paseUrl(){ if(!empty($_GET['url'])){ $url = explode('/',$_GET['url']); //得到控制器 if(isset($url[0])){ self::$controller = $url[0]; unset($url[0]); } //得到方法名 if(isset($url[1])){ self::$method = $url[1]; unset($url[1]); } //判斷是否有其他參數 if(isset($url)){ self::$pams = array_values($url); } } } /** * 項目的入口方法 * @throws Exception */ public static function run(){ self::paseUrl(); //判斷是前臺還是后臺 if(APP == 'app'){ //得到控制器的路徑 $url = 'app/controllers/'.self::$controller.'.class.php'; } if(APP == 'web'){ //得到控制器的路徑 $url = 'controllers/'.self::$controller.'.class.php'; } //判斷控制器文件是否存在 if(file_exists($url)){ $c = new self::$controller; }else{ throw new MyException('控制器不存在'); } //執行方法 if(method_exists($c,self::$method)){ $m = self::$method; $new_pams = array(); $num = count(self::$pams); //傳遞參數,判斷是否有參數 if($num > 0){ //判斷傳遞的參數的數量是否是2的倍數 if($num % 2 == 0){ //將參數進行處理 for($i=0;$i<$num;$i+=2){ $new_pams[self::$pams[$i]] = self::$pams[$i+1]; } }else{ throw new MyException('非法參數!'); } } $c->$m($new_pams); }else{ throw new MyException('方法不存在'); } } /** * 自動加載類方法 * @param $className * @throws Exception */ public static function myAutoloader($className){ if(APP == 'app'){ //控制器類文件目錄 $controller = 'app/controllers/'.$className.'.class.php'; //模型類文件目錄 $model = 'app/models/'.$className.'.class.php'; //核心類文件目錄 $core = 'core/'.$className.'.class.php'; } if(APP == 'web'){ //控制器類文件目錄 $controller = 'controllers/'.$className.'.class.php'; //模型類文件目錄 $model = 'models/'.$className.'.class.php'; //核心類文件目錄 $core = '../core/'.$className.'.class.php'; } if(file_exists($controller)){ require_once $controller; }else if(file_exists($model)){ require_once $model; }else if(file_exists($core)){ require_once $core; }else{ throw new MyException('類文件不存在'); } } } ``` 然后我們也建立一個后臺首頁控制器 ```cpp |-web 后臺 | |-controllers 存放所有的控制器目錄 | |-Home.class.php 后臺首頁控制器 <?php /** * 網站后臺首頁 * User: find35.com * Date: 15/12/27 * Time: 下午3:19 */ class Home { public function index(){ echo '這里是后臺的控制器首頁'; } } ``` 此時我們在瀏覽器中輸入 ```cpp http://localhost/php_mvc/web/ ``` 如果顯示如下則表示成功 ```cpp 這里是后臺的控制器首頁 ``` #13.封裝一個單例模式的MODEL類 單例模式就是一個類在使用的時候只能有一個實例,類的實例是在類內部進行創建,好處是大大的節省了資源的開銷,方便訪問類的實例,使用最多的地方是數據庫類的封裝。具體實現的方法是將我們的構造方法進行private進行修飾,禁止在類外進行實例化,因此只要你在類面進行實例化,就會報錯。再類里面定義一個,可以在類里面得到一個實例的方法。判斷類是否存在,如果存在則返回否則創建。 我們創建一個model.class.php數據庫操作類 ```cpp |-core 框架核心目錄 | |-Model.class.php 數據庫操作類 業務邏輯層 <?php /** * 數據庫操作類 * User: find35.com * Date: 15/12/27 * Time: 下午4:52 */ class Model { protected static $_instance; //單例模式 不允許在類外對類進行實例化 private function __construct(){} //獲得類的實例 public static function getSingleton(){ //判斷我們類的實例是否存在,沒有則創建之 if(!isset(self::$_instance)){ self::$_instance = new self(); } return self::$_instance; } } ``` 再類中對構造函數給予了private權限,因此無法在外面對這個類進行實例化,然后我們在入口文件這里執行以下這個方法,看看有沒有東西 ```cpp |-index.php 項目前臺入口文件,單一入口 <?php /** * 項目前臺入口文件 * User: find35.com * Date: 15/12/24 * Time: 下午5:15 */ echo "<meta charset='utf-8'>"; require_once 'core/App.class.php'; //注冊一個 define('APP','app'); spl_autoload_register(array('App','myAutoloader')); try{ App::run(); }catch(MyException $e){ $e->showError($e->getMessage()); } $db = Model::getStringleton(); print_r($db); ``` 此時我們在瀏覽器中輸入 ```cpp http://localhost/php_mvc/ ``` 如果返回如下,則表示成功 ```cpp 前臺首頁Model Object ( ) ``` #14.PDO方式連接MySQL數據庫 采用的是PDO的方式進行封裝,PDO是PHP中的一個擴展庫,他是一個純面向對象的,好處就是提供了一個可以連接各種數據庫的接口,另外PDO中的prepare預處理的方式可以大大減少sql語句的注入機器相關的安全性。 和其他框架一樣,我們將關于數據庫信息寫入一個配置文件中。 ```cpp |-config 配置 | |-constants.php 項目常量文件 <?php /** * 項目常量文件 * User: find35.com * Date: 15/12/30 * Time: 下午8:49 */ define('HOST','localhost');//服務器地址 define('UNAME','root');//數據庫賬號 define('UPASS','');//數據庫密碼 define('DBNAME','test');//操作的數據庫名 ``` 之后我們在前臺入口文件引入這個文件。然后我們在model.class.php類中封裝一個方法來連接數據庫。 ```cpp |-core 框架核心目錄 | |-Model.class.php 數據庫操作類 業務邏輯層 <?php /** * 數據庫操作類 * User: find35.com * Date: 15/12/27 * Time: 下午4:52 */ class Model { protected static $_instance; protected static $_link; /** * 單例模式 不允許在類外對類進行實例化 */ private function __construct(){} /** * 獲得類的實例 * @return mixed|Model */ public static function getStringleton(){ //判斷我們類的實例是否存在,沒有則創建之 if(!isset(self::$_instance)){ self::$_instance = new self(); } //連接數據庫 self::connect(HOST,UNAME,UPASS,DBNAME); return self::$_instance; } /** * 連接數據庫方法 * @param $host 服務器地址 * @param $username 數據庫賬號 * @param $userpass 數據庫密碼 * @param $dbname 操作的數據庫名 */ protected static function connect($host,$username,$userpass,$dbname){ try{ self::$_link = new PDO("mysql:host={$host};dbname={$dbname}",$username,$userpass); if(self::$_link){ echo '連接數據庫成功'; } }catch (PDOException $e){ MyException::showError($e->getMessage()); } } } ``` 我們把自定義的異常報錯類的showerror方法設置為static屬性,此處不貼代碼了 然后我們在入口文件調用下,看看是否可以 ```cpp |-index.php 項目前臺入口文件,單一入口 <?php /** * 項目前臺入口文件 * User: find35.com * Date: 15/12/24 * Time: 下午5:15 */ echo "<meta charset='utf-8'>"; require_once 'core/App.class.php'; require_once 'config/constants.php'; //注冊一個 define('APP','app'); spl_autoload_register(array('App','myAutoloader')); try{ App::run(); }catch(MyException $e){ $e->showError($e->getMessage()); } $db = Model::getStringleton(); ``` 瀏覽器中輸入 ```cpp http://localhost/php_mvc ``` 返回如下,則表示成功 ```cpp 前臺首頁連接數據庫成功 ``` #15.MODEL層CURD的實現 首先我們在test庫中先建立數據庫表users ```cpp CREATE TABLE users ( `id` INT(10) AUTO_INCREMENT , `username` VARCHAR(255) , `userpass` VARCHAR(255) , `create_time` INT(10),PRIMARY KEY (id)); INSERT INTO users (username,userpass,create_time) VALUES ('zhang','e10adc3949ba59abbe56e057f20f883e',1451515405), ('zhang2','e10adc3949ba59abbe56e057f20f883e',1451515406), ('zhang3','e10adc3949ba59abbe56e057f20f883e',1451515407), ('zhang4','e10adc3949ba59abbe56e057f20f883e',1451515408), ('zhang5','e10adc3949ba59abbe56e057f20f883e',1451515409); ``` 這里是使用預處理語言來查詢數據庫,注意設置數據返回類型,數據如何進行報錯。MODEL的CURD來了。 ```cpp |-core 框架核心目錄 | |-Model.class.php 數據庫操作類 業務邏輯層 <?php /** * 數據庫操作類 * User: find35.com * Date: 15/12/27 * Time: 下午4:52 */ class Model { protected static $_instance; protected static $_link; protected $whereStr = '';//用來存儲where條件 /** * 單例模式 不允許在類外對類進行實例化 */ private function __construct(){} /** * 獲得類的實例 * @return mixed|Model */ public static function getStringleton(){ //判斷我們類的實例是否存在,沒有則創建之 if(!isset(self::$_instance)){ self::$_instance = new self(); } //連接數據庫 self::connect(HOST,UNAME,UPASS,DBNAME); return self::$_instance; } /** * 連接數據庫方法 * @param $host 服務器地址 * @param $username 數據庫賬號 * @param $userpass 數據庫密碼 * @param $dbname 操作的數據庫名 */ protected static function connect($host,$username,$userpass,$dbname){ try{ self::$_link = new PDO("mysql:host={$host};dbname={$dbname}",$username,$userpass); //設置返回數據的類型 self::$_link->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC); //設置操作數據庫的報錯模式 // self::$_link->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING); // if(self::$_link){ // echo '連接數據庫成功'; // } }catch (PDOException $e){ MyException::showError($e->getMessage()); } } /** * 直接執行sql語句查詢數據庫的方法 * @param $sql mysql語句 * @param array $where 條件數據 * @return mixed 成功數組 */ public function queryString($sql,$where=array()){ try{ //使用預處理語句來執行sql $stmt = self::$_link->prepare($sql); //判斷是否有條件數組 if(empty($where)){ $stmt->execute(); }else{ $stmt->execute($where); } //判斷執行是否成功 if($stmt->rowCount() > 0){ return $stmt->fetchAll(); }else { //得到錯誤信息 $err = $stmt->errorInfo(); throw new PDOException($err[2]); } }catch(PDOException $e){ MyException::showError($e->getMessage()); } } /** * 內部sql處理好的查詢方法 * @param $table 表名 * @param array $where 查詢條件 * @return mixed 成功返回數組 */ public function select($table,$where = array()){ $sql = "select * from {$table} "; if(!empty($this->whereStr)){ $sql .= $this->whereStr; } try{ //執行sql語句 $stmt = self::$_link->prepare($sql); if(empty($where)){ $stmt->execute(); }else{ $stmt->execute($where); } //判斷是否成功,如果不成功爆出異常 if($stmt->rowCount() > 0){ return $stmt->fetchAll(); }else{ $err = $stmt->errorInfo(); return $err[2]; } }catch(PDOException $e){ MyException::showError($e->getMessage()); } } /** * where條件方法 * @param string $whereStr * @return $this */ public function where($whereStr = ''){ $this->whereStr = $whereStr; return $this;//返回當前對象 } /** * 查詢單條數據的方法 * @param $table 表名 * @param array $where 查詢的條件,:key=value * @return mixed 成功返回數組 */ public function find($table,$where = array()){ $sql = "select * from {$table} "; if(!empty($this->whereStr)){ $sql .= $this->whereStr; } try{ //執行sql $stmt = self::$_link->prepare($sql); if(empty($where)){ $stmt->execute(); }else{ $stmt->execute($where); } //判斷是否成功 if($stmt->rowCount() > 0){ $result = $stmt->fetchAll(); return $result[0]; }else{ $err = $stmt->errorInfo(); throw new PDOException($err[2]); } }catch(PDOException $e){ MyException::showError($e->getMessage()); } } /** * 添加單條數據的方法 * @param $table 表名 * @param array(':username'=>'zhang6',':userpass'=>md5(123456),':create_time'=>time()) $data * @return int 成功返回1 */ public function insert($table,array $data){ $sql = "insert into {$table} "; $fields = ""; $values = ""; foreach($data as $k => $v){ $fields .= ltrim($k,":").","; $values .= "'".ltrim($v,":")."',"; } $sql .= "(".rtrim($fields,",").") values (".rtrim($values,",").")"; try{ //開啟事務 self::$_link->beginTransaction(); $stmt = self::$_link->prepare($sql); $stmt->execute($data); if($stmt->rowCount() > 0){ self::$_link->commit(); return 1; }else{ self::$_link->rollback(); $err = $stmt->errorInfo(); throw new PDOException($err[2]); } }catch(PDOException $e){ MyException::showError($e->getMessage()); } } /** * 更新數據 * @param $table 表名 * @param array $data array(':username'=>'lisi',':userpass'=>md5(456789)); * @param array $where array(':id'=>9); * @return int */ public function update($table,array $data,array $where){ $sql = "update {$table} set "; $set_str = ''; foreach($data as $k => $v){ $set_str .= ltrim($k,":")."=$k,"; } $sql .= rtrim($set_str,',').' '.$this->whereStr; try{ self::$_link->beginTransaction(); $stmt = self::$_link->prepare($sql); $data2 = array_merge($data,$where); $stmt->execute($data2); if($stmt->rowCount() > 0){ self::$_link->commit(); return 1; }else{ self::$_link->rollback(); $err = $stmt->errorInfo(); throw new PDOException($err[2]); } }catch(PDOException $e){ MyException::showError($e->getMessage()); } } /** * 刪除數據方法 * @param $table 表名 * @param array $where * @return int */ public function delete($table,array $where){ $sql = "delete from {$table} ".$this->whereStr; try{ self::$_link->beginTransaction(); $stmt = self::$_link->prepare($sql); $stmt->execute($where); if($stmt->rowCount() > 0){ self::$_link->commit(); return 1; }else{ self::$_link->rollback(); $err = $stmt->errorInfo(); throw new PDOException($err[2]); } }catch(PDOException $e){ MyException::showError($e->getMessage()); } } /** * 析構方法 * 銷毀對象 */ public function __destruct(){ self::$_link = null; } } ``` 然后我們開始進行測試 ```cpp |-index.php 項目前臺入口文件,單一入口 <?php /** * 項目前臺入口文件 * User: find35.com * Date: 15/12/24 * Time: 下午5:15 */ echo "<meta charset='utf-8'>"; require_once 'core/App.class.php'; require_once 'config/constants.php'; //注冊一個 define('APP','app'); spl_autoload_register(array('App','myAutoloader')); try{ App::run(); }catch(MyException $e){ $e->showError($e->getMessage()); } $db = Model::getStringleton(); //直接執行sql語句 //$result = $db->queryString('select * from users where username=:username',array(':username'=>'zhang')); //查詢某個表 //$result = $db->select('users'); //查詢某個表,并增加where條件 //$result = $db->where('where username=:username')->select('users',array(':username'=>'zhang')); //查詢單條數據 //$result = $db->where('where id=:id')->find('users',array(':id'=>'3')); //插入數據 //$data = array(':username'=>'zhang6',':userpass'=>md5(123456),':create_time2'=>time()); //$result = $db->insert('users',$data); //更新數據 //$data = array(':username'=>'lisi',':userpass'=>md5(456789)); //$where = array(':id'=>9); //$result = $db->where('where id=:id')->update('users',$data,$where); //刪除數據 $result = $db->where('where id=:id')->delete('users',array('id'=>9)); echo "<pre>"; print_r($result); ``` 如果結果都是1,那么表示都成功了。
                  <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>

                              哎呀哎呀视频在线观看