【问题标题】:Codeigniter issue with controller and model控制器和模型的 Codeigniter 问题
【发布时间】:2010-12-18 01:00:31
【问题描述】:

我正在使用 codeigniter 1.7.3,并且我已设置并运行控制器,但是当我尝试通过控制器访问模型时,我无法返回查询结果。

我在配置区域中正确配置了我的数据库(我知道这一点,因为当我故意弄乱其中一个配置选项时,我收到一条消息说无法访问数据库。)

这是相关的控制器(SiteObj.php)代码:

class SiteObj extends Controller {
     function __construct() {
          parent::Controller();
          $this->load->model('Site_model');
          $data['query'] = $this->Site_model->create_site();

          if ($data->num_rows() == 1) {
             //etc. etc.

这里是相关的模型(site_model.php)代码:

class Site_model extends Model {
    function __construct() {
        parent::Model();
        $this->load->database();
    }

    function create_site(){
        $query = $this->db->query("SELECT * FROM sites WHERE siteid = '1' LIMIT 1");

        if ($query->num_rows() > 0) {
         $row = $query->row();
         return $row;
             // etc etc

我也尝试过命名初始函数 Site_model 而不是构造函数,但没有成功。我还尝试通过 autoload.php 文件自动加载数据库,还尝试在 create_site 函数本身而不是构造函数中加载数据库。

这是我收到的错误消息:

致命错误:在非对象上调用成员函数 num_rows() /www/development/sunrise_ci/00ci00/application/init/siteObj.php 在第 9 行

更新:我遵循了第一响应者的建议,但没有帮助。

我已经删除了所有对数据库连接的引用,以试图隔离问题。当我只是尝试从控制器中调用 create_site() 函数时,我得到了这个:

Undefined property: SiteObj::$Site_model
Fatal error: Call to a member function create_site() on a non-object

所以看来问题出在控制器和模型之间,不知何故,它们似乎并没有正确地相互“交谈”。有趣的是,我可以看到我可以将值从 create_site() 传递给控制器​​,但我仍然会收到错误消息。

**** 12/18 更新 **********

好的,首先,我修改了 application/config/hooks.php 文件,以便我可以在所有页面调用之前预加载我的初始化代码。所以这个页面有这个:

$hook['pre_controller'][] = array(
        'class'    => 'SiteObj',
        'function' => '__construct',
        'filename' => 'siteObj.php',
        'filepath' => 'init'
    );

接下来,我有一个处理所有页面调用的默认控制器。它位于 controllers/page.php,代码如下:

class Page extends Controller {
        // I am the core controller for the application.
        function _remap() {
            $mysite = new SiteObj();
        }
    }

这会调用我在 application/init/siteobj.php 中设置的 init 对象。这是代码:

class SiteObj extends Controller {
        function __construct() {
            parent::Controller();
            $this->load->model('Site_model');
            $data = $this->Site_model->create_site();
            if ($data){
                $this->siteid = $data->siteid;
            } else {
                $this->siteid = 0;
            }
        }
    }

最后是models/site_model.php中的模型代码:

class Site_model extends Model {
        function Site_model() {
            parent::Model();
            $this->load->database();
        }

        public function create_site(){
            // I load the site data from the database and send the result to the controller
            $query = $this->db->query("SELECT * FROM sites WHERE siteid = '1' LIMIT 1");
            if ($query->num_rows() == 1) {
                return $query->row();
            }
        }
    }

我收到此错误:

Undefined property: SiteObj::$Site_model
Fatal error: Call to a member function create_site() on a 
non-object in 
/www/development/sunrise_ci/00ci00/application/init/siteObj.php 
on line 7

提前致谢!

加里

【问题讨论】:

    标签: php codeigniter model controller


    【解决方案1】:

    根据原始问题中的更新代码进行更新

    请记住,CodeIgniter 的 Hooks 类是在 Loader 类之前初始化的,因此您的 pre_controller 挂钩正在实例化 SiteObj 并尝试调用 Site_model->create_site() 之前 @987654326 @ 已通过 Loader 类加载。

    它会引发错误,因为您无法在尚不存在的对象上调用方法。在这种情况下,Site_model 是尚不存在的对象。

    请记住,您可以检查您的日志文件(位于 /system/logs/)以查看资源的执行顺序。查看CodeIgniter Application Flow Chart 也可能会有所帮助。

    希望有帮助!

    结束更新

    num_rows() 方法只能用于整个$query 结果对象,就像您在Site_model 中一样:

    $query = $this->db->query("SELECT * FROM sites WHERE siteid = '1' LIMIT 1");
    
    if ($query->num_rows() > 0) {
            // do stuff
    }
    

    但是,目前您的Site_model 中的create_site() 方法正在从结果对象返回单行 (return $row;),然后您尝试调用num_rows() on SiteObj 控制器中的那一行。

    确实没有必要这样做,因为$query->row(); 将始终返回单个结果行。

    如果你确实想从你的控制器内部调用num_rows()(同样,真的没有意义,因为$query->row()总是只返回一行),你必须像这样返回整个$query结果对象:

    $query = $this->db->query("SELECT * FROM sites WHERE siteid = '1' LIMIT 1");
    
    if ($query->num_rows() > 0) {
        return $query;
    }
    

    然后在您的SiteObj 控制器中:

    $this->load->model('Site_model');
    
    $data = $this->Site_model->create_site();
    
    if ($data->num_rows() == 1) {
        //etc. etc.
    }
    

    希望对您有所帮助 - 如果不告诉我。看起来您的代码并不太遥远!作为参考,请查看num_rows() methodrow() method

    【讨论】:

    • 对于阅读本文的任何人,OP 在原始问题中提到的另一个答案已发布。
    • 您好 Colin,感谢您的反馈 - 这与原始响应者所说的非常相似。但这个问题似乎与我最初认为的不同(请参阅我原帖中的更新)。即使我取出所有数据库连接的东西,我也会收到这个错误:“调用非对象上的成员函数 create_site()”。实例化对象时我做错了吗?谢谢!
    • 我想我明白了:似乎当我从构造函数中取出除 parent::Controller() 或 parent::Model() 调用之外的所有内容时,事情开始表现得更像预期的。那是问题吗?我不能在该构造函数中添加任何其他代码吗?
    • @Gary:是的,您可以将其他代码放入构造函数中——这不是问题。我快速设置了一个 CodeIgniter 测试实例,仅包含您在问题中提到的控制器、模型和数据库表,一切正常。我唯一改变的是我在控制器中删除了对num_rows() 的调用。您可以发布更多代码吗?或者你能发布你最新的代码吗?
    • @Gary:您在更新中报告的错误表明您不再加载模型?你不能在没有先完成$this->load->model('Site_model'); 的情况下打电话给create_site()。是的,你可以在构造函数中做到这一点。
    猜你喜欢
    • 1970-01-01
    • 2012-05-03
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2010-12-19
    • 2015-04-24
    • 2015-10-04
    相关资源
    最近更新 更多