You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter自定义库初始化异常求助:循环依赖引发未定义属性

问题根源分析

你遇到的是库之间的循环依赖+初始化时机冲突导致的未定义属性错误,具体触发流程如下:

  1. 控制器同时加载lib_wishlists和lib_basket,优先加载lib_wishlists
  2. lib_wishlists构造函数中加载lib_basket
  3. lib_basket构造函数中尝试加载lib_wishlists(CI会标记该库已在加载队列,不会重复实例化),随后调用init_basket
  4. init_basket中调用lib_wishlists的use_wishlist_as_basket方法
  5. 此时lib_basket的实例还未完全初始化完成,尚未被赋值到CI实例的属性中,因此$this->CI->lib_basket会触发未定义属性的错误
解决方案

方案一:统一加载+延迟初始化(推荐)

移除库内部的交叉加载逻辑,将依赖加载和初始化步骤统一放到控制器中执行,确保所有依赖都加载完成后再初始化。

修改后的控制器代码

class Tests extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        // 先加载所有依赖库
        $this->load->library(['lib_wishlists', 'lib_basket']);
        // 再执行初始化逻辑
        $this->lib_wishlists->initWishlist();
        $this->lib_basket->init_basket();
    }
}

修改后的Lib_wishlists代码

class Lib_wishlists
{
    protected CI_Controller $CI;

    public function __construct()
    {
        $this->CI =& get_instance();
        $this->CI->load->database();
        // 移除内部加载lib_basket和自动调用initWishlist的逻辑
    }

    public function initWishlist()
    {
        // 原构造函数中的初始化逻辑移到这里
    }

    public function use_wishlist_as_basket(array $where = []): ReturnObject
    {
        // 此时lib_basket已被控制器加载完成,可正常调用
        $addObj = $this->CI->lib_basket->add_product_checks(...);
    }
}

修改后的Lib_basket代码

class Lib_basket
{
    protected CI_Controller $CI;

    public function __construct()
    {
        $this->CI =& get_instance();
        // 移除内部加载lib_wishlists和自动调用init_basket的逻辑
    }

    public function init_basket()
    {
        if (empty($this->CI->session->userdata('basket')))
        {
            if ($this->CI->auth->logged_in())
            {
                $this->CI->lib_wishlists->use_wishlist_as_basket(...);
            } else {
                $this->CI->session->set_userdata('basket', []);
            }
        }
    }
}

方案二:懒加载依赖(应急方案)

如果无法调整初始化时机,可以在调用对方方法前检查依赖是否已加载,未加载则手动加载并初始化:

Lib_wishlists中修改use_wishlist_as_basket方法

public function use_wishlist_as_basket(array $where = []): ReturnObject
{
    if (!isset($this->CI->lib_basket)) {
        $this->CI->load->library('lib_basket');
        $this->CI->lib_basket->init_basket();
    }
    $addObj = $this->CI->lib_basket->add_product_checks(...);
}

Lib_basket中修改init_basket方法

public function init_basket()
{
    if (empty($this->CI->session->userdata('basket')))
    {
        if ($this->CI->auth->logged_in())
        {
            if (!isset($this->CI->lib_wishlists)) {
                $this->CI->load->library('lib_wishlists');
                $this->CI->lib_wishlists->initWishlist();
            }
            $this->CI->lib_wishlists->use_wishlist_as_basket(...);
        } else {
            $this->CI->session->set_userdata('basket', []);
        }
    }
}
总结

核心原则是避免在库的构造函数中交叉加载依赖和执行初始化逻辑,将初始化时机延后到所有依赖都加载完成之后,即可解决循环依赖导致的未定义属性问题。

内容的提问来源于stack exchange,提问作者Bobyblanco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 23:36:38