Blogger Information
Blog 29
fans 0
comment 0
visits 27238
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
用命名空间实现一个小框架示例,并进行类的自动加载
LIWEN的博客
Original
719 people have browsed it

一、使用的数据库名称:demo1,表名:user

二、文档结构如下图:

2018-01-18_161025.png

三、实现效果(获取表的全部内容)如下图:

2018-01-18_160828.png

四、注意问题

1、使用命名空间时,调用PDO,需要在前面添加 \,否则会报错,找不到PDO对象,因为PDO对象是在根目录下的;

2、已经创建了自动加载文件,只需要在入口文件中引入自动加载文件即可,其他位置和文件中都不需要重复引入;

另外,实现过程中,感谢张小金同学帮忙排错,PDO的问题卡了好久的。

五、各个文件代码如下

数据库操作Db.php 

<?php
/**
 * 封装数据库操作
 */
namespace model;  //以目录为空间名,model目录下的多个类使用同一个命名空间名
class Db
{
    //将数据库的配置参数放入数组$dbConfig中,用pdo来做数据库连接,所以参数如下:
    private $dbConfig = [
        'dbType' => 'mysql',  //数据库类型
        'host' =>'localhost',  //服务器主机名称
        'charset' => 'utf8',  //默认字符集
        'dbname' => 'demo1',  //默认数据库
        'userName' => 'root',  //用户名
        'password' => 'root',  //密码
    ];

    //声明变量存储新增主键,并赋初始值为null
    public $insertId = null;
    //声明变量存储受影响的记录数,并赋初始值为0
    public $num = 0;
    //单例模式,本例的实例
    private static $instance = null;
    //声明数据库的链接对象
    public $pdo = null;
    //单例模式:私有化构造方法,以防止外部实例化;参数为用户自定义的数据库连接参数
    private function __construct($params=[])
    {
        //初始化连接参数,使用用户自定义的连接参数替换默认参数
        $this->dbConfig = array_merge($this->dbConfig, $params);
        //连接数据库
        $this->connect();
    }
    //单例模式:禁止外部克隆
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }
    //单例模式:获取当前类的唯一实例
    public static function getInstance($params=[])
    {
        if (!self::$instance instanceof self) {
            self::$instance = new self($params);
        }
        return self::$instance;
    }

    //数据库连接:必须要在构造方法中调用,这样创建本类的单例时可确保数据库处于连接状态
    private function connect()
    {
        try {
            //配置数据源dsn
            $dsn = $this->dbConfig['dbType']
                .':host='.$this->dbConfig['host']
                .';dbname='.$this->dbConfig['dbname']
                .';charset='.$this->dbConfig['charset'];
            $userName = $this->dbConfig['userName'];
            $password = $this->dbConfig['password'];
            //创建PDO对象,并连续数据库
            $this->pdo = new \PDO($dsn,$userName,$password);
        }catch (\PDOException $e){
           print $e->getMessage();
           die();
        }
    }

    //完成数据表的写操作,包括:新增、更新、删除,使用exec(),返回受影响的记录数,如果是新增,还返回新增主键
    public function exec($sql)
    {
        //返回受影响的记录数
        $num = $this->pdo->exec($sql);
        //判断是否有受影响的记录
        if ($num > 0){
            //如果受影响的记录数大于零,再判断是否为新增操作,如果是新增操作,初始化新增主键ID属性
            if (null !== $this->pdo->lastInsertId()){
                $this->insertId = $this->pdo->lastInsertId();
            }
            //如果是更新或删除操作,则返回受影响的记录数
            $this->num = $num;
        } else{  //如果sql语句错误,输出错误信息
            print_r($this->pdo->errorInfo());
        }
    }

    //完成数据表的查询操作
    //获取单条查询结果,返回一维数组
    public function get($sql)
    {
        $pdoStmt = $this->pdo->query($sql);
        if (isset($pdoStmt) && $pdoStmt->rowCount() == 1) {
            return $pdoStmt->fetch(\PDO::FETCH_ASSOC);
        } else {
            print_r($pdoStmt->errorInfo());
        }

    }

    //获取多条查询结果,返回二维数组
    public function all($sql)
    {
        $pdoStmt = $this->pdo->query($sql);
        if (isset($pdoStmt) && $pdoStmt->rowCount() > 0) {  //如果$pdoStatement对象存在,并且结果数量大于零
            return $pdoStmt->fetchAll(\PDO::FETCH_ASSOC);  //返回结果集
        } else {
            print_r($pdoStmt->errorInfo());
        }
    }
}

