数据集CollectionTP5报Cannot use object of type __PHP_Incomplete_Class as array错误

本文探讨了在使用PHP框架进行登录功能开发时,如何避免将对象直接存入session导致的数据类型错误。通过将数据库返回的对象转换为数组再存储,并调整数据库返回类型为数据集,解决了session存储问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本来是写登陆功能的时候将管理员数据保存到session中去,然后在BaseController中获取session并输出到模板,主要代码如下: login控制器
$result = AdminModel::get(['username'=>$data['username']]);
unset($result->password);
session('adminAccount',$result);
$this->success('登陆成功','index/index','',2);

BaseController

public function _initialize(){
        if(!$this->isLogin()){
            $this->redirect('login/index');
        }
        if(Session::has('sysData')){
            $sysdata = Session::get('sysData');
        }else{
            $this->getSysData();
            $sysdata = Session::get('sysData');
        }
        $admin = Session::get('adminAccount');
        $this->assign('admin',$admin);
        $this->assign('sysdata',$sysdata);
    }

Cannot use object of type __PHP_Incomplete_Class as array

1、本来登陆功能之前就已经写好了,也没出问题,今天突然报错,看了下大体意思是数据类型输出的问题,网上搜了下,似乎是不建议将对象查询的结果对象直接保存到session中取的,我们知道,TP5的返回结果虽说默认是array,但里面还是一堆对象,有时处理还会有问题,所以找到了一个自认为比较稳妥的方法。

在这里插入图片描述

2、将database中的返回类型改为数据集,默认是array。数据集支持对象化的操作,也可以用访问数组的方式访问它,TP官方推出collection返回类型设置不是木有道理的,几乎满足获取数据之后的主要操作。更多操作详情访问这一篇。

// 数据集返回类型
'resultset_type'  => 'collection',

3、将上方代码改成如下所示后就OK了

