一、使用的数据库名称:demo1,表名:user
二、文档结构如下图:
三、实现效果(获取表的全部内容)如下图:
四、注意问题
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();