用户
 找回密码
 入住 CI 中国社区
搜索
12
返回列表 发新帖
楼主: yezihack
收起左侧

[版本 2.x] 关于ci框架里用魔术方法(__call())

  [复制链接]
 楼主| 发表于 2011-11-3 10:05:49 | 显示全部楼层
如果 在Test类加入构造函数
class Test extends CI_Controller{
function __construct(){
    $params=$this->uri->uri_to_assoc();
    print_r($params);
}
http://localhost/ci/test/id/1
显示为: Array ( [id] => 1 )
  不过还显示了404错误页
现在问题是如何出错不显示404.这个错误页在哪里被调用?
}
发表于 2012-2-9 11:25:34 | 显示全部楼层
/syetem/core/CodeIgniter.php
里面被这样定义了:
        $class  = $RTR->fetch_class();
        $method = $RTR->fetch_method();

        if ( ! class_exists($class)
                OR strncmp($method, '_', 1) == 0
                OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
                )
        {
                if ( ! empty($RTR->routes['404_override']))
                {
                        $x = explode('/', $RTR->routes['404_override']);
                        $class = $x[0];
                        $method = (isset($x[1]) ? $x[1] : 'index');
                        if ( ! class_exists($class))
                        {
                                if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
                                {
                                        show_404("{$class}/{$method}");
                                }

                                include_once(APPPATH.'controllers/'.$class.'.php');
                        }
                }
                else
                {
                        show_404("{$class}/{$method}");
                }
        }

应该是遍历一下class里面有没这个方法,没有就直接404了
很无耐,但是又不敢改这里
发表于 2012-2-9 13:46:11 | 显示全部楼层
这个和魔术方法没关系,CI 会先检查你的类是否存在这个方法,而检查类是否存在某个方法的PHP函数不会执行 __call,所以不会得到你预期的结果。
建议你仔细研读CI源码。
发表于 2012-2-10 09:45:00 | 显示全部楼层
ci2.0.3 /system/core/CodeIgniter.php 312行如下:
if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI)))){...}
这就是检查从url得来的function是不是在控制器里。。
__call是php的魔术方法,ci不可能去检测这个,所以认识方法不存在,当然404了。。

你要是这样写,就没问题。也就是在test里调用不存在的方法,php的__call是肯定有效的。
function test(){
    echo($this->fuck('baby'));
}
       
function __call($key,$args){
    echo "你调用的".$key."函数不存在, 传入的参是:".$args;
}

你这需求怎么会这样?其实访问不存在的页面ci不已经给你定义好了进404吗。难道要在_call里做其他特别的事情?

点评

GOOD  发表于 2012-12-6 23:20
发表于 2012-2-10 11:27:13 | 显示全部楼层
我本来是想把每一个action分离出一个个独立文件,在class里面不写方法了,用call去require进来

但貌似在CodeIgniter.php被挡住了,现在只能这么写了。。。多么不美感啊

class Lpackage extends Back_Controller{

    /**
     * 学习包列表页
     */
    public function index(){
        require ACTIONPATH.strtolower(__CLASS__).'/'.strtolower(__FUNCTION__).'.php';
    }

    public function save() {
        require ACTIONPATH.strtolower(__CLASS__).'/'.strtolower(__FUNCTION__).'.php';
    }

    public function course() {
        require ACTIONPATH.strtolower(__CLASS__).'/'.strtolower(__FUNCTION__).'.php';
    }
}

本版积分规则