一步步编写PHP的Framework(十八)

 

上一次我们把模型的驱动类实现了,由于ConnectionManager需要按照配置文件中配置的驱动名实例化驱动类,所以我们先在配置文件中加入驱动名:

01 <?php
02 return array(
03     'defaultController' => 'Index',
04     'defaultAction' => 'index',
05     'debug' => true,
06     'errorReporting' => -1,
07     'timeZone' => 'PRC',
08     'db' => array(
09         'dsn' => 'mysql:dbname=test;host=localhost',
10         'user' => 'test',
11         'pwd' => 'test',
12         'driver' => 'pdo'
13     )
14 );

这里面的db下面的driver就是驱动名。

 

配置文件弄好之后,ConnectionManager这个类的两个静态方法:getConnection和releaseConnection的实现就很简单了,首先getConnection就是按照配置文件中的配置选择一个驱动类,然后实例化,当然,由于以后模型文件可能有多个,然后数据库的连接最好只有一个,所以这个地方必须是单例的,releaseConnection就更简单了,直接调用驱动类的close方法即可。

01 <?php
02 class ConnectionManager extends Base {
03     private static $_instance = null;
04     public static function getConnection() {
05         if(self::$_instance == null) {
06             //按照配置文件寻找驱动类,然后连接DB
07             switch(C('db=>driver')) {
08                 case 'pdo' :
09                     self::$_instance = new PdoDriver();
10                     break;
11                 default :
12                     self::$_instance = new PdoDriver();
13                     break;
14             }
15         }
16         return self::$_instance;
17     }
18     public static function releaseConnection() {
19         if(null !== self::$_instance) {
20             self::$_instance.close();
21         }
22     }
23 }

ConnectionManager写完之后,我们再讲ModelBase,由于这个类是后面的表模型和关系模型的父类,所以它基本上定义了外部可访问的所有接口,如execute,select,update,insert,delete等。现在我们先写一个比较简单的ModelBase,这个例子中只有构造函数,execute,getAll三个方法,execute就是执行一个SQL,getAll就是获取数据。

注:如果按照之前我们讲的可以按照对象,普通数组或者Iterator返回数据,那么此处的getAll就比较复杂了,但是现在我们在getAll中就直接调用getAllByAssocArray,这样这个方法就非常简单了。

好了,话不多说,直接贴代码吧!!

01 <?php
02 class ModelBase extends Base {
03     protected $_db = null;
04     public function __construct() {
05         $this->_db = ConnectionManager::getConnection();
06     }
07     public function execute($sql,Array $arr) {
08         $this->_db->prepare($sql);
09         $this->_db->execute($arr);
10     }
11     public function getAll() {
12         return $this->_db->getAllByAssocArray();
13     }
14 }

 

由于此处没有几行代码,所以就不讲了,下面讲一下复杂一点的东西了啊。。。

我之前在B这一块儿还分了一个Sql Parse,它主要完成SQL的解析,我们知道一个简单的查询语句格式如下:

SELECT  [ALLDISTINCT]  Field FROM Table  WHERE whereCondition [GROUP BY groupCondition] [HAVING havingCondition] [ORDER BY orderCondition] 

之前我们都是直接写一个SQL字符串,这种方式不利于我们扩展,如果我们只需要指定SQL的一部分内容,其他的内容框架可以自动完成,这样维护起来容易一些,当然,复杂的SQL我不建议这么做。

就比如在表模型中,我们是指定了表名的,那么框架应该可以识别出来Table这一块儿,还有Field这部分可以默认为*,whereCondition如果没有可以不写,All或DISTINCT默认是ALL即可。

现在假设在一个表模型中,关联的表为user,那么执行一个$this->select(),按照原来的观点系统根本不知道查询的语句是什么,自然也就无法执行了,但是如果框架可以自动完成SQL的话,这个SQL就变成了:

SELECT * FROM user

这样一个SQL语句是没有任何问题的。

时间: 2024-12-22 11:30:41

一步步编写PHP的Framework(十八)的相关文章

一步步编写PHP的Framework(十)

  之前讲了这么多,实际上都只是为框架搭建了一个架子而已,框架里面还没有什么东西, 从今天开始,我就开始从Controller,Model,View这几块儿来分别介绍一下. PS:之前的很多内容我都没有细讲,就比如路由,真正的框架路由肯定不是通过GET方式指定的,而是正则,并且它需要兼容多个Server,多种方式. 我们知道所有的请求都需要经过控制器,所以首先还是说一下控制器. 我们之前已经 说过控制器的概念了,但是这个控制器还是功能太弱了,因为它只是从功能上是控制器,框架并没有为它做任何事情,