公共模型类Model.php

<?php
/**
 * 公共模型类,是当前Db类的抽象层
 */
namespace model;
use model\Db;  //引入model命名空间的Db类
class Model
{
    protected $db = null;  //数据库的连接对象
    public $data = null;  //当前用户请求的数据
    public function __construct()
    {
        $this->init();  //将模型初始化,即调用数据库连接方法,完成数据库连接
    }

    //创建数据库连接方法init()
    private function init()
    {
        //这里的变量名$dbConfig,可以随意自定义,与类无关
        $dbConfig = [
            'user' => 'root',
            'pass' => 'root',
            'dbname' => 'demo1'
        ];
        //使用用户自定义连接对象的配置参数覆盖默认参数
        $this->db = Db::getInstance($dbConfig);
    }

    //创建获取全部数据的方法all()
    public function all()
    {
        $sql = "SELECT `id`,`name`,`email` FROM `user`";
        return $this->data = $this->db->all($sql);
    }

    //创建获取单条数据的方法get()
    public function get($id)
    {
        $sql = "SELECT `id`,`name`,`email` FROM `user` WHERE `id`={$id}";
        return $this->data = $this->db->get($sql);
    }
}

实际工作类StudentModel.php

<?php
/**
 *实际工作类,与一张数据表user绑定
 */
namespace model;
use model\Db;
use model\Model;
class StudentModel extends Model
{
    //暂时保持为空,以后直接用这个与数据表绑定的自定义模板来操作数据库
}

控制器StudentController.php

<?php
/**
 * 控制器
 * 模块管理一般有:CURD增删改查
 * 模型根据数据表创建,控制器根据模块创建
 * 所以呢,一个控制器完成了一个模块的功能
 */

use model\StudentModel;   //引入model命名空间的StudentModel类
class StudentController
{
   //获取所有数据
    public function getAll()
    {
        //实例化模型,获取全部数据
        $stu = new StudentModel();
        $data = $stu->all();
        include 'view/getAll.php'; //渲染模板
    }

    //假定数据来自URL:http://www.php.io/40/index.php?c=user$a=getInfo&id=3
    //获取所有数据
    public function getInfo($id=29)
    {
        $id = isset($_GET['id']) ? $_GET['id'] : $id;
        //实例化模型,获取单条数据
        $stu = new StudentModel();
        $data = $stu->get($id);
        include 'view/getInfo.php'; //渲染模板

    }
}

自动加载文件Loader.php

<?php
//自动加载
function my_autoloader($class) {
    include $class . '.php';
}
spl_autoload_register('my_autoloader');

入口文件index.php

<?php
/**
 * 入口文件,也有人叫前端控制器、请求分发器
 */

include 'Loader.php';  //有了自动加载,入口文件中,只需要引入这一个文件就可以了。
//URL:http://www.php.io/40/index.php?c=Student&a=getInfo&id=3
//然后,获取当前URL地址,并判断有没有相应的参数。如果有c,说明有controller,如果没有,则默认为当前user.
$controller = isset($_GET['c']) ? $_GET['c'] : 'Student';
//给控制加后缀
$controller .= 'Controller';

//加载控制器
require 'controller/'.$controller.'.php';
//获取操作。用a代表操作,如果有a,就用a,如果没有a,就给个默认操作,此处默认操作给getAll
$action = isset($_GET['a']) ? $_GET['a'] : 'getAll';

//将控制器实例化
$stu = new $controller();
//调用action方法,因为$action变量获取的是个字符串,所以后面需要加上()
$stu->$action();


Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post