CI框架入门笔记
PS - 个人博客原文:CI框架入门笔记
当前(2019-03-22)CodeIgniter 框架的最新版本是 3.1.5,于2017年6月发布,距今快两年了也没有更新,这与 Laravel 的更新速度相比差距太大了。因为确实,它是一个很古老的框架了(第一个版本在2006年发布),当初的设计原则,开发环境与现在都已经大为不同。它有自己的设计原则,有相配套的一大堆工具、库,使用这些现有的工具就已经能很好地满足日常开发所需。
虽然已经是2019年了,但是公司用的框架是CI框架,所以我也应当快速适应CI框架的开发模式。本文就针对CI框架开发中的一些重点问题进行梳理和记录。CI框架的官网文档( http://codeigniter.org.cn/user_guide/index.html )很完善,但是我觉得仍然有必要整理出自己的一套实用规则。
就一个常规PHP框架来说,我认为应当包含这几个部分:
- (1)index.php 或全局 App 对象,一个提供统一入口,一个提供容器资源管理
- (2)路由控制
- (3)请求和响应对象的封装,输入数据过滤和验证,输出数据的验证和转义,各种输入输出方法
- (4)MVC 分层,控制器,模型和视图层,以及 Service 层
- (5)数据库操作:数据库驱动、查询构造器、通用的查询方法
- (6)文件存储、缓存管理
- (7)Session, Cookie管理
- (8)安全性、配置、国际化、自动加载、第三方扩展机制
- (9)常见的工具类(其实应当通过扩展提供)
- (10)模板语言(这个不是必要的,因为PHP本身就能输出)
入门
了解框架
我们下载好CI框架解压之后的初始目录是下面这样的:
application/
controller/
cache/
config/
controllers/
core/
helpers/
hooks/
language/
libraries/
logs/
models/
third_party/
views/
.htaccess
index.html
system/
core/
database/
fonts/
helpers/
language/
libraries/
index.html
.gitignore
composer.json
index.php
其中,我注意到,每个目录下面都有一个index.html文件,其内容也都是一样的:403 Forbidden。这是为了防止意外访问吗?
application/ 就是是项目目录,就是我们实际的项目代码存放处,下面分了很多子目录,看名字就知道会放哪种功能的代码,这些子目录目前除了包含一个 403 index.html 文件,没有别的内容。system/ 就是框架目录,下面就是框架代码。
根目录的 index.php 是整个项目的唯一入口点。index.php 主要的功能是定义了一些系统目录,包括项目目录、视图目录、框架目录,在最后调用了框架目录下的 core/CodeIgniter.php,这个文件是CI框架的入口点和结束点,即包含了CI框架的所有生命周期。它的执行过程如下:
* 定义全局常量,加载全局函数,环境检测,PHP版本判断
* 注册错误处理函数,自动加载函数(Composer判断)
* 加载一系列类:
* Hooks,钩子函数类
* Config,配置类
* UTF-8,
* URI,(CI_URI)
* Router,路由类
* Output,输出类
* Security,安全类
* Input,输入类
* Lang,多语言类
* 加载控制器类
* 判断控制器类、方法是否存在,不存在则404
* 调用控制器前置钩子函数
* 实例化控制器
* 调用控制器后置钩子函数
* 调用控制器方法(业务逻辑)
* 输出响应
* 调用系统后置钩子函数
在实例化控制器这一部分中,注意到它定义了一个静态实例,代码如下
# core/CodeIgniter.php
# 此处定义了一个全局函数 get_instance(),返回一个静态对象。
function &get_instance()
{
return CI_Controller::get_instance();
}
// ...
$CI = new $class();
# core/Controller.php
class CI_Controller {
public function __construct()
{
self::$instance =& $this;
// ...
}
public static function &get_instance()
{
return self::$instance;
}
}
在之后的任意位置的代码中,只要通过 get_instance() 方法就能获取唯一的 Controller 对象,它其实就是CI框架中的“容器”。
调用控制器方法(即业务逻辑)通过这段代码调用执行:
call_user_func_array(array(&$CI, $method), $params);
业务逻辑
在调用上述代码之后,就进入到 application/ 目录下我们的实际的业务功能代码。上面的 &$CI 就是 $class 名对象,即根据URL参数解析对应到 application/controllers/ 目录下的实际控制器类文件名。具体的映射方法可以看文档( https://codeigniter.org.cn/user_guide/general/controllers.html )
比如,有一个 URI 是这样的:/welcome,会解析为 application/controller/Welcome.php 文件,它应该是一个继承自 CI_Controller 的类。/welcome 相当于 /welcome/index,URI 的第一个部分是控制器,第二个部分是控制器的方法,所以这个 URI 会调用 Welcome 类的 index 方法。URI 中只有第一个部分时,那第二个部分默认是 index。在控制器方法中我们编写实际的业务功能代码。示例如下:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Welcome extends CI_Controller {
public function index()
{
$this->load->view('welcome_message');
}
}
加载功能模块(类库)
CI框架默认提供了模型、视图、辅助函数、日志、配置、缓存等功能。这些功能模块默认是不加载的,需要在控制器中进行手动按需加载。另外,libraries 目录中的类库,也是同上的加载机制,只不过这里面的类库是开发人员自己写的功能模块。下面详细描述每种模块的加载方式。
model
首先,我们看到上节中的 $this->load,这就是CI框架中的加载类(CI_Loader),我们所有需要的类库、模块都可以通过它来加载。这个加载类实际上是“容器”的一个对象属性,从下面 model 的源码可以看到,实际上所有容器的“对象属性”都可以直接通过模型获取:
class CI_Model {
public function __get($key)
{
return get_instance()->$key;
}
}
在业务功能开发中,使用最频繁的就是模型了。CI框架提供的模型类是 core/Model.php 即 CI_Model 类,它其实就是一个很简单的类,没有提供任何内容,如果你需要使用模型,那就应该在 application/models 下面新建一个继承自 CI_Model 的类,然后在使用模型的地方先使用 $this->load->model() 来加载它,加载了之后,就能直接通过 $this->{模型名} 访问该模型对象:
$this->load->model('User_model');
$result = $this->User_model->get_one($id);
model() 默认到 application/model/ 目录下寻找 user_model.php 这个文件名,然后加载 User_model 类,实例化之,并赋值作为“容器”的对象属性,属性名就是模型名。model() 方法部分源码:
public function model($model, $name = '', $db_conn = FALSE)
{
// ...
$model = new $model();
$CI->$name = $model;
}
model() 方法的第二个参数可以指定属性名,示例代码如下:
$this->load->model('User_model', 'USER');
$result = $this->USER->get_one($id);
CI框架并没有规定模型类中应当放什么,这取决于你。通常我们会写一个 Base_Model 类,用来提供各种查询方法,然后在具体的模型类中实现具体模型对应的业务方法。在控制器中直接调用模型类的业务方法获取数据。在CI框架中我们使用模型类的理由就是封装逻辑,不然所有的逻辑都写在控制器中(我看到项目中现在有一部分老代码就是这样做的!)。CI也没有提供进一步Service层,这由你自己决定。
database
一般在 Base_Model 类中,我们会加载一下默认的数据库,封装若干查询方法:
class Base_Model
{
function __construct()
{
// ...
$this->load->database();
}
function save() {}
function get_one() {}
function get_all() {}
function update() {}
function delete() {}
function query() {}
...
}
调用了 database() 之后,会实际化一个 CI_DB 对象,并赋值为控制器的 $db 属性,database() 部分源码如下:
public function database($params = '', $return = FALSE, $query_builder = NULL)
{
// ...
if ($return === TRUE)
{
return DB($params, $query_builder);
}
// ...
$CI->db =& DB($params, $query_builder);
}
可以看到,当第二个参数为 TRUE 时,直接返回 DB 对象,并不会设置为控制器的属性。这一点在具体的模型类中会有用,比如我们会在具体的模型类中加载不同的数据库类:
class Article_model extends Base_Model
{
public function __construct()
{
$this->db = $this->load->database('myDb2', TRUE);
}
}
这里获取 myDb2 数据库对象,避免了污染全局的 $CI->db 对象。
最复杂的部分其实已经介绍完了,下面是一些常用的类库介绍
helper
在使用自定义的辅助函数之前,需要加载一下,语法同上。只不过它会去 application/helpers 目录下去寻找相应文件。
$this->load->helper('dt');
libraries
application/libraries 目录下的类,加载语法同上,使用其实没什么问题,值得注意的是如何写一个自己的类库。
$this->load->library('t');
config
配置文件也需要加载,然后 item 方法直接访问配置文件中的值,自定义的配置需要设置为 $config 数组的属性的形式。
# application/config/d.php
$config['ddd'] = '';
# Controller
$this->load->config('d');
$data = $this->config->item('ddd')
view
由于现在CI项目只是作为API,所以并无视图,但为了介绍,下面提供了一个示例:
# application/views/welcome.php
# Controller
$this->load->view('welcome', $data);
这个视图文件就是一个普通的PHP文件,可以直接输出。
driver
驱动其实也是类库的一种。
总结
就我入手这个CI项目的一个月经验来看,日常业务开发就是这些东西,后面也不过是在这个框架基础上不断深入和完善。所以这篇文章作为入门总结应该算是足够了。
CI框架入门笔记的更多相关文章
- CI框架入门1
CI框架入门: 1.url的特点 2.目录结构/布局 3.MVC分别在哪里,如何依葫芦画瓢 4.安全性 ...
- CI框架入门
本人最近在学习CI框架,网上找到一些个人觉得入门比较好的资料,记录一下: 兄弟连的CI框架入门系类: [军哥谈CI框架]之入门教程之第一讲:codeigniter的介绍和安装配置:http://bbs ...
- 一看就懂的Mybatis框架入门笔记
本篇为初学Mybatis框架时的入门笔记,整理发出 Spring集成Mybatis https://www.cnblogs.com/yueshutong/p/9381590.html SpringBo ...
- 【转】最简单的CI框架入门示例--数据库取数据
1.下载CI框架(自己找) 2.配置 database.php配置: 为数据库服务器设置 connection 参数: $db['default']['hostname'] = "yo ...
- CI框架入门教程
1. URL常用的相关函数 url相关函数在辅助类url中第一,要使用它们必须先加载$this->load->helper('url')或者自动装载 site_url('控制器/方法 ...
- 最简单的CI框架入门示例--数据库取数据
前提: 安装好MySQL,Apache,PHP. 1.下载CI框架 下载地址 http://www.codeigniter.com/ 2.配置 database.php配置: 为数据库服务器设 ...
- CI框架入门2
文件目录与布局 1.user_guide 用户手册,可删 2.readme.rst 说明,可删 3.license.txt 证书,可删 4..gitignore composer. ...
- CI框架学习笔记
打印SQL语句$this->dbRead->last_query(); 重映射方法正如上文所说,URI 的第二段通常决定控制器的哪个方法被调用.CodeIgniter 允许你使用 _rem ...
- Express NodeJs Web框架 入门笔记
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具. 使用 Express 可以快速地搭建一个完整功能的网 ...
随机推荐
- 2018.10.27 洛谷P2915奶牛混合起来Mixed Up Cows(状压dp)
传送门 状压dp入门题. 按照题意建一个图. 要求的就是合法的链的总数. 直接f[i][j]f[i][j]f[i][j]表示当前状态为jjj,下一位要跟iii连起来的方案数. 然后从没被选并且跟iii ...
- dom4j 通过 org.dom4j.DocumentFactory 设置命名空间来支持 带namespace 的 xpath
测试文件 test.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:/ ...
- Servlet Life Cycle
Servlet Life Cycle http://docs.oracle.com/javaee/5/tutorial/doc/bnafi.html Servlet Filters and Event ...
- Eclipse环境下如何配置tomcat,并且把项目部署到Tomcat服务器上
打开Eclipse,单击“Window”菜单,选择下方的“Preferences”. 单击“Server”选项,选择下方的“Runtime Environments”. 点击“Add”添加Tomca ...
- $.contains(a,b)
jQuery.contains()函数用于判断指定元素内是否包含另一个元素. 简而言之,该函数用于判断另一个DOM元素是否是指定DOM元素的后代. 该函数属于全局jQuery对象. 语法 jQuery ...
- 属性动画和Activity、Fragment过渡动画等
主题是关于动画的,但是不是什么动画的内容都包括.先泛泛的介绍一下,然后详细的介绍一下翻代码找见的一个好玩的动画的使用.以下的内容包括Android 3和Android 3.1等引入的API,在使用中请 ...
- 20145232 韩文浩 《Java程序设计》第5周学习总结
教材学习内容总结 处理异常 教材中使用一个简单的程序,用户连续输入整数最后输入0结束后显示输入数的平均值. 但有时,用户会没有按常规出牌输入不正确的信息,例如"30"输成" ...
- JAVA作业之两数的加减乘除
1.设计思路 把输入的字符转化为计算的数字问题,再以对话框的形式输入输出加减乘除的结果问题. 2.程序流程图 3.源代码 4.实验结果
- 第86讲:Scala中For表达式的生成器、定义和过滤器
今天我们来看一下For表达式中的生成器,定义和过滤等内容. 让我们来看下代码 def main(args:Array[String]){ val lauren = Persons(" ...
- 卷积神经网络(CNN)之一维卷积、二维卷积、三维卷积详解
作者:szx_spark 由于计算机视觉的大红大紫,二维卷积的用处范围最广.因此本文首先介绍二维卷积,之后再介绍一维卷积与三维卷积的具体流程,并描述其各自的具体应用. 1. 二维卷积 图中的输入的数据 ...