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

使用PHP-DI延迟注入mysqli时出现属性访问不允许警告

解决PHP-DI延迟注入mysqli时的属性访问警告问题

你遇到的这个问题,本质是PHP-DI的延迟代理机制在处理mysqli这类内置扩展类时,属性访问的转发逻辑出现了兼容问题。让我帮你拆解原因并给出可行的解决办法:

问题根源

当你给mysqli::class配置->lazy()后,PHP-DI不会立刻创建真实的mysqli实例,而是生成一个代理类占位符。这个代理只会在你第一次调用对象的方法时,才会去初始化真实的mysqli连接。但mysqli的affected_rows是一个直接的属性而非方法——代理类默认只拦截方法调用,对于属性访问,要么在真实实例未初始化时就触发,要么无法正确转发到真实对象,从而抛出"Property access is not allowed yet"的警告。

解决方案

这里有几个实用的解决思路,你可以根据自己的场景选择:

1. 访问属性前手动触发实例初始化

在myService的myMethod里,先调用一个mysqli的无副作用方法(比如ping()),强制代理初始化真实的mysqli实例,之后再访问属性:

public function myMethod() {
    // 先触发代理初始化真实mysqli连接
    $this->dbService->ping();
    
    $sql = "DELETE FROM my_table where column1 = 'test';";
    $this->dbService->query($sql);
    return $this->dbService->affected_rows;
}

2. 改用工厂函数配置延迟加载

PHP-DI的create()->lazy()对部分内置类的支持不够友好,你可以换成工厂函数配合延迟加载,确保实例化逻辑被正确执行:

$config = [
    mysqli::class => lazy(function () {
        $mysqli = new mysqli(
            env('DATABASE_HOST'),
            env('DATABASE_USER'),
            env('DATABASE_PASSWORD'),
            env('DATABASE'),
            3306,
            null
        );
        
        // 提前检查连接错误,避免后续隐藏问题
        if ($mysqli->connect_error) {
            throw new RuntimeException("数据库连接失败: " . $mysqli->connect_error);
        }
        
        return $mysqli;
    }),
    myService::class => autowire()
    // ...其他服务配置
];

3. 移除mysqli的延迟加载配置

如果你的应用中数据库连接的初始化开销不大,其实完全可以去掉lazy()。毕竟数据库连接通常是应用启动阶段就需要的核心资源,延迟加载带来的性能收益远小于解决这类兼容性问题的成本——这也是你移除lazy后一切正常的原因。

额外小提示

另外,你的myService类名不符合PHP的PSR命名规范(应该首字母大写为MyService),虽然这不是问题的直接原因,但遵循规范能提升代码的可读性和团队协作效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:27:44