Yaf模型定义与源码分析

YAF中并没有包含数据库操作部分的基类,这个需要我们自己去集成,我们可以使用PHP官方的PDO来集成我们的模型基类

一、模型定义

1、模型文件
  • 文件位置:在models文件夹下
  • 模型文件命名:采用首字母大写的形式,去掉模型类的后缀Model,如Posts.php
2、模型类定义
  • 模型类定义:以控制器文件名为基础,后面添加上Model后缀
  • 继承:一般继承模型基类(这个基类需要我们自己定义,如\core\Model)
  1. <?php
  2. class PostsModel extends \core\Model
  3. {
  4. }

二、ORM

这是ORM是来源于大眼猫的YOF,在此表示感谢,对部分内容进行了改造

1、包含的基本功能:
  • 连接数据库
  • 封装数据库CURD操作
2、实现
(1)数据库连接
  • 读取数据库连接的相关配置
  • 使用这些配置参数初始化PDO类

配置文件大体如下:(这些配置是自定义的,请根据自己的需要重新定义)

  1. database.type = mysql ;声明数据库类型
  2. database.hosts = commondb ;声明数据库主机的别名,如果多台请使用,隔开
  3. database.default.server = commondb ;默认的主机别名
  4. database.commondb.read.host = 127.0.0.1 ;commondb这个库的读库主机IP
  5. database.commondb.read.port = 3306
  6. database.commondb.read.dbname = commondb
  7. database.commondb.read.user = shixinke
  8. database.commondb.read.password = 123456
  9. database.commondb.read.prefix = tbl_ ;commondb这个库的表前缀
  10. database.commondb.write.host = 127.0.0.1 ;commondb这个库的写库主机IP
  11. database.commondb.write.port = 3306
  12. database.commondb.write.dbname = commondb
  13. database.commondb.write.user = shixinke
  14. database.commondb.write.password = 123456
  15. database.commondb.write.prefix = tbl_

读取数据库配置代码:

  1. protected function getDbConfig()
  2. {
  3. return \Yaf\Registry::get('config');
  4. }

连接数据库的代码:

  1. <?php
  2. $config = $this->getDbConfig();
  3. $type = strtolower($type);
  4. if (!$this->server) {
  5. $this->server = $config['database']['default']['server'];
  6. }
  7. $db = $this->database ? $this->database : $config['database'][$this->server][$type]['dbname'];
  8. $driver = $config['database']['type'];
  9. $host = $config['database'][$this->server][$type]['host'];
  10. $port = $config['database'][$this->server][$type]['port'];
  11. $user = $config['database'][$this->server][$type]['user'];
  12. $pwd = $config['database'][$this->server][$type]['password'];
  13. $persistent = isset($config['database'][$this->server][$type]['pconnect']) ? $config['database'][$this->server][$type]['pconnect'] : 0;
  14. if ($persistent) {
  15. $option = array(PDO::ATTR_PERSISTENT => 1);
  16. } else {
  17. $option = array();
  18. }
  19. if (!$port) {
  20. $port = 3306;
  21. }
  22. $dsn = $driver . ':host=' . $host . ';port=' . $port . ';dbname=' . $db;
  23. try {
  24. // 判断 READ, WRITE 是否是相同的配置, 是则用同一个链接, 不再创建连接
  25. $read_host = $config['database'][$this->server]['read']['host'];
  26. $read_port = $config['database'][$this->server]['read']['host'];
  27. $write_host = $config['database'][$this->server]['write']['host'];
  28. $write_port = $config['database'][$this->server]['write']['host'];
  29. if ($read_host == $write_host && $read_port == $write_port) {
  30. $sington = TRUE;
  31. }
  32. if ($sington) {
  33. if (isset(self::$obj)) {
  34. if (isset(self::$obj[$this->server]['read'])) {
  35. self::$obj[$this->server]['write'] = self::$obj[$this->server]['read'];
  36. } else {
  37. self::$obj[$this->server]['read'] = self::$obj[$this->server]['write'];
  38. }
  39. self::$conn = self::$obj[$this->server]['write'];
  40. }
  41. }
  42. // 读写要分离则创建两个连接
  43. if (!isset(self::$obj[$this->server][$type])) {
  44. self::$conn = self::$obj[$this->server][$type] = new PDO($dsn, $user, $pwd, $option);
  45. self::$conn->query('SET NAMES `utf8`');
  46. unset($db, $driver, $host, $port, $user, $pwd, $dsn);
  47. }
  48. } catch (PDOException $e) {
  49. if (ENV == 'DEV') {
  50. throw new Exception($e->getMessage());
  51. } else {
  52. //写入日志
  53. }
  54. }
(2)CURD操作
  • 读操作调用PDO的query方法,并结合PDO的fetchAll方法读取结果
  • 写操作调用PDO的exec方法
(3)调试
  • 将错误信息记入日志
  • 将每次执行的sql语句存储到一个变量中,通过getLastSql()来获取上次执行的sql语句

三、使用

1、先看一下表结构:

2、定义模型:
  • 文件位置:在application/models文件夹中
  • 文件名:去掉Model后缀的部分,如Config.php
  • 模型定义:继承于自定义的模型基类Model
  1. <?php
  2. class ConfigModel extends \core\Model
  3. {
  4. public $tableName = 'config';
  5. public $pk = 'item';
  6. public function items()
  7. {
  8. return $this->where(array('group'=>'website'))->select();
  9. }
  10. public function item()
  11. {
  12. return $this->where(array('item'=>'test'))->find();
  13. }
  14. }
3、在控制器中调用
  1. <?php
  2. class TestController extends \Yaf\Controller_Abstract
  3. {
  4. public function init()
  5. {
  6. }
  7. public function indexAction()
  8. {
  9. $model = new ConfigModel();
  10. $dataList = $model->items();
  11. var_dump($dataList);
  12. }
  13. public function detail()
  14. {
  15. $model = new ConfigModel();
  16. $info = $model->item();
  17. var_dump($info);
  18. }
  19. public function add()
  20. {
  21. $data = array('item'=>'shop', 'group'=>'website', 'value'=>'商城', 'title'=>'商城介绍', 'datatype'=>1, 'element'=>'text');
  22. $model = new ConfigModel();
  23. $res = $model->insert($data);
  24. var_dump($res);
  25. }
  26. public function edit()
  27. {
  28. $data = array('item'=>'shop', 'group'=>'website', 'value'=>'商城123', 'title'=>'商城介绍', 'datatype'=>1, 'element'=>'text');
  29. $model = new ConfigModel();
  30. $res = $model->insert($data);
  31. var_dump($res);
  32. }
  33. public function del()
  34. {
  35. $model = new ConfigModel();
  36. $res = $model->deleteById('shop');
  37. var_dump($res);
  38. }
  39. }

数据库模型操作基类完整代码:见附件

链接: https://pan.baidu.com/s/17n1VopDm7eF4saoLhU00EQ 密码: 68hc