博客列表 >用命名空间实现一个小框架示例,并进行类的自动加载

用命名空间实现一个小框架示例,并进行类的自动加载

LIWEN的博客
LIWEN的博客原创
2018年01月18日 16:30:35720浏览

一、使用的数据库名称: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();


声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议