CodeIgniter框架深入理解
.
CodeIgniter框架深入理解
1.CodeIgniter是一个小巧但功能强大的 PHP 框架,作为一个简单而“优雅”的工具包,它可以为 PHP 程序员建立功能完善的 Web 应用程序。如果你是一个使用共享主机,并 且为客户所要求的期限而烦恼的开发人员,如果你已经厌倦了那些傻大笨粗的框架那么 CodeIgniter 就是你所需要的。CodeIgniter 是一个基于MVC框架的PHP开源轻量级框架 ,适合快速开发,相对与Zend Freamwork,其更容易学习和应用,而且CodeIgniter 入门简单,配置方便
2.对于标准的MVC框架来说,Model(模型) 是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据; View(视图) 是应用程序中处理数据显 示的部分也就是用户能够看到的界面,通常视图是依据模型数据创建的;Controller(控制器)是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用 户输入,并向模型发送数据,最后,将模型返回的数据发送给视图,显示在界面上。
Controller层往往是程序的入口(网页的地址就是 Controller层的地址 ) ,然后由 Controller层加载 View层进行显示(显示在浏览器上的页面 其实并不是你输入的地 址),在View层用户通过表单实现交互,表单将数据传回 Controller层,由 Controller层调用Model层进行数据处理、存储、读取等操作,然后Model 层将处理结果返回 给 Controller层, Controller层再次加载View层显示处理的结果
3.配置CI开发环境
(1)在开发工具中创建工程目录ci(名字随便),把CodeIniter压缩包解压后的所有文件(不复制根目录)再复制到eclipse中的工程ci中
使用文本编辑器打开 application/config/config.php 文件设置你网站的根 URL,如果你想使用加密或会话,在这里设置上你的加密密钥;
如果你想通过隐藏 CodeIgniter 的文件位置来增加安全性,你可以将 system 和 application 目录修改为其他的名字,然后打开主目录下的 index.php 文件将 $system_path 和 $application_folder 两个变量设置为你修改的名字。
(2)为更好的安全性,system 和 application 目录都应该放置在 Web 根目录之外,这样它们就不能通过浏览器直接访问。CodeIgniter 默认在每个目录下都包含了一个 .htaccess 文件,用于阻止直接访问,但是最好还是将它们移出能公开访问的地方,防止出现 Web 服务器配置更改或者 .htaccess 文件不被支持这些情况。
(3)配置数据库文件。在application\config\database.php中,一般修改以下内容
'dsn' => 'mysql:host=localhost;dbname=ci',//'hostname' => 'localhost',用pdo时注释掉,下同//'database' => 'ci','username' => 'root','password' => '','dbdriver' => 'pdo',//默认数据库驱动是mysqli,一般改为pdo对象操作数据库
(4)在config.php中设置默认地址$config[‘base_url’] = ‘http://localhost/CodeIgniter/’;
(5)路由配置在applicaiton\config\routes.php中,
$route[‘default_controller’] = ‘welcome’;//可以修改
4.编写控制器方法和静态页面
例子http://example.com/news/latest/10 有一个叫做 “news” 的控制器,被调用的方法为 “latest” , 这个方法的作用应该是查询 10 条新闻条目并显示在页面上
新建一个文件 application/controllers/Pages.php ,然后添加一个view方法
<?php
class Pages extends CI_Controller {
public function view(KaTeX parse error: Expected '}', got 'EOF' at end of input: …/views/pages/'.page.’.php’)){
show_404();
}
$data['title'] = ucfirst($page);$this->load->view('tempates/header', $data);$this->load->view('pages/'.$page, $data);$this->load->view('tempates/footer', $data);//view() 方法的第二个参数用于向视图传递参数,$data 数组中的每一项将被赋值给一个变量
}}
新建两个视图(页面模板)分别作为我们的页脚和页头
新建页头文件 application/views/templates/header.php 并添加以下代码:
<h1><?php echo $title; ?></h1>
新建页脚文件application/views/templates/footer.php ,然后添加以下代码:
© 2015
解释: 标签告诉浏览器把其中的文本表示为强调的内容。对于所有浏览器来说,这意味着要把这段文字用斜体来显示。
静态页面模板位于 application/views/pages/ 目录,在该目录中,再新建两个文件 home.php 和 about.php 内容随便写其中之一比如
<p>Let's start to study CodeIniter now!</p></body>
</html>
5.测试页面
控制器现在开始工作了!在你的浏览器中输入 http://localhost/CodeIgniter/index.php/pages/view来查看你的页面。当你访问 在view后面加上/about 时你将看到about 页面,包括页头和页脚。
如果不行有进可以在地址的index.php后加上?,如果提示404错误可能是控制器或页面文件里的文件名或位置错误
6.可以隐藏入口文件index.php,在url总中显示入口文件不太美观,如果要隐藏可以进行如下设置(路由配置文件中也能更方便的设置隐藏)。
(1)服务器配置文件http.conf中开启重写
LoadModule rewrite_module modules/mod_rewrite.so
这条前面不可有#,如果没有这条加上即可
(2)在网站根目录下新建文件.htaccess,属于隐藏文件,可新建文件后另存为时修改名字,
7.创建数据库模型
打开 application/models/ 目录,新建一个文件 News_model.php ,然后写入下面的代码。 确保你的 数据库配置正确
<?php echo $title; ?>
<?php foreach ($news as $news_item): ?><h3><?php echo $news_item['title']; ?></h3>
<div class="main"><?php echo $news_item['text']; ?>
</div>
<p><a href="<?php echo site_url('news/'.$news_item['slug']); ?>">View article</a></p><?php endforeach; ?>剩下的事是创建视图文件 application/views/news/view.php 并添加如下代码 。<?php
echo '<h2>'.$news_item['title'].'</h2>';
echo $news_item['text'];?>创建路由就可以访问了 注意__construct()函数的下划线是长的否则报错还有php标识后面的?>在ci中可以不写
可以不注释前面的路由照样有效,访问成功!$route['news/(:any)'] = 'news/view/$1';
$route['news'] = 'news';
$route['(:any)'] = 'pages/view/$1';
$route['default_controller'] = 'pages/view';
11.用表单写入数据,在文件 application/views/news/create.php 中创建一个新视图。
<?php echo $title; ?>
<?php echo validation_errors(); ?> <?php echo form_open('news/create'); ?><label for="title">Title</label>
<input type="input" name="title" /><br /><label for="text">Text</label>
<textarea name="text"></textarea><br /><input type="submit" name="submit" value="Create news item" />
回到你的 News 控制器
public function create()
{
$this->load->helper(‘form’);
$this->load->library(‘form_validation’);
$data['title'] = 'Create a news item';$this->form_validation->set_rules('title', 'Title', 'required');
$this->form_validation->set_rules('text', 'Text', 'required');if ($this->form_validation->run() === FALSE)
{$this->load->view('templates/header', $data);$this->load->view('news/create');$this->load->view('templates/footer');}
else
{$this->news_model->set_news();$this->load->view('news/success');
}
}
建一个视图文件 application/views/news/success.php 并写上成功的信息
<?php echo "create success!"; ?>
向数据库中插入数据。打开之前创建的模型文件,添加以下代码:
public function set_news()
{
$this->load->helper(‘url’);
$slug = url_title($this->input->post('title'), 'dash', TRUE);$data = array('title' => $this->input->post('title'),'slug' => $slug,'text' => $this->input->post('text')
);return $this->db->insert('news', $data);
}
到 config/routes.php 文件中去添加一条新的路由规则
$route[‘news/create’] = ‘news/create’;
$route[‘news/(:any)’] = ‘news/view/$1’;
$route[‘news’] = ‘news’;
$route[’(:any)’] = ‘pages/view/$1’;
$route[‘default_controller’] = ‘pages/view’;
12.用控制器接收多个参数
创建控制器
<?php
class Products extends CI_Controller {
public function shoes($sandals, $id)
{
echo $sandals;
echo $id;
}
}
测试 shoes方法将会收到两个参数(“sandals” 和 “123”):
http://localhost/CodeIgniter/index.php/Products/shoes/sandals/123
13.控制器的注意事项
如果你的控制包含一个_remap() 方法,那么无论 URI 中包含什么参数时都会调用该方法。 它允许你定义你自己的路由规则,重写默认的使用 URI 中的分段来决定调用哪个方法这种行为。
如果你的控制器含有一个 _output() 方法,输出类将会调用该方法来显示数据, 而不是直接显示数据。该方法的第一个参数包含了最终输出的数据。
类名和方法名都不要跟父类的相同,你的控制器将继承主程序的控制器,在新建方法时你必须要小心不要使用和父类一样的方法名, 要不然你的方法将覆盖它们
14.用数组和循环来显示页面
创建控制器Blog
</head>
<body>
<h1><?php echo $heading;?></h1>
<h3>My Todo List</h3><ul>
<?php foreach ($todo_list as $item):?><li><?php echo $item;?></li><?php endforeach;?>
</ul>
</body>
</html>
15.在视图文件中使用PHP替代语法?
Echo 替代语法?
通常情况,你会使用下面的方法来打印一个变量:
<?php echo $variable; ?>使用替代语法,你可以写成这样:
<?=$variable?>控制结构的替代语法?
像 if、for、foreach、while 这样的控制结构也可以写成精简的格式。 下面以 foreach 举例:
<li><?=$item?></li>
<?php endforeach; ?>
注意这里没有任何括号。所有的结束括号被替换成了 endforeach 。 上面说的那些控制结构也都有这相似的结束标志:endif 、 endfor 、 endforeach 和 endwhile 。
ul是定义无序列表的样式,显示时前面只有圆点, ol是有序列表显示时前面有序号
li是列表内行的样式
在HTML代码中列表是这样的
- 列表一
- 列表二
- …
16.加载视图方法有一个可选的第三个参数可以让你修改它的默认行为,它让视图作为字符串返回 而不是显示到浏览器中
$string = $this->load->view(‘myfile’, ‘’, TRUE);
模型需要在整个应用程序中使用,你可以让 CodeIgniter 在系统初始化时自动加载它。打开 application/config/autoload.php 文件, 并将该模型添加到 autoload 数组中。
17.连接数据库?
当模型加载之后,它 并不会 自动去连接你的数据库,下面是一些关于 数据库连接的选项:
你可以在控制器或模型中使用 标准的数据库方法 连接数据库。
你可以设置第三个参数为 TRUE 让模型在加载时自动连接数据库,会使用你的数据库配置文件中的配置:
$this->load->model(‘model_name’, ‘’, TRUE);
18.加载辅助函数?
可以使用下面的方法简单的加载辅助函数:
要加载 URL 辅助函数 ,它的文件名为 url_helper.php ,你可以这样加载它:
$this->load->helper(‘url’);
如果你需要加载多个辅助函数,你可以使用一个数组,像下面这样:
$this->load->helper(
array(‘helper1’, ‘helper2’, ‘helper3’)
);
自动加载辅助函数同上自动加载模型
19.所有的系统类库都位于 system/libraries/ 目录下,大多数情况下,在使用之前, 你要先在 控制器 中初始化它,使用下面的方法:
$this->load->library(‘class_name’);
在加载类库的时候,你可以通过第二个参数动态的传递一个数组数据,该数组将被传到你的类的构造函数中,如果你使用了该功能,你必须在定义类的构造函数时加上参数
你也可以将参数保存在配置文件中来传递,只需简单的创建一个和类文件同名的配置文件
20.在你的类库中使用 CodeIgniter 资源?
在你的类库中使用 get_instance() 函数来访问 CodeIgniter 的原生资源,这个函数返回 CodeIgniter 超级对象。
通常情况下,在你的控制器方法中你会使用 $this 来调用所有可用的 CodeIgniter 方法:
$this->load->helper(‘url’);
$this->load->library(‘session’);
$this->config->item(‘base_url’);
但是 $this 只能在你的控制器、模型或视图中直接使用,如果你想在你自己的类中使用 CodeIgniter 类,你可以像下面这样做:
首先,将 CodeIgniter 对象赋值给一个变量:
$CI =& get_instance();
一旦你把 CodeIgniter 对象赋值给一个变量之后,你就可以使用这个变量来 代替 $this
$CI =& get_instance(); //这是非常重要的,引用赋值允许你使用原始的 CodeIgniter 对象,而不是创建一个副本
$CI->load->helper(‘url’);
$CI->load->library(‘session’);
$CI->config->item(‘base_url’);
既然类库是一个类,那么我们最好充分的使用 OOP 原则,所以,为了让类中的所有方法都能使用 CodeIgniter 超级对象,建议将其赋值给一个属性:
class Example_library {
protected $CI;
public function __construct()
{
// Assign the CodeIgniter super-object
$this->CI =& get_instance();
}
21.使用你自己的类库替换原生类库?
将你的类文件名改为和原生的类库文件一致,CodeIgniter 就会使用它替换掉原生的类库
要加载你的类库,和标准的方法一样,注意数据库类不能被你自己的类替换掉。
扩展原生类库?
类在定义时必须继承自父类。
你的新类名和文件名必须以 MY_ 为前缀(这个可配置,见下文)
要扩展原生的 Email 类你需要新建一个文件命名为 application/libraries/MY_Email.php , 然后定义你的类:
class MY_Email extends CI_Email {
}
如果你需要在你的类中使用构造函数,确保你调用了父类的构造函数 parent::__construct($config);
22.使用 CodeIgniter 驱动器?
驱动器是一种特殊类型的类库,它有一个父类和任意多个子类。子类可以访问父类,但不能访问兄弟类。在你的控制器中,驱动器为你的类库提供了一种优雅的语法,从而不用将它们拆成很多离散的类。
驱动器位于 system/libraries/ 目录,每个驱动器都有一个独立的目录,目录名和 驱动器父类的类名一致,在该目录下还有一个子目录,命名为 drivers,用于存放 所有子类的文件。
要使用一个驱动器,你可以在控制器中使用下面的方法来进行初始化:
$this->load->driver(‘class_name’);
class_name 是你想要调用的驱动器类名,例如,你要加载名为 Some_parent 的驱动器, 可以这样:
$this->load->driver(‘some_parent’);
然后就可以像下面这样调用该类的方法:
$this->some_parent->some_method();
而对于那些子类,我们不用初始化,可以直接通过父类调用了:
$this->some_parent->child_one->some_method();
$this->some_parent->child_two->another_method();
23.钩子 - 扩展框架核心?
CodeIgniter的钩子特性提供了一种方法来修改框架的内部运作流程,而无需修改 核心文件。
启用钩子?
钩子特性可以在 application/config/config.php 文件中全局的启用或禁用, 设置下面这个参数:
$config[‘enable_hooks’] = TRUE;
定义钩子?
钩子是在 application/config/hooks.php 文件中被定义的,每个钩子可以定义 为下面这样的数组格式:
$hook[‘pre_controller’] = array(
‘class’ => ‘MyClass’,
‘function’ => ‘Myfunction’,
‘filename’ => ‘Myclass.php’,
‘filepath’ => ‘hooks’,
‘params’ => array(‘beer’, ‘wine’, ‘snacks’)
);
数组的索引为你想使用的挂钩点名称,例如上例中挂钩点为 pre_controller ,function 你希望调用的方法或函数的名称。
如果你使用 PHP 5.3 以上的版本,你也可以使用 lambda表达式(匿名函数或闭包)作为钩子, 这样语法更简单:
$hook[‘post_controller’] = function()
{
/* do something here */
};
24.公共函数?
CodeIgniter 定义了一些全局的函数,你可以在任何地方使用它们,并且不需要加载任何 类库或辅助函数。
is_php( v e r s i o n ) ? 判 断 当 前 运 行 的 P H P 版 本 是 否 高 于 或 等 于 你 提 供 的 版 本 号 i s r e a l l y w r i t a b l e ( version)?判断当前运行的 PHP 版本是否高于或等于你提供的版本号 is_really_writable( version)?判断当前运行的PHP版本是否高于或等于你提供的版本号isreallywritable(file)?
config_item( k e y ) ? 访 问 单 个 配 置 项 r e m o v e i n v i s i b l e c h a r a c t e r s ( key)?访问单个配置项 remove_invisible_characters( key)?访问单个配置项removeinvisiblecharacters(str[, u r l e n c o d e d = T R U E ] ) ? 这 个 函 数 去 掉 A S C I I 字 符 串 中 插 入 的 空 字 符 h t m l e s c a p e ( url_encoded = TRUE])?这个函数去掉ASCII字符串中插入的空字符 html_escape( urlencoded=TRUE])?这个函数去掉ASCII字符串中插入的空字符htmlescape(var)?访问单个配置项这个函数类似于 PHP 原生的 htmlspecialchars() 函数,只是它除了可以接受字符串参数外,还可以接受数组参数
25.设置你自己的路由规则?
路由规则将按照它们定义的顺序执行,前面的规则优先级高于后面的规则。
路由规则定义在 application/config/routes.php 文件中,在这个文件中你会 发现一个名为 $route 的数组,
利用它你可以设置你自己的路由规则。 在路由规则中你可以使用通配符或正则表达式。
通配符一个典型的使用通配符的路由规则如下:
$route[‘product/:num’] = ‘catalog/product_lookup’;
在一个路由规则中,数组的键表示要匹配的 URI ,而数组的值表示要重定向的位置。 上面的例子中,如果 URL 的第一段是字符串 “product” ,第二段是个数字,
那么, 将调用 “catalog” 类的 “product_lookup” 方法。
你可以使用纯字符串匹配,或者使用下面两种通配符:(:num) 匹配只含有数字的一段。 (:any) 匹配含有任意字符的一段。(除了 ‘/’ 字符,因为它是段与段之间的分隔符)
route[‘journals’] = ‘blogs’; URL 的第一段是单词 “journals” 时,将重定向到 “blogs” 类。
$route[‘blog/joe’] = ‘blogs/users/34’; URL 包含 blog/joe 的话,将重定向到 “blogs” 类和 “users” 方法。ID 参数设为 “34” 。
$route[‘product/(:any)’] = ‘catalog/product_lookup’;URL 的第一段是 “product” 第二段是任意字符时,将重定向到 “catalog” 类的 “product_lookup” 方法。
$route[‘product/(:num)’] = ‘catalog/product_lookup_by_id/$1’;URL 的第一段是"product",第二段是数字时,将重定向到"catalog"类的"product_lookup_by_id"方法,并将参数传递给它。
你可以在路由规则中使用正则表达式。任何有效的正则表达式都是 允许的,包括逆向引用。
$route[‘products/([a-z]+)/(\d+)’] = ‘$1/id_$2’;
上例中,一个类似于 products/shirts/123 这样的 URL 将会重定向到 “shirts” 控制器的 “id_123” 方法
在路由中使用 HTTP 动词,可以使用标准的 HTTP 动词(GET、PUT、POST、DELETE、PATCH),
$route[‘products’][‘put’] = ‘product/insert’;
上例中,当发送 PUT 请求到 “products” 这个 URI 时,将会调用 Product::insert() 方法。
$route[‘404_override’] = ‘’; 这个路由表示当用户请求了一个不存在的页面时该加载哪个控制器,它将会覆盖默认的 404 错误页面。
保留的路由规则必须位于任何一般的通配符或正则路由的前面。