标签CodeIgniter下的文章

Jerry Bendy 发布于 09月25, 2014

CodeIgniter在IIS、Apache、SAE和NginX上的伪静态设置方法

CodeIginter是一个很不错的轻量级PHP框架,文档也比较全面。关于CI去除“index.php”的伪静态设置在官方的文档中却只提及了一点,而且给出的方法对于静态文件还会出现错误。

以下的内容并非是原创,而是整理了CI在不同服务器下的伪静态设置方法放在一起,供有需要的朋友复制、使用。

Apache服务器

Apache服务在打开URLRewrite模块后使用.htaceess文件处理伪静态规则。使用方法很简单,在网站根目录创建一个文本文件并命名为.htaccess,复制下面的内容进去保存就好了。(Windows的电脑上不允许这种以点号开头的文件,不过可以使用命令提示符重命名,或者先随便用什么名字,上传到服务器后再改回成.htaccess)。

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]

IIS服务器

IIS从IIS7版本开始开始使用新的URLRewrite机制,并使用web.config文件处理伪静态规则,IIS7以上版本URLRewrite插件的安装及.htaccess文件转web.config的方法请参见我的另一篇博文《IIS 7及IIS 7.5下面.htaccess转为web.config的方法》,另外贴出一份转换好的文件。在网站根目录创建文本文件并命名为web.config,把以下内容复制进去即可:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="CodeIginiterRewrite" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                        <add input="{R:1}" pattern="^(index\.php|images|robots\.txt)" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/index.php/{R:1}" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

NginX服务器

NginX是一个轻量级的WEB服务器,具有高并发等优势,NginX的配置可能会有些麻烦,在path_info开启的情况下修改nginx.conf文件,在对应网站的server段加入以下内容:

location / {
    if (!-e $request_filename) {
        rewrite ^/(.+)$ /index.php/$1 last;
    }
}

SAE新浪云服务

SAE有专为SAE修改的CI版本可用,对应的伪静态文件也一起贴出来吧。SAE需要在网站根目录下建立config.yaml文件,并输入以下内容:

handle:
- compress:  if ( out_header["Content-type"]=="text/css" ) compress
- compress:  if ( out_header["Content-type"]=="text/javascript" ) compress
- compress:  if ( out_header["Content-type"]=="application/javascript" ) compress
- rewrite: if(!is_dir() &amp;&amp; !is_file() &amp;&amp; path~"/") goto "/index.php/%{QUERY_STRING}"

如果文件中已有“handle”段可以在后面追加这部分内容。代码中的三行以“compress”结尾的内容是静态文件压缩,不使用压缩的话可以删除它们。

阅读全文 »

Jerry Bendy 发布于 09月18, 2014

CodeIgniter表单验证类报错:Unable to access an error message corresponding to your field name.

在使用CodeIgniter(CI)框架中的表单验证类做用户登录时,发现了一个出错信息:

ci_unable_access_an_error

查看源代码发现并没有与其相关的说明,而且语言文件中也没有对这句话的翻译,最终在N次测试后发现问题出现在了对密码验证的回调函数上:

//.......
$this->form_validation->set_rules('password', '密码', 'trim|required|min_length[5]|max_length[30]|callback_pword_check');

//........

/**
 * 用户名及密码有效性验证回调函数
 */
function pword_check($pword){
    $uname = $this->input->post('username');
    $ret =  $this->user_model->login_user($uname, $pword);  //此模块函数完成对密码有效性的验证

    if ($ret) {
        return TRUE;
    } else {
        $this->form_validation->set_message('密码', '用户名或%s错误');
        return FALSE;
    }
}

再次查阅CI的文档发现有句没被翻译的内容大致是说“在上面回调的例子中, 错误信息是通过传送回调函数的名称来返回的”,也就是说set_message函数的第一个参数应该是对应回调函数的函数名。

$this->form_validation->set_message('pword_check', '用户名或%s错误');

OK,错误消失~~

现在知道了,set_message如果是在回调函数使用的话,第一个参数应该是对应的回调函数的函数名称。

阅读全文 »

Jerry Bendy 发布于 01月09, 2014

CI获取当前连接数据库信息的方法

用过CI(CodeIgnter)的都知道CI有一个内置的Config系统,用来获取设置项,但这个设置只对 $config['xxx']这样的操作有效,对数据库是无效的。在数据库操作中为了使程序更具灵活性往往会给数据表设置一个前缀,如“wp_”,为了程序的扩展性我们不可能在SQL中把数据表前缀写死,CI的数据库选项有这样一行:

$db['default']['dbprefix'] = 'test_';

因为不是$config['xxx']这样的变量,再使用 $this->config->item('dbprefix');这样的形式就无法取得前缀,查阅CI的文档也没找到解决方法。无奈只得翻看源代码。

在“system/database/DB_dirver.php”中可以发现里面好多和数据库相关的变量都是用“var”定义的,“var”和“public”相同,就意味着可以直接从外部读取甚至修改这些变量,于是乎解决了以上问题:

echo $this->db->dbprefix;  //数据表前缀
echo $this->db->database;  //数据表名
echo $this->db->query_count; //查询次数
// ……

阅读全文 »

Jerry Bendy 发布于 11月12, 2013

CodeIgniter中对同一个核心类的多次扩展

CodeIgniter提供了对核心类进行扩展的方法,默认情况下是添加MY_前缀(当然这个前缀是可以改的),但是很多情况下我们可能需要对同一个核心类多次扩展,例如:我们可能需要在网站的所有后台管理页面的开头加上用户身份认证的代码,当后台有多个文件时就相当于有多个入口,而我们却不得不对每个控制器类文件的构造函数中添加身份认证的代码,很显然这样不利用代码的重用,而且不易于维护。

还好,CI提供了扩展核心类的方法,这就意味着我们可以通过在Application/core中创建一个“MY_Controller”文件来扩展Controller类,然后在这个类的构造函数中进行身份认证,管理部分的控制器只需要继承自这个类就可以了。

问题是网站上不可能只有管理员,还需要在前台页面对用户的身份加以认证,可以再扩展一个Controller类吗?例如一个MY_Controller,一个MY_Admin_Controller?答案是否定的,“System/Core/Codeigniter.php”中有这样一段代码 :

if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller'.EXT))
{
    require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller'.EXT;
}

就是说CI只会查找MY_Controller文件,别的文件不会被加载,如此一来该如何对默认的Controller类进行多次扩展呢?

有一个取巧的方法:既然CI的启动的时候会加载MY_Controller这个类,当然就是加载了“MY_Controller.php”这个文件,既然整个文件都加载了,理论上即使这个文件中包含多个类也会同时被加载,呵呵。方法很简单,就是在“MY_Controller.php”这个文件中写两个类,我试过,这样确实可行,只要你在继承的时候别继承错父类就可以了。

如果非想一个文件一个类的话依据上面的方法也可以,就是在“MY_Controller.php”的开头加上“ require_once(dirname(FILE) . '/' . 'admin_controller.php');”即可。

还有另一个方法,是我在博客园上看到的,就是只使用这一个扩展核心类,只是在这个扩展的类的构造函数中去判断网址的段,代码如下:

class MY_Controller extends CI_Controller {
    function __construct(){
        parent::__construct();
        if( $this->uri->segment(1) === 'admin' ){
               ...
        }
    }
}

 

阅读全文 »