session('adminAccount',$result->toArray());
<think>我们正在处理一个C++编译错误:invalid useof incompletetype 'class Ui::Dlg_Login'这个错误通常发生在尝试使用一个只有前向声明但没有完整定义的类型时。具体到Qt开发中,这往往与使用Qt Designer生成的UI文件有关。原因分析:1.在头文件中,我们通常会有类似的前向声明:`namespace Ui{ classDlg_Login; }`2.然后在类的私有成员中声明一个指针:`Ui::Dlg_Login *ui;`3.但是,在实现文件(.cpp)中,如果没有包含该类的完整定义(即ui头文件),那么当我们使用`ui`指针访问成员时,编译器只知道`Ui::Dlg_Login`是一个类,但不知道它的具体内容(因此是不完整类型),从而导致该错误。解决方案:1.确保在实现文件中包含了对应的UI头文件。这个头文件是在编译过程中由uic工具从.ui文件生成的,通常命名为`ui_xxx.h`(其中xxx是.ui文件的基名)。2.检查头文件和实现文件中的类名是否一致。特别要注意,UI文件中定义的类名(在Qt Designer中,可以通过查看对象属性中的“类名”或“objectName”)应该与代码中使用的类名一致。参考用户提供的引用[^1]:在Qt Designer中,需要确保“类名”(在UI文件中对应的是类名,但实际上在生成的代码中,类名是由UI文件中顶层窗口对象的objectName决定的)与代码中使用的类名一致。具体来说:-在QtDesigner中,选择顶层窗口(比如Dialog、Widget等),然后在属性编辑器中查看“objectName”属性。-假设你有一个对话框,其objectName为“Dlg_Login”,那么生成的UI头文件中会有一个名为`Ui_Dlg_Login`的类,而在代码中我们通常使用`namespace Ui{ classDlg_Login; }`来前向声明,然后使用`Ui::Dlg_Login`。因此,检查步骤:a.打开你的.ui文件(例如:dlg_login.ui)b.选中顶层窗口(比如Dialog)c.在属性编辑器中查看“objectName”属性,确保它是“Dlg_Login”(注意大小写)d.重新运行qmake(因为uic工具会根据.ui文件生成ui_dlg_login.h,其中定义的类为`Ui_Dlg_Login`,而在代码中我们通过`namespace Ui{ classDlg_Login; }`来使用它,实际上在ui_dlg_login.h中,这个类的完整定义是在命名空间Ui中,类名为`Dlg_Login`)如果objectName不是“Dlg_Login”,那么生成的类名就会不同,从而导致前向声明和实际定义不匹配。另外,检查代码:-在头文件(比如dlg_login.h)中,应该只有前向声明,而不包含ui头文件(因为这样会加快编译速度,并避免不必要的依赖)。-在实现文件(dlg_login.cpp)中,必须包含ui头文件(例如:#include "ui_dlg_login.h")错误示例://dlg_login.hnamespace Ui{ classDlg_Login; }classDlg_Login :public QDialog {Q_OBJECTpublic:explicitDlg_Login(QWidget*parent= nullptr);~Dlg_Login();private:Ui::Dlg_Login*ui;//这里只是一个指针,不需要完整定义};// dlg_login.cpp#include "dlg_login.h"//缺少 #include "ui_dlg_login.h"Dlg_Login::Dlg_Login(QWidget*parent) :QDialog(parent),ui(newUi::Dlg_Login) {ui->setupUi(this);//这里使用ui指针,需要知道Ui::Dlg_Login的完整定义}如果没有包含ui_dlg_login.h,那么在构造函数中,当我们使用`ui->setupUi(this)`时,编译器不知道`Ui::Dlg_Login`的具体内容,因此错。因此,在dlg_login.cpp中,必须添加:#include "ui_dlg_login.h"此外,还要确保在构建过程中,uic工具被正确执行,生成了ui_dlg_login.h文件。总结步骤:1.检查.ui文件中顶层窗口的objectName,确保与代码中使用的类名一致(即Ui::后面的部分,这里是Dlg_Login)。2.在实现文件中包含对应的ui头文件(#include"ui_xxx.h",其中xxx是.ui文件的文件名,注意文件名大小写)。3.清理项目,重新运行qmake(因为可能修改了.ui文件,需要重新生成ui头文件)并重新构建。如果以上步骤都正确,问题应该解决。相关问题:1.Qt中如何正确使用ui文件生成的类?2.前向声明和包含头文件在C++中有什么区别?3.如何避免在头文件中包含其他头文件?4.在Qt中,如何修改ui文件并更新生成的代码?</think>### 错误原因分析 `invalid use of incomplete type 'class Ui::Dlg_Login'` 错误通常发生在以下场景: 1. **前向声明不匹配** 在头文件中使用了前向声明 `namespace Ui { class Dlg_Login; }`,但实际UI类名与声明不一致。例如: ```cpp // 头文件中的前向声明 namespace Ui { class Dlg_Login; } // 声明类名为 Dlg_Login ``` 而UI文件(`.ui`)中顶层对象的 `objectName` 或类名被修改为其他名称(如 `LoginDialog`),导致生成的 `ui_*.h` 文件中实际类名为 `Ui::LoginDialog`,与声明冲突。 2. **未包含UI头文件** 在实现文件(`.cpp`)中直接使用 `Ui::Dlg_Login` 成员,但未包含对应的 `ui_*.h` 文件: ```cpp // 实现文件中缺少: #include "ui_dlg_login.h" // 未包含实际定义 ``` 3. **UI文件与代码类名不一致** Qt Designer 中顶层对象(如 `QDialog`)的 `objectName` 属性必须与代码中使用的 `Ui::` 类名严格一致。例如: - UI 文件中 `objectName="Dlg_Login"` → 代码中需使用 `Ui::Dlg_Login` - 若 UI 文件中误设为 `objectName="LoginDialog"` → 代码中需改为 `Ui::LoginDialog` --- ### 解决方案 #### 步骤 1:统一类名 1. **打开 `.ui` 文件**(如 `dlg_login.ui`) 2. **选中顶层对象**(`QDialog`/`QWidget`) 3. **在属性面板中检查 `objectName`** → 确保值为 `Dlg_Login`(与错误中的类名一致) ![Qt Designer 属性面板](https://i.imgur.com/5jXK7lD.png) #### 步骤 2:包含正确的头文件 在实现文件(`.cpp`)开头添加: ```cpp #include "ui_dlg_login.h" // 文件名与.ui文件对应 ``` #### 步骤 3:同步代码声明 修改头文件(`.h`)中的前向声明,确保与 `objectName` 一致: ```cpp // 正确声明(与UI的objectName匹配) namespace Ui { class Dlg_Login; } // 注意: 无分号 ``` #### 步骤 4:重新生成UI头文件 1. 清理项目:`Build → Clean Project` 2. 重新运行 `qmake`:`Build → Run qmake` 3. 重新编译:`Build → Rebuild Project` > 此操作会触发 `uic` 工具重新生成 `ui_dlg_login.h`,其中包含完整的 `Ui::Dlg_Login` 定义。 --- ### 关键原理 - **前向声明限制**:仅声明 `class Ui::Dlg_Login` 允许定义指针(`Ui::Dlg_Login* ui;`),但访问成员(如 `ui->setupUi(this)`)需要完整定义。 - **UI生成规则**:`uic` 工具根据 `.ui` 中顶层对象的 `objectName` 生成类名: `objectName="X"` → 生成 `class Ui_X` → 代码中通过 `namespace Ui { class X; }` 访问。 --- ### 相关问题 1. 如何在Qt Creator中快速定位UI文件对应的生成头文件? 2. Qt Designer中 `objectName` 和 `类名` 属性有何区别? 3. 如何避免在头文件中包含UI头文件以减少依赖? 4. 除了类名不一致,还有哪些原因会导致 `incomplete type` 错误? [^1]: 引用自Qt开发社区关于UI类名前向声明的典型解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值