(1)自动加载models——php5风格
使用这个技巧以后,我们将能够直接创建这个model对象。
这个代码是简洁的并且容易理解对象。
使用这个技巧以后会有2个影响。首先你不再需要继承model类了。
这个技巧
我们需要做的就是添加一个 php5 风格的 autolader 函数
添加这些代码到 system/application/config/config.php:
<?php
// ...
function __autoload($class) {
if (file_exists(APPPATH."models/".strtolower($class).EXT)) {
include_once(APPPATH."models/".strtolower($class).EXT);
}
}
?>
如果你也有兴趣运用这个技巧到 controller ,你只需要添加以下代码来代替上面的代码。
<?php
// ...
function __autoload($class) {
if (file_exists(APPPATH."models/".strtolower($class).EXT)) {
include_once(APPPATH."models/".strtolower($class).EXT);
} else if (file_exists(APPPATH."controllers/".strtolower($class).EXT)) {
include_once(APPPATH."controllers/".strtolower($class).EXT);
}
}
?>
任何时候,你试着使用一个没有定义的类 时候,这个 __autoload 函数将会被调用,它将会加载这个类文件。
(2)防止model-controller名字冲突
使用这个技巧要达到的目标:
一般来说,模型和控制器你都不会有相同的类名字。让我先创建一个取名为 post 的 model 。
class Post extends Model {
// ...
}
现在你就不能有一个像这样的 url :
http://HdhCmsTestmysite测试数据/post/display/13
这个原因是因为你也需要有一个名字为 post 的 controller ,如果创建了这样的一个类的话将会引起致命错误。
但是使用了这个技巧一般,一切皆有可能。那个 url 的控制器看起来是这样的:
// application/controllers/post.php
class Post_controller extends Controller {
// ...
}
注意这个[ __controller ]后缀
技巧:
为了避免这个问题,通常大多数人都是添加‘ _model ’后缀到 model 名字(例如命名 Post_model )。
在所有的应用 程序 中 Model 对象都被创建和引用,所以在所有的 model 名字后面跟上‘ _model ’有些无聊。
我认为最好的 办法 就是在 controller 上来添加后缀,因为在代码中 controller 的名字几乎从来不会被引用。
首先我们需要继承 Router class 。创建这样一个文件: "application/libraries/MY_Router.php"
class MY_Router extends CI_Router {
var $suffix = '_controller';
function MY_Router() {
parent::CI_Router();
}
function set_class($class) {
$this->class = $class . $this->suffix;
}
function controller_name() {
if (strstr($this->class, $this->suffix)) {
return str_replace($this->suffix, '', $this->class);
}
else {
return $this->class;
}
}
}
现在编辑 "system/codeigniter/CodeIgniter.php"
第 153 行
if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->controller_name().EXT))
然后第 158 行
include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->controller_name().EXT);
然后编辑 "system/libraries/Profiler.php" 的第 323 行
$output .= "< div style="color:#995300;font-weight:normal;padding:4px 0 4px 0">".$this->CI->router->controller_name()."/".$this->CI->router->fetch_method()."</div>";
大功告成。使用这个技巧一定需要记住的是要把‘ _controller ’后缀放到你的 controller 的类的名字后面,不是放在你的控制器文件名中。
(3)表单 验证 [唯一值](如注册用户名email)
Ci 有一个完美的表单验证类。但是这个验证有一点不足,例如当大部分用户注册用户名的时候,需要验证用户名没有被占用,或者邮箱是否存在在 系统 中。
使用这个技巧,你将能够非常容易添加这项验证规则到你的表单提交中。
注意最后一部分 "unique[User.username]." 这个新的验证规则叫做[ unique ],并且带了一个方框在这个中括号中,它们是[ tablename.filedname ] . 所以它将会检测 数据库 的[ user ] 数据 表的[ username ]列确定提交的值在数据库里面不存在。
同理,你也能利用这个规则验证相同的邮件地址。
$this->form_validation->set_rules('email', 'E-mail',
'required|valid_email|unique[User.email]');
你的应用程序将会得到以下错误信息
与其说这是一个技巧而不如说是一个扩展。虽然如此,我们将要添加一个核心 ci 类库并且改善它。
创建 "application/libraries/MY_Form_validation.php"文件
class MY_Form_validation extends CI_Form_validation {
function unique($value, $params) {
$CI =& get_instance();
$CI->load->database();
$CI->form_validation->set_message('unique',
'The %s is already being used.');
list($table, $field) = explode(".", $params, 2);
$query = $CI->db->select($field)->from($table)
->where($field, $value)->limit(1)->get();
if ($query->row()) {
return false;
} else {
return true;
}
}
}
现在你就能使用这个[唯一]验证规则了。
(4)从命令行运行codeignite r
目标:
就像这个标题所说,我们的目标是能够从命令行运行 ci 。对于创建定时任务,这个是必须的,或者是运行更多的特别的操作,
所以你没有 web 脚本的资源限制,就像最大执行 时间 一样。
这就是本地 windows 机器上面运行的效果
技巧
创建一个[ cli.php ]文件在 ci 的根目录(即与 index.php 在同一目录)
if (isset($_SERVER['REMOTE_ADDR'])) {
die('Command Line Only!');
}
set_time_limit(0);
$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'] = $argv[1];
require dirname(__FILE__) . '/index.php';
如果你在 linux 环境下使用,并且想要让这代码自动执行,你能添加以下代码在 cli.php 文件的第一行
#!/usr/bin/php
如果你需要一个仅仅能在命令行下使用的控制器,你能阻止 web 调用控制器构造函数
class Hello extends Controller {
function __construct() {
if (isset($_SERVER['REMOTE_ADDR'])) {
die('Command Line Only!');
}
parent::Controller();
}
// ...
}
(5)添加Doctrine orm 到codeigniter
(Doctrine orm是一个比较复杂的东西,我们将会继续出一些相关 教程 )
目标
Doctine 是一个流行的 php 的关系对象映射( orm )。添加它到 ci 里面以后,你将会一个更加强大的模型层。
技巧:
其实安装 Doctrine 不是那么难,就像安装插件一样。然后一旦安装成功,你的 model 类将需要继承 Doctrine 基类,而不是继承 ci 的 model 类。这将会完全改变 model 层的工作方式。你建立的对象将会有持久的数据库连接并且也将能有其他对象的数据库关系。
按照以下几步:
1. 建立文件夹: application/plugins
2. 创建文件夹: application/plugins/doctrine
3. 下载文件( 1.2 版本的)
4. 从 Doctrine 复制[ lib ]文件夹到[ application/plugins/doctrine ]
5. 创建[ application/plugins/doctrine_pi.php ]
// system/application/plugins/doctrine_pi.php
// load Doctrine library
require_once APPPATH.'/plugins/doctrine/lib/Doctrine.php';
// load database configuration from CodeIgniter
require_once APPPATH.'/config/database.php';
// this will allow Doctrine to load Model classes automatically
spl_autoload_register(array('Doctrine', 'autoload'));
// we load our database connections into Doctrine_Manager
// this loop allows us to use multiple connections later on
foreach ($db as $connection_name => $db_values) {
// first we must convert to dsn format
$dsn = $db[$connection_name]['dbdriver'] .
'://' . $db[$connection_name]['username'] .
':' . $db[$connection_name]['password'].
'@' . $db[$connection_name]['hostname'] .
'/' . $db[$connection_name]['database'];
Doctrine_Manager::connection($dsn,$connection_name);
}
// CodeIgniter's Model class needs to be loaded
require_once BASEPATH.'/libraries/Model.php';
// telling Doctrine where our models are located
Doctrine::loadModels(APPPATH.'/models');
然后,编辑‘ application/config/autoload.php ’自动加载 Doctrine 插件
$autoload['plugin'] = array('doctrine');
你也要确定在[ application/config/database.php 的数据库配置好了,]
就这样,现在你就能使用 ci 应用程序创建 Doctrine 模型了。阅读更多的资源在 这里 。
(6)运行多个站点
目标:
这个技巧将会使安装一个 codeigniter 就能运行多个站点成为可能,每个站点有它自己的 application 文件夹,但是他们共享这相同的系统文件夹。
安装 ci 在 服务器 的任何位置。然后将 application 文件夹从 system 文件夹拿出来。放在外面,请看上面的图片。
现在复制 index.php 文件到每个站点的跟目录下面(即图中的 application_site1 、 application_site2 等)
然后编辑它:
在第 26 行,给出 system 文件夹的完整路径
$system_folder = dirname( __FILE__ ) . 'codeigniter/system' ;
在第 43 行,给出 application 文件夹的文章路径
$application_folder = dirname( __FILE__ ) . 'application_site1' ;
现在你就能使用独立的 application 文件夹来建立不同的站点了,而只是共享同一个 system 文件夹
这里有一个相似的操作在 ci用户手册
(7)允许所有类型的文件上传
目标:
当使用 ci 的上传类的时候,你必须指明哪些文件类型允许上传。
$this->load->library('upload'); $this->upload->set_allowed_types('jpg|jpeg|gif|png|zip');
如果你没有指明特定的上传类型,你将会从 ci 那里得到一个错误信息 "Youhave not specified any allowed file types."
所有,默认的方式,将没有办法允许所有的文件上传。我们需要做一些小的改变来处理这个限制。我们设定[ * ]将能够运行所有类型的文件上传。
$this->load->library('upload'); $this->upload->set_allowed_types('*');
技巧:
我们需要修改上传文件类。
创建文件: application/librarys/My_upload.php
class MY_Upload extends CI_Upload {
function is_allowed_filetype() {
if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
{
$this->set_error('upload_no_file_types');
return FALSE;
}
if (in_array("*", $this->allowed_types))
{
return TRUE;
}
$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
foreach ($this->allowed_types as $val)
{
$mime = $this->mimes_types(strtolower($val));
// Images get some additional checks
if (in_array($val, $image_types))
{
if (getimagesize($this->file_temp) === FALSE)
{
return FALSE;
}
}
if (is_array($mime))
{
if (in_array($this->file_type, $mime, TRUE))
{
return TRUE;
}
}
else
{
if ($mime == $this->file_type)
{
return TRUE;
}
}
}
return FALSE;
}
}
查看更多关于codeigniter框架开发技巧的详细内容...