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.phpCI_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框架入门笔记的更多相关文章

  1. CI框架入门1

    CI框架入门: 1.url的特点             2.目录结构/布局             3.MVC分别在哪里,如何依葫芦画瓢             4.安全性             ...

  2. CI框架入门

    本人最近在学习CI框架,网上找到一些个人觉得入门比较好的资料,记录一下: 兄弟连的CI框架入门系类: [军哥谈CI框架]之入门教程之第一讲:codeigniter的介绍和安装配置:http://bbs ...

  3. 一看就懂的Mybatis框架入门笔记

    本篇为初学Mybatis框架时的入门笔记,整理发出 Spring集成Mybatis https://www.cnblogs.com/yueshutong/p/9381590.html SpringBo ...

  4. 【转】最简单的CI框架入门示例--数据库取数据

    1.下载CI框架(自己找) 2.配置 database.php配置:    为数据库服务器设置 connection 参数: $db['default']['hostname'] = "yo ...

  5. CI框架入门教程

    1. URL常用的相关函数 url相关函数在辅助类url中第一,要使用它们必须先加载$this->load->helper('url')或者自动装载    site_url('控制器/方法 ...

  6. 最简单的CI框架入门示例--数据库取数据

    前提: 安装好MySQL,Apache,PHP. 1.下载CI框架 下载地址  http://www.codeigniter.com/ 2.配置 database.php配置:    为数据库服务器设 ...

  7. CI框架入门2

    文件目录与布局 1.user_guide    用户手册,可删 2.readme.rst    说明,可删 3.license.txt     证书,可删 4..gitignore composer. ...

  8. CI框架学习笔记

    打印SQL语句$this->dbRead->last_query(); 重映射方法正如上文所说,URI 的第二段通常决定控制器的哪个方法被调用.CodeIgniter 允许你使用 _rem ...

  9. Express NodeJs Web框架 入门笔记

    Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具. 使用 Express 可以快速地搭建一个完整功能的网 ...

随机推荐

  1. tp5内置验证规则

    验证规则 描述 require 必须验证 alpha 是否为字母 alphaNum 是否为字母和数字 alphaDash 是否为字母.数字,下划线_及破折号- number 是否为数字 integer ...

  2. ac自动机板子

    hdu2222 #include<bits/stdc++.h> #define ll long long #define M 500005 using namespace std; int ...

  3. Linux下启动tomcat报错,WARN org.apache.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect java.net.ConnectException:

    tomcat启动完了之后,一直不停的打印这种错误信息,看表面上,应该是zk节点下的数据是空的,连接不上服务,所以一直在尝试连接,然后一直又连不上: 完整的错误信息: 407662 [usf-ZooKe ...

  4. spring mvc项目中导出excel表格简单实现

    查阅了一些资料,才整理出spring mvc 项目导出excel表格的实现,其实很是简单,小计一下,方便以后查阅,也希望帮助有需要的朋友. 1.导入所需要依赖(Jar包).我使用的是maven,所以坐 ...

  5. matlab画无向图,基于坐标的无向图联系作者

    %函数名netplot %使用方法输入请help netplot %无返回值 %函数只能处理无向图 %作者:tiandsp %最后修改: function netplot(A,flag) %调用方法输 ...

  6. Arria10中的OCT功能

    OCT是什么? 串行(RS)和并行(RT) OCT 提供了 I/O 阻抗匹配和匹配性能.OCT 维持信号质量,节省电路板空 间,并降低外部组件成本. Arria 10 器件支持所有 FPGA 和 HP ...

  7. Linux(CentOS)下的apache服务器配置与管理

    原文链接:http://blog.csdn.net/ylqmf/article/details/5291680 一.WEB服务器与Apache1.web服务器与网址 2.Apache的历史 3.补充h ...

  8. canvas画的时钟

    结合几天来学习的canvas的API,终于完成了一个时钟呵呵 html <!doctype html> <html> <head> <meta charset ...

  9. 07-css的继承性和层叠性

    css有两大特性:继承性和层叠性 继承性 面向对象语言都会存在继承的概念,在面向对象语言中,继承的特点:继承了父类的属性和方法.那么我们现在主要研究css,css就是在设置属性的.不会牵扯到方法的层面 ...

  10. VC6.0编译器设置

    主要通过VC的菜单项Project->Settings->C/C++页来完成.我们可以看到这一页的最下面Project Options中的内容,一般如下:/nologo /MDd /W3 ...