Codeigniter - 只能在 autoload.php 中加载模型

Posted

技术标签:

【中文标题】Codeigniter - 只能在 autoload.php 中加载模型【英文标题】:Codeigniter - Can only load model in autoload.php 【发布时间】:2014-12-21 19:11:24 【问题描述】:

我快疯了,因为我已经使用 Codeigniter 好多年了,但我似乎无法在我的视图中加载模型。

这就是我所做的。模型代码(models/changelog.php):

<?php

class Changelog extends CI_Model 
    function __construct() 
        parent::__construct();
        $this->load->database();
    

    function get_list() 
        $query = $this->db->get('changelog');
        return $query->result();        
    


/* Location: ./application/models/changelog.php */

这是我的控制器(controllers/explore.php):

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Explore extends CI_Controller 
    public function index() 
        $this->load->view('include/header');
        $this->load->view('home');
        $this->load->view('include/footer');
    

    public function changelog() 
        $this->load->model('changelog');
        $data['changelog_row'] = $this->changelog->get_list();

        $this->load->view('include/header');
        $this->load->view('explore/changelog', $data);
        $this->load->view('include/footer');
    


/* Location: ./application/controllers/explore.php */

我收到一个 Codeigniter 通知,告诉我 消息:未定义的属性:Explore::$Changelog 和一个 PHP 错误,致命错误:在非对象

这就是我所做的

尝试自动加载数据库,而不是仅在该模型中加载它 尝试将控制器中的 Changelog 调用更改为小写 检查了与数据库的连接 启用日志文件,它没有告诉我任何新信息

一切正常,也许只是我有点累,但如果有人可以帮助我,我会喜欢的:)


经过一些测试,我发现错误在

$data['changelog_row'] = $this->Changelog->get_list();

我的代码行。我不知道问题是什么。区分大小写很好(也尝试了许多小写/大写的组合),即使我创建了另一个具有不同名称的函数(例如 foo()),内部有一个正常的回声,我也会得到相同的错误,但指的是那个函数。

这是一个屏幕


发生了一些不可思议的事情:如果我在 autoload.php 中添加“changelog”模型,它似乎真的可以加载它。到底是怎么回事?我已经在许多应用程序中使用了此代码,没有问题。

我做的另一个测试:如果我写

public function __construct() 
        parent:: __construct();
        $this->load->model('changelog');

在控制器中或只是在更改日志函数中添加 parent:: __construct(); 就像

public function changelog() 
        parent:: __construct();
        $this->load->model('changelog');
        $data['changelog_data'] = $this->changelog->get_list();

        $this->load->view('include/header');
        $this->load->view('explore/changelog', $data);
        $this->load->view('include/footer');
    

它工作 O_o。但为什么?我更改了主题标题,现在一切都围绕着我无法在控制器的功能中加载我的模型。

【问题讨论】:

请先更改您的相关代码。这不是用大写字母开始调用类的正确方法。首先,只需用小写字母调用该类并修改您的问题。 我相应地更新了问题。 也检查一下,例子中che模型实际上是用大写字母调用的:ellislab.com/codeigniter/user-guide/general/models.html#loading 请查看我的更新答案。现在应该可以了。 还是什么都没有。同样的错误,但我正在更新主要答案,因为我发现了一些新东西。 【参考方案1】:

CI 对此有些奇怪。 Om unix 系统(文件名区分大小写)您必须使用区分大小写的名称加载模型。 但是在控制器中,您应该使用小写字母来处理它,即

$this->load->model('changeLog');
$this->changelog->getList();

【讨论】:

