一次对CI框架update方法底层实现的探索之旅
如果执行数据更新,CI框架一般都是如此调用$this->db->update,这是如何实现的呢
CI框架的db->update
- Print_r($this->db),知道了他的细节,他的名字,属性,
- 然后在系统文件夹中找到了这个类文件,
- 发现并没有update这个方法
- 去他的父类中寻找
- 然而并没有发现CI_DB这个文件
- 在DB.php中发现了这样的代码:
a)
i. 这个代码,定义了CI_DB,虽然类内什么都没有,但是它继承了CI_DB_active_record或者CI_DB_driver,至于根据什么判断去继承,日后研究
ii. 而DB.php早已经在调用$this->db->update之前加载好了
iii. 在本项目中,是走上者的,即继承了CI_DB_active_record
7.去查看CI_DB_active_rec.php并找到了update方法
8.
9.在update方法中,对需要update的数据$set进行处理
10.去看set方法,
a)
b) 这是把每一项需要修改的数据通过escape方法处理后,放到ar_set属性中
c) 去找escape方法,它在父类CI_DB_driver中,
d)
e) 看到此方法中是调用escape_str方法进行的处理
f) 然后总是想当然的认为此方法就在父类CI_DB_driver里
g) 可是父类CI_DB_driver并没有此方法,而且并没有继承任何类
h) 当时就找啊找,总以为用了类似于__call之类的方法,或者我没有接触过的方法
i) 后来,捋一捋继承顺序
i. CI_DB_mysql_driver extends CI_DB(escape_str在CI_DB_mysql中)
ii. class CI_DB extends CI_DB_active_record
iii. class CI_DB_active_record extends CI_DB_driver(CI_DB_driver::escape方法里调用了CI_DB_mysql:: escape_str)
j) 终于明白了,这个escape方法,只能在创建CI_DB_mysql_driver的实例的时候,才能调用内部的escape_str
举个简单的例子,下图父类中的fathermethod方法,只有在子类child去调用时,才不会出错,因为fathermethod方法调用了在子类内部才定义的方法