一步步编写PHP的Framework(十四)

   今天我说一下怎么在框架中over掉这些安全问题.       首先是SQL注入,这个如果你使用的是PDO,我觉得应该没什么问题,如果你使用的还是mysql_*等API,那么你可以在框架中实现bindParameter或者在插入数据库之前进行字符串转义.       前两天把上一篇文章写完之后,Vian在后面留言说到过SQL注入的一个解决方案,就是在在插入DB之前进行'''.addslashes($id).''',它的意思就是首先进行addslashes操作,之后再强制单引号包裹,这样它就是

一步步编写PHP的Framework(十五)

  从今天开始我们开始介绍模型,模型是一个框架中非常重要的一块儿,控制器实际上不能进行数据的处理,这种处理的过程我们全部放在模型这一块儿来做.         如果是Java,即使是没用框架,它的模型这一块儿也挺复杂的,首先编写service接口,然后写实现,然后定义DAO接口,DAO实现,然后定义这几层之间传输数据的Domain,一般我认为它就是一个POJO.         Java这种契约式的编程方式很不错,即使后面的实现类发生改变,接口没有改变,代码的修改的量也不是很多.        

一步步编写PHP的Framework(十六)

  我把模型分成了几块儿,A,B,C,D,E,F,这几块儿分别代表了什么呢?       首先A,这个Base代表的就是整个框架的基类,所有的模型文件都必须继承自这个基类:       由于B的内容需要依赖D,所以先说一下D,D首先有一个ConnectionManager,它负责管理数据库的连接和关闭还有数据库驱动的选择,这个命名自己感觉不太好,先就将就吧,既然它负责数据库的连接和关闭,肯定它就有以下方法: 1 <?php 2 public class ConnectionManager { 3

一步步编写PHP的Framework(十二)

          我上次在讲redirect和forward的时候我就说过,这两个函数要正常使用还需要修改一下Route这个类,至少要将比如域名,控制器名,Action名等存储起来,后面调用redirect,forward的时候可以使用.         现在我们就转到Route.php,原来这个类的代码很简单: 01 <?php 02 class Route extends Base { 03    public static function run() { 04       $contr

一步步编写PHP的Framework(八)

  既然前端控制器控制一切,那么我们可以用它来做更多的事情!! 我们知道,在windows里面默认php.ini中display_errors默认开启,而在linux中默认是关闭的,那么这样对于程序的调试时很麻烦的,所以我们可以在配置文件中设置一个debug属性,它代表是否调试打开,如果打开调试,程序出现任何异常,那么会输出很多调试信息.在这儿,我只是很简单的设置一下,真正的框架调试功能肯定不是这样简单的. 先我们实现如果debug开启,那么显示调试信息debug mode:这样一个字符串,并且

一步步编写PHP的Framework(十三)

  上次讲到控制器怎么样将数据传递到视图,今天我就主要说一下在程序中怎么让代码更"安全",之后就转到讲模型,再讲怎么做视图,最后再讲控制器的功能强化.       我再声明一下,我写这个文章只是让大家对PHP的框架编写有一个基本的了解,由于本人技术有限,这个文章是给PHP初学者学习的,所以高手勿喷,还有就是我现在时间也有限,所以每次可能需要两三天才能写一篇,每篇我写的时间也要控制在一个小时以内,由于边写这个文章边编代码,所以代码中可能会存在很多BUG,见谅!!        如果你是一

一步步编写PHP的Framework(一)

        框架这个概念可能一开始就吓坏了很多PHP的Coder,其实你只要把一个Framework想明白了,其实也没啥,只是别人功能更复杂,细节考虑的更多,代码质量更高.        框架最重要的一个文件为入口文件,基本上相当于一个总控开关,所有的请求都需要经过这个文件: 1 <?php 2 define('APP_PATH',dirname(__FILE__).'/..'); //应用路径 3 include APP_PATH.'/Library/Toper/Core/FrontCon

一步步编写PHP的Framework(九)

         之前讲到过对于异常的处理机制,最好可以自定义异常,如果debug打开,那么显示具体的调试信息,如果debug关闭,那么将异常记录到日志,然后跳转到错误页,这节课我就主要来讲一下这个异常处理机制.        现在我们定义一个异常的基类,在Toper中为Tp_Exception,在这儿,我就直接叫BaseException吧,那BaseException.php肯定首先是有一个架子的: 1 <?php 2 class BaseException extends Exceptio