我尊重区分大小写,但没有任何变化。我更新了主要答案! 另外我会得到“无法找到您指定的模型”错误,我实际上并没有得到 也许函数名称与模型名称相同存在问题,不确定只是大声思考。 已经试过了:(我现在真的不知道该怎么办!【参考方案2】:

请使用以下语法更改您的 changelog 函数。

public function changelog() 
        $this->load->model('changelog', 'model');
        $data['changelog_row'] = $this->model->get_list();

        $this->load->view('include/header');
        $this->load->view('explore/changelog', $data);
        $this->load->view('include/footer');


你的模型的功能应该如下:

public function get_list() 
    $query = $this->db->get('changelog');
    return $query->result();        

您错过了public 关键字。所以,它现在是一个private 函数,这就是为什么你不能从另一个类访问它的原因。

【讨论】:

我会尽快试试这个,我可以知道你为什么在函数调用中添加“模型”作为第二个参数吗? 你当然知道。这只不过是创建一个新实例。这意味着它完成了以下任务:$model = new changelog(); 我已经尝试过了,但没有运气,我仍然遇到同样的错误,没有任何变化。我认为创建实例可能会有所帮助,但在我的情况下没有 我编辑了主帖添加:“启用日志文件,这并没有告诉我任何新内容。” 如果没有看到很多东西,很难回答你。请提及您的模型的文件名。以及控制器文件中小写的用户“changelog”。【参考方案3】:

您使用的模型名称与控制器功能的名称相同,因此出现名称冲突是因为;

    $this->changelog()

正在尝试同时引用你已经加载的模型和类方法。

重命名您的 Explore::changelog() 函数(或模型名称 - 例如后缀 _m)应该没问题。类似的东西;

    $this->changelog_m->getList();

【讨论】:

不幸的是,情况并非如此。已经尝试过了,没有任何变化。 还尝试了一个完全不同的模型,只是为了确定,称为 test.php。没有运气:( 嗯,不同型号的相同代码?仍然出现同样的错误? 当然我改变了必须改变的部分,例如“类测试扩展 CI_Model”等等。是的,同样的错误没有该死的差异。快疯了。 奇怪的家伙,我只是运行了相同的代码,它运行没有问题。反正只要你修好了!【参考方案4】:

经过数小时的测试并搞砸了一切,包括配置文件……我做到了!

这是完全超越模型和控制器的东西,它是关于我调用的钩子的东西。事实上,我有一个叫 languageloader.php 的钩子,写成这样:

class LanguageLoader extends CI_Controller 
    public function initialize() 
        $ci =& get_instance();
        $site_lang = $ci->session->userdata('site_lang');
        if (!empty($site_lang)) 
            $ci->lang->load('text', $site_lang);
         else 
            $ci->lang->load('text', 'english');
        
    

在我的 hooks 文件中,它的加载方式如下:

$hook['post_controller_constructor'] = array(
    'class'    => 'LanguageLoader',
    'function' => 'initialize',
    'filename' => 'languageloader.php',
    'filepath' => 'hooks',
);

由于我使用的是post_controller_constructor,所以指的是CI doc文件

在您的控制器实例化后立即调用,但在此之前 发生任何方法调用。

我相信做类似我的 $ci =& get_instance();我无法实例化我该死的模型。我通过将钩子更改为来修复它

$hook['pre_controller']

我不认为这可能与钩子有关,这就是我没有发布它的原因。感谢所有试图帮助我的人。我希望这可以帮助遇到同样麻烦的其他人!

【讨论】:

【参考方案5】:

供您参考,您可以从

修改您的 autoload.php

./application/config/autoload.php

然后只包含模型文件夹中存在的所有模型

./application/models/*_Model.php

所以从 autoload.php 设置你的 autoload['model'] 数组。

/*
| -------------------------------------------------------------------
|  Auto-load Models
| -------------------------------------------------------------------
| Prototype:
|
|   $autoload['model'] = array('first_model', 'second_model');
|
| You can also supply an alternative model name to be assigned
| in the controller:
|
|   $autoload['model'] = array('first_model' => 'first');
*/
$autoload['model'] = array('Foo_Model', 'Bar_Model', ...);

然后从您的 Controller 中,您可以从您的 __construct() 中删除 $this-&gt;load(...);,因为您从 autoload.php 定义的所有模型都是全局加载的并且可以使用每当您运行系统时。

然后直接从那个模型调用你需要的公共方法,像这样;

$this->Foo_Model->your_public_method_to_call();

PS:

CI_VERSION:3.x

PHP:5.4+

我希望这对某人有所帮助,谢谢。

【讨论】:

以上是关于Codeigniter - 只能在 autoload.php 中加载模型的主要内容,如果未能解决你的问题,请参考以下文章

在 Codeigniter 中设置表单的“名称”属性

php优秀框架codeigniter学习系列——CodeIgniter.php概览

CodeIgniter - 如何在 url 路由中删除类名

CodeIgniter 错误:变量引用

CodeIgniter 仅允许在登录时访问某些控制器

Codeigniter 仅更新第一行