• [转]1小时内打造你自己的PHP MVC框架


    简介

    MVC框架在现在的开发中相当流行,不论你使用的是JAVA,C#,PHP或者IOS,你肯定都会选择一款框架。虽然不能保证100%的开发语言都会使用框架,但是在PHP社区当中拥有*多数量的MVC框架。今天你或许还在使用Zend,明天你换了另一个项目也许就会转投Yii,Laravel或者CakePHP的怀抱。如果你刚开始使用一种框架,当你看它的源码的时候你会觉得一头雾水,是的,这些框架都很复杂。因为这些流行的框架并不是短时间之内就写出来就发行的,它们都是经过一遍又一遍的编写和测试加上不断的更新函数库才有了今天得模样。所以就我的经验来看,了解MVC框架的设计核心理念是很有必要的,不然你就会感觉在每一次使用一个新的框架的时候一遍又一遍的从头学习。

     

    所以*好的理解MVC的方法就是写一个你自己的MVC框架。在这篇文章中,我将会向你展示如何构建一个自己的MVC框架

    MVC架构模式

    M: Model-模型

    V: View-视图

    C: Controller-控制器

     

    MVC的关键概念就是从视图层分发业务逻辑。首先解释以下HTTP的请求和相应是如何工作的。例如,我们有一个商城网站,然后我们想要添加一个商品,那么*简单的一个URL就会是像下面这个样子:

    http://bestshop.com/index.php?p=admin&c=goods&a=add

     

    http://bestshop.com就是主域名或者基础URL;

    p=admin 意味着处在管理模块,,或者是系统的后台模块。同时我们肯定也拥有前台模块,前台模块供所有用户访问(本例中, 它是p=public)


    c=goods&a=add 意思是URL请求的是goods控制器里的add方法。

    前台控制器设计

    在上面的例子中index.php中是什么?在PHP框架中它被称为入口文件。这个文件通常都被命名为index.php,当然你也可以给它别的命名。这个index.php的*主要的作用就是作为HTTP请求的唯一入口文件,这样无论你的URL请求什么资源,它都必须通过这个Index.php来请求。你可能要问为什么,它是如何做到的?PHP中的前端控制器用到了Apache服务器的分布式配置.htaccess实现的。在这个文件中,我们可以使用重写模块告诉Apache服务器重定向到我们的index.php入口文件,就像下面这样:

    <IfModule mod_rewrite.c>
    
       
    
       Options +FollowSymLinks
    
       RewriteEngine on
    
    
       # Send request via index.php
    
       RewriteCond %{REQUEST_FILENAME} !-f
    
       RewriteCond %{REQUEST_FILENAME} !-d
    
       RewriteRule ^(.*)$ index.php/$1 [L]
    
    
    </IfModule>

    这个配置文件非常有用,还有当你重写这个配置文件的时候你不需要重启Apache。但是当你修改Apache的其他配置文件的时候你都需要重启Apache才能生效,因为Apache只有在启动的时候才会读取这些配置文件。

    同时,index.php还会进行框架的初始化并且分发路由请求给对应的控制器和方法。

    我们的MVC目录结构

    现在让我们开始创建我们的框架目录结构。我们你可以随便先建立一个文件夹,命名为你项目的名称,比如:/bestshop。在这个文件夹下你需要建立下面的文件夹:

    /application-存放web应用程序目录

    /framework-存放框架文件目录

    /public-存放所有的公共的静态资源,比如HTML文件,CSS文件和jJS文件。

    index.php-唯一入口文件

     

    然后在application文件夹下再建立下一级的目录

    /config-存放应用的配置文件

    /controllers-应用的控制器类

    /model-应用的模型类

    /view-应用的视图文件

     

    现在在application/controllers文件夹下,我们还需要创建两个文件夹,一个frontend,一个backend:

    同样的,在view下也建立frontend和backend文件夹:

     

    就像你看到的,在application的controllers和view下面建立了backen和frontend文件夹,就像我们的用用有前台和后台功能一样。但是为什么不在model下也这样做呢?

    Well, the reason here is, normally for a web app:是因为一般在我们的应用中,前台和后台其实是可以看做是两个“网站的”,但是CRUD操作的是同一个数据库,这就是问什么管理员更新了货物的价格的时候,前台用户可以马上看到价格的变化,因为前台和后台是共享一个数据库(表)的。所以在model中没必要再去建立两个文件夹。

      

    :现在让我们回到framework文件夹中,一些框架的文件夹命名会用框架的名字命名,比如"symfony"。在framework中让我们快速建立下面的子目录:

    /core-框架核心文件目录

    /database-数据库目录(比如数据库启动类)

    /helpers-辅助函数目录

    /libraries-类库目录

    现在进入public文件夹,建立下面的目录:

    /css-存放css文件

    /images-存放图片文件

    /js-存放js文件

    /uploads-存放上传的文件

    OK。到目前为止这就是我们这个迷你的MVC框架的目录结构了!

    框架核心类

    现在在framework/core下建立一个Framework.class.php的文件。写入以下代码:

     1 // framework/core/Framework.class.php
     2 
     3 class Framework {
     4 
     5 
     6    public static function run() {
     7 
     8        echo "run()";
     9 
    10    }

    我们创建了一个静态方法run(),现在让我们通过入口文件index.php测试一下:

    1 <?php
    2 
    3 
    4 require "framework/core/Framework.class.php";
    5 
    6 
    7 Framework::run();

    你可以在你的浏览器里访问index.php看到结果。通常这个静态方法被命名为run()或者bootstrap()。在这个方法中,我们要做3件*主要的事情:

     1 class Framework {
     2 
     3 
     4    public static function run() {
     5 
     6 //        echo "run()";
     7 
     8        self::init();
     9 
    10        self::autoload();
    11 
    12        self::dispatch();
    13 
    14    }
    15 
    16 
    17    private static function init() {
    18 
    19    }
    20 
    21 
    22    private static function autoload() {
    23 
    24 
    25    }
    26 
    27 
    28    private static function dispatch() {
    29 
    30 
    31    }
    32 
    33 }

    初始化

    init()方法:

     1 // Initialization
     2 
     3 private static function init() {
     4 
     5     // Define path constants
     6 
     7     define("DS", DIRECTORY_SEPARATOR);
     8 
     9     define("ROOT", getcwd() . DS);
    10 
    11     define("APP_PATH", ROOT . 'application' . DS);
    12 
    13     define("FRAMEWORK_PATH", ROOT . "framework" . DS);
    14 
    15     define("PUBLIC_PATH", ROOT . "public" . DS);
    16 
    17 
    18     define("CONFIG_PATH", APP_PATH . "config" . DS);
    19 
    20     define("CONTROLLER_PATH", APP_PATH . "controllers" . DS);
    21 
    22     define("MODEL_PATH", APP_PATH . "models" . DS);
    23 
    24     define("VIEW_PATH", APP_PATH . "views" . DS);
    25 
    26 
    27     define("CORE_PATH", FRAMEWORK_PATH . "core" . DS);
    28 
    29     define('DB_PATH', FRAMEWORK_PATH . "database" . DS);
    30 
    31     define("LIB_PATH", FRAMEWORK_PATH . "libraries" . DS);
    32 
    33     define("HELPER_PATH", FRAMEWORK_PATH . "helpers" . DS);
    34 
    35     define("UPLOAD_PATH", PUBLIC_PATH . "uploads" . DS);
    36 
    37 
    38     // Define platform, controller, action, for example:
    39 
    40     // index.php?p=admin&c=Goods&a=add
    41 
    42     define("PLATFORM", isset($_REQUEST['p']) ? $_REQUEST['p'] : 'home');
    43 
    44     define("CONTROLLER", isset($_REQUEST['c']) ? $_REQUEST['c'] : 'Index');
    45 
    46     define("ACTION", isset($_REQUEST['a']) ? $_REQUEST['a'] : 'index');
    47 
    48 
    49     define("CURR_CONTROLLER_PATH", CONTROLLER_PATH . PLATFORM . DS);
    50 
    51     define("CURR_VIEW_PATH", VIEW_PATH . PLATFORM . DS);
    52 
    53 
    54     // Load core classes
    55 
    56     require CORE_PATH . "Controller.class.php";
    57 
    58     require CORE_PATH . "Loader.class.php";
    59 
    60     require DB_PATH . "Mysql.class.php";
    61 
    62     require CORE_PATH . "Model.class.php";
    63 
    64 
    65     // Load configuration file
    66 
    67     $GLOBALS['config'] = include CONFIG_PATH . "config.php";
    68 
    69 
    70     // Start session
    71 
    72     session_start();
    73 
    74 }

    在注释中你可以看到每一步的目的。

    自动加载

    在项目中,我们不想在脚本中想使用一个类的时候手动的去include或者require加载,这就是为什么PHP MVC框架都有自动加载的功能。例如,在symfony中,如果你想要加载lib下的类,它将会被自动引入。很神奇是吧?现在让我们在自己的框架中加入自动加载的功能。

     

    这里我们要用的PHP中的自带函数spl_autoload_register:

     1 // Autoloading
     2 
     3 private static function autoload(){
     4 
     5     spl_autoload_register(array(__CLASS__,'load'));
     6 
     7 }
     8 
     9 
    10 // Define a custom load method
    11 
    12 private static function load($classname){
    13 
    14 
    15     // Here simply autoload app&rsquo;s controller and model classes
    16 
    17     if (substr($classname, -10) == "Controller"){
    18 
    19         // Controller
    20 
    21         require_once CURR_CONTROLLER_PATH . "$classname.class.php";
    22 
    23     } elseif (substr($classname, -5) == "Model"){
    24 
    25         // Model
    26 
    27         require_once  MODEL_PATH . "$classname.class.php";
    28 
    29     }
    30 
    31 }

    每一个框架都有自己的命名规则,我们的也不例外。对于一个控制器类,它需要被命名成类似xxxController.class.php,对于一个模型类,需要被命名成xxModel.class.php。为什么在使用一个框架的时候你需要遵守它的命名规则呢?自动加载就是一条原因。

    路由/分发

    // Routing and dispatching
    
    private static function dispatch(){
    
        // Instantiate the controller class and call its action method
    
        $controller_name = CONTROLLER . "Controller";
    
        $action_name = ACTION . "Action";
    
        $controller = new $controller_name;
    
        $controller->$action_name();
    
    }
    在这步中,index.php将会分发请求到对应的Controller::Aciton()方法中。
     
     
     

    基础Controller类

    通常在框架的核心类中都有一个基础的控制器。在symfony中,被称为sfAction;在iOS中,被称为UIViewController。在这里我们命名为Controller,在framework/core下建立Controller.class.php

     1 <?php
     2 
     3 // Base Controller
     4 
     5 class Controller{
     6 
     7     // Base Controller has a property called $loader, it is an instance of Loader class(introduced later)
     8 
     9     protected $loader;
    10 
    11 
    12     public function __construct(){
    13 
    14         $this->loader = new Loader();
    15 
    16     }
    17 
    18 
    19     public function redirect($url,$message,$wait = 0){
    20 
    21         if ($wait == 0){
    22 
    23             header("Location:$url");
    24 
    25         } else {
    26 
    27             include CURR_VIEW_PATH . "message.html";
    28 
    29         }
    30 
    31 
    32         exit;
    33 
    34     }
    35 
    36 }
    37 基础控制器有一个变量$loader,它是Loader类的实例化(后面介绍)。准确的说,$this->loader是一个变量指向了被实例化的Load类。在这里我不过多的讨论,但是这的确是一个非常关键的概念。我遇到过一些PHP开发者相信在这个语句之后:
    38 
    39 $this->loader = new Loader();
    40 $this->load是一个对象。不,它只是一个引用。这是从Java中开始使用的,在Java之前,在C++和Objective C中被称为指针。引用是个封装的指针类型。比如,在iOS(O-C)中,我们创建了一个对象:
    41 
    42 UIButton *btn = [UIButton alloc] init];

    加载类

    在framework.class.php中,我们已经封装好了应用的控制器和模型的自动加载。但是如何自动加载在framework目录中的类呢?现在我们可以新建一个Loader类,它会加载framework目录中的类和函数。当我们加载framework类时,只需要调用这个Loader类中的方法即可。

     1 class Loader{
     2 
     3     // Load library classes
     4 
     5     public function library($lib){
     6 
     7         include LIB_PATH . "$lib.class.php";
     8 
     9     }
    10 
    11 
    12     // loader helper functions. Naming conversion is xxx_helper.php;
    13 
    14     public function helper($helper){
    15 
    16         include HELPER_PATH . "{$helper}_helper.php";
    17 
    18     }
    19 
    20 }

    封装模型

    我们需要下面两个类来封装基础Model类:

    Mysql.class.php - 在framework/database下建立,它封装了数据库的链接和一些基本查询方法。

     

    Model.class.php - framework/core下建立,基础模型类,封装所有的CRUD方法。

     

    Mysql.class.php :

      1 <?php
      2 
      3 /**
      4 
      5 *================================================================
      6 
      7 *framework/database/Mysql.class.php
      8 
      9 *Database operation class
     10 
     11 *================================================================
     12 
     13 */
     14 
     15 class Mysql{
     16 
     17     protected $conn = false;  //DB connection resources
     18 
     19     protected $sql;           //sql statement
     20 
     21    
     22 
     23     /**
     24 
     25      * Constructor, to connect to database, select database and set charset
     26 
     27      * @param $config string configuration array
     28 
     29      */
     30 
     31     public function __construct($config = array()){
     32 
     33         $host = isset($config['host'])? $config['host'] : 'localhost';
     34 
     35         $user = isset($config['user'])? $config['user'] : 'root';
     36 
     37         $password = isset($config['password'])? $config['password'] : '';
     38 
     39         $dbname = isset($config['dbname'])? $config['dbname'] : '';
     40 
     41         $port = isset($config['port'])? $config['port'] : '3306';
     42 
     43         $charset = isset($config['charset'])? $config['charset'] : '3306';
     44 
     45        
     46 
     47         $this->conn = mysql_connect("$host:$port",$user,$password) or die('Database connection error');
     48 
     49         mysql_select_db($dbname) or die('Database selection error');
     50 
     51         $this->setChar($charset);
     52 
     53     }
     54 
     55     /**
     56 
     57      * Set charset
     58 
     59      * @access private
     60 
     61      * @param $charset string charset
     62 
     63      */
     64 
     65     private function setChar($charest){
     66 
     67         $sql = 'set names '.$charest;
     68 
     69         $this->query($sql);
     70 
     71     }
     72 
     73     /**
     74 
     75      * Execute SQL statement
     76 
     77      * @access public
     78 
     79      * @param $sql string SQL query statement
     80 
     81      * @return $result,if succeed, return resrouces; if fail return error message and exit
     82 
     83      */
     84 
     85     public function query($sql){        
     86 
     87         $this->sql = $sql;
     88 
     89         // Write SQL statement into log
     90 
     91         $str = $sql . "  [". date("Y-m-d H:i:s") ."]" . PHP_EOL;
     92 
     93         file_put_contents("log.txt", $str,FILE_APPEND);
     94 
     95         $result = mysql_query($this->sql,$this->conn);
     96 
     97        
     98 
     99         if (! $result) {
    100 
    101             die($this->errno().':'.$this->error().'<br />Error SQL statement is '.$this->sql.'<br />');
    102 
    103         }
    104 
    105         return $result;
    106 
    107     }
    108 
    109     /**
    110 
    111      * Get the first column of the first record
    112 
    113      * @access public
    114 
    115      * @param $sql string SQL query statement
    116 
    117      * @return return the value of this column
    118 
    119      */
    120 
    121     public function getOne($sql){
    122 
    123         $result = $this->query($sql);
    124 
    125         $row = mysql_fetch_row($result);
    126 
    127         if ($row) {
    128 
    129             return $row[0];
    130 
    131         } else {
    132 
    133             return false;
    134 
    135         }
    136 
    137     }
    138 
    139     /**
    140 
    141      * Get one record
    142 
    143      * @access public
    144 
    145      * @param $sql SQL query statement
    146 
    147      * @return array associative array
    148 
    149      */
    150 
    151     public function getRow($sql){
    152 
    153         if ($result = $this->query($sql)) {
    154 
    155             $row = mysql_fetch_assoc($result);
    156 
    157             return $row;
    158 
    159         } else {
    160 
    161             return false;
    162 
    163         }
    164 
    165     }
    166 
    167     /**
    168 
    169      * Get all records
    170 
    171      * @access public
    172 
    173      * @param $sql SQL query statement
    174 
    175      * @return $list an 2D array containing all result records
    176 
    177      */
    178 
    179     public function getAll($sql){
    180 
    181         $result = $this->query($sql);
    182 
    183         $list = array();
    184 
    185         while ($row = mysql_fetch_assoc($result)){
    186 
    187             $list[] = $row;
    188 
    189         }
    190 
    191         return $list;
    192 
    193     }
    194 
    195     /**
    196 
    197      * Get the value of a column
    198 
    199      * @access public
    200 
    201      * @param $sql string SQL query statement
    202 
    203      * @return $list array an array of the value of this column
    204 
    205      */
    206 
    207     public function getCol($sql){
    208 
    209         $result = $this->query($sql);
    210 
    211         $list = array();
    212 
    213         while ($row = mysql_fetch_row($result)) {
    214 
    215             $list[] = $row[0];
    216 
    217         }
    218 
    219         return $list;
    220 
    221     }
    222 
    223 
    224    
    225 
    226     /**
    227 
    228      * Get last insert id
    229 
    230      */
    231 
    232     public function getInsertId(){
    233 
    234         return mysql_insert_id($this->conn);
    235 
    236     }
    237 
    238     /**
    239 
    240      * Get error number
    241 
    242      * @access private
    243 
    244      * @return error number
    245 
    246      */
    247 
    248     public function errno(){
    249 
    250         return mysql_errno($this->conn);
    251 
    252     }
    253 
    254     /**
    255 
    256      * Get error message
    257 
    258      * @access private
    259 
    260      * @return error message
    261 
    262      */
    263 
    264     public function error(){
    265 
    266         return mysql_error($this->conn);
    267 
    268     }
    269 
    270 }
    271  

    Model.class.php:

      1 <?php
      2 
      3 // framework/core/Model.class.php
      4 
      5 // Base Model Class
      6 
      7 class Model{
      8 
      9     protected $db; //database connection object
     10 
     11     protected $table; //table name
     12 
     13     protected $fields = array();  //fields list
     14 
     15     public function __construct($table){
     16 
     17         $dbconfig['host'] = $GLOBALS['config']['host'];
     18 
     19         $dbconfig['user'] = $GLOBALS['config']['user'];
     20 
     21         $dbconfig['password'] = $GLOBALS['config']['password'];
     22 
     23         $dbconfig['dbname'] = $GLOBALS['config']['dbname'];
     24 
     25         $dbconfig['port'] = $GLOBALS['config']['port'];
     26 
     27         $dbconfig['charset'] = $GLOBALS['config']['charset'];
     28 
     29        
     30 
     31         $this->db = new Mysql($dbconfig);
     32 
     33         $this->table = $GLOBALS['config']['prefix'] . $table;
     34 
     35         $this->getFields();
     36 
     37     }
     38 
     39     /**
     40 
     41      * Get the list of table fields
     42 
     43      *
     44 
     45      */
     46 
     47     private function getFields(){
     48 
     49         $sql = "DESC ". $this->table;
     50 
     51         $result = $this->db->getAll($sql);
     52 
     53         foreach ($result as $v) {
     54 
     55             $this->fields[] = $v['Field'];
     56 
     57             if ($v['Key'] == 'PRI') {
     58 
     59                 // If there is PK, save it in $pk
     60 
     61                 $pk = $v['Field'];
     62 
     63             }
     64 
     65         }
     66 
     67         // If there is PK, add it into fields list
     68 
     69         if (isset($pk)) {
     70 
     71             $this->fields['pk'] = $pk;
     72 
     73         }
     74 
     75     }
     76 
     77     /**
     78 
     79      * Insert records
     80 
     81      * @access public
     82 
     83      * @param $list array associative array
     84 
     85      * @return mixed If succeed return inserted record id, else return false
     86 
     87      */
     88 
     89     public function insert($list){
     90 
     91         $field_list = '';  //field list string
     92 
     93         $value_list = '';  //value list string
     94 
     95         foreach ($list as $k => $v) {
     96 
     97             if (in_array($k, $this->fields)) {
     98 
     99                 $field_list .= "`".$k."`" . ',';
    100 
    101                 $value_list .= "'".$v."'" . ',';
    102 
    103             }
    104 
    105         }
    106 
    107         // Trim the comma on the right
    108 
    109         $field_list = rtrim($field_list,',');
    110 
    111         $value_list = rtrim($value_list,',');
    112 
    113         // Construct sql statement
    114 
    115         $sql = "INSERT INTO `{$this->table}` ({$field_list}) VALUES ($value_list)";
    116 
    117         if ($this->db->query($sql)) {
    118 
    119             // Insert succeed, return the last record&rsquo;s id
    120 
    121             return $this->db->getInsertId();
    122 
    123             //return true;
    124 
    125         } else {
    126 
    127             // Insert fail, return false
    128 
    129             return false;
    130 
    131         }
    132 
    133        
    134 
    135     }
    136 
    137     /**
    138 
    139      * Update records
    140 
    141      * @access public
    142 
    143      * @param $list array associative array needs to be updated
    144 
    145      * @return mixed If succeed return the count of affected rows, else return false
    146 
    147      */
    148 
    149     public function update($list){
    150 
    151         $uplist = ''; //update fields
    152 
    153         $where = 0;   //update condition, default is 0
    154 
    155         foreach ($list as $k => $v) {
    156 
    157             if (in_array($k, $this->fields)) {
    158 
    159                 if ($k == $this->fields['pk']) {
    160 
    161                     // If it&rsquo;s PK, construct where condition
    162 
    163                     $where = "`$k`=$v";
    164 
    165                 } else {
    166 
    167                     // If not PK, construct update list
    168 
    169                     $uplist .= "`$k`='$v'".",";
    170 
    171                 }
    172 
    173             }
    174 
    175         }
    176 
    177         // Trim comma on the right of update list
    178 
    179         $uplist = rtrim($uplist,',');
    180 
    181         // Construct SQL statement
    182 
    183         $sql = "UPDATE `{$this->table}` SET {$uplist} WHERE {$where}";
    184 
    185        
    186 
    187         if ($this->db->query($sql)) {
    188 
    189             // If succeed, return the count of affected rows
    190 
    191             if ($rows = mysql_affected_rows()) {
    192 
    193                 // Has count of affected rows  
    194 
    195                 return $rows;
    196 
    197             } else {
    198 
    199                 // No count of affected rows, hence no update operation
    200 
    201                 return false;
    202 
    203             }    
    204 
    205         } else {
    206 
    207             // If fail, return false
    208 
    209             return false;
    210 
    211         }
    212 
    213        
    214 
    215     }
    216 
    217     /**
    218 
    219      * Delete records
    220 
    221      * @access public
    222 
    223      * @param $pk mixed could be an int or an array
    224 
    225      * @return mixed If succeed, return the count of deleted records, if fail, return false
    226 
    227      */
    228 
    229     public function delete($pk){
    230 
    231         $where = 0; //condition string
    232 
    233         //Check if $pk is a single value or array, and construct where condition accordingly
    234 
    235         if (is_array($pk)) {
    236 
    237             // array
    238 
    239             $where = "`{$this->fields['pk']}` in (".implode(',', $pk).")";
    240 
    241         } else {
    242 
    243             // single value
    244 
    245             $where = "`{$this->fields['pk']}`=$pk";
    246 
    247         }
    248 
    249         // Construct SQL statement
    250 
    251         $sql = "DELETE FROM `{$this->table}` WHERE $where";
    252 
    253         if ($this->db->query($sql)) {
    254 
    255             // If succeed, return the count of affected rows
    256 
    257             if ($rows = mysql_affected_rows()) {
    258 
    259                 // Has count of affected rows
    260 
    261                 return $rows;
    262 
    263             } else {
    264 
    265                 // No count of affected rows, hence no delete operation
    266 
    267                 return false;
    268 
    269             }        
    270 
    271         } else {
    272 
    273             // If fail, return false
    274 
    275             return false;
    276 
    277         }
    278 
    279     }
    280 
    281     /**
    282 
    283      * Get info based on PK
    284 
    285      * @param $pk int Primary Key
    286 
    287      * @return array an array of single record
    288 
    289      */
    290 
    291     public function selectByPk($pk){
    292 
    293         $sql = "select * from `{$this->table}` where `{$this->fields['pk']}`=$pk";
    294 
    295         return $this->db->getRow($sql);
    296 
    297     }
    298 
    299     /**
    300 
    301      * Get the count of all records
    302 
    303      *
    304 
    305      */
    306 
    307     public function total(){
    308 
    309         $sql = "select count(*) from {$this->table}";
    310 
    311         return $this->db->getOne($sql);
    312 
    313     }
    314 
    315     /**
    316 
    317      * Get info of pagination
    318 
    319      * @param $offset int offset value
    320 
    321      * @param $limit int number of records of each fetch
    322 
    323      * @param $where string where condition,default is empty
    324 
    325      */
    326 
    327     public function pageRows($offset, $limit,$where = ''){
    328 
    329         if (empty($where)){
    330 
    331             $sql = "select * from {$this->table} limit $offset, $limit";
    332 
    333         } else {
    334 
    335             $sql = "select * from {$this->table}  where $where limit $offset, $limit";
    336 
    337         }
    338 
    339        
    340 
    341         return $this->db->getAll($sql);
    342 
    343     }
    344 
    345 }
    346  

    现在我们可以在application下创建一个User模型,对应数据库里的user表:

     1 <?php
     2 
     3 // application/models/UserModel.class.php
     4 
     5 class UserModel extends Model{
     6 
     7 
     8     public function getUsers(){
     9 
    10         $sql = "select * from $this->table";
    11 
    12         $users = $this->db->getAll($sql);
    13 
    14         return $users;
    15 
    16     }
    17 
    18 }

    后台的indexController:

     1 <?php
     2 
     3 // application/controllers/admin/IndexController.class.php
     4 
     5 
     6 class IndexController extends BaseController{
     7 
     8     public function mainAction(){
     9 
    10         include CURR_VIEW_PATH . "main.html";
    11 
    12         // Load Captcha class
    13 
    14         $this->loader->library("Captcha");
    15 
    16         $captcha = new Captcha;
    17 
    18         $captcha->hello();
    19 
    20         $userModel = new UserModel("user");
    21 
    22         $users = $userModel->getUsers();
    23 
    24     }
    25 
    26     public function indexAction(){
    27 
    28                        $userModel = new UserModel("user");
    29 
    30         $users = $userModel->getUsers();
    31 
    32         // Load View template
    33 
    34         include  CURR_VIEW_PATH . "index.html";
    35 
    36     }
    37 
    38     public function menuAction(){
    39 
    40         include CURR_VIEW_PATH . "menu.html";
    41 
    42     }
    43 
    44     public function dragAction(){
    45 
    46         include CURR_VIEW_PATH . "drag.html";
    47 
    48     }
    49 
    50     public function topAction(){
    51 
    52         include CURR_VIEW_PATH . "top.html";
    53 
    54     }
    55 
    56 }

    到目前为止,我们后台的index控制器就正常执行了,控制器中实例化了模型类,并且将得到的数据传给了视图中的模板,这样在浏览器中就能看到数据了。

     

    转自:phpchina原创译文  1小时内打造你自己的PHP MVC框架  http://www.phpchina.com/article-40109-1.html

    原文链接:http://www.codeproject.com/Articles/1080626/WebControls/

  • 相关阅读:
    MySQL事务提交流程详解
    MySQL启动过程详解五:GTID的处理
    MySQL启动过程详解二:核心模块启动 init_server_components()
    网络安全:SQL注入,XSS攻击,CSRF攻击
    Dropdown下拉菜单
    VUE:身份证组件
    window系统下 解决MySQL 8报错sql_mode=only_full_group_by:this is incompatible with sql_mode=only_full_group_by
    上传图片:点击按钮后进入对话框,点击➕号直接上传图片,点击确定即保存
    VUE: TreeChart树形图
    vue生成二维码:vueqr二维码插件使用
  • 原文地址:https://www.cnblogs.com/EdwinChan/p/7484597.html
Copyright © 2020-2023  润新知