在 laravel 控制器中使用特征

Posted

技术标签:

【中文标题】在 laravel 控制器中使用特征【英文标题】:using traits inside laravel controller 【发布时间】:2021-01-20 00:26:36 【问题描述】:

我的 laravel(7.23.0) 控制器中有一些重复的代码

use App\ModelA;
use App\ModelB;
use App\ModelC;
use App\Traits\DbTrait;

    class DarsController extends Controller
    
       use DbTrait;

    public function A($id) 
           return ModelA::where('column', $id)->get(*);
    
    public function B($id) 
           return ModelB::where('column', $id)->get(*);
    

    public function C($id)
           return ModelC::where('column', $id)->get(*);
      
    //the only difference in these codes is model, all codes are the same
    
  

我创建了一个名为 Traits 的文件夹,并在其中定义了一个 trait DbTrait.php

<?php 
namespace App\Traits;

trait DbTrait

    public function getAllz($ModelName , $id)
        return $ModelName::where('column', $id)->get('*');
    

所以我将控制器的功能修改为这个

public function A($id) 
            //   return ModelA::where('column', $id)->get(*); works fine
               $this->getAllz('ModelA', $id);// throws an error

   

它会抛出错误消息:“找不到类‘ModelA’”

谢谢

更新: 我应该道歉,我真的很抱歉,答案中的 3 个有效,我在网络选项卡中看到了数据,我正在使用 vue 显示数据, 我认为使用 trait 制作了一个复杂的数组

这是我的简单 vue

axios.get('/api/emla/' + id).then(response =>
                         this.data = JSON.parse(JSON.stringify(response.data)); 

【问题讨论】:

因为它在你的特征目录中寻找 ModelA app( '\App\' . $ModelName )::where('column', $id)-&gt;get('*'); 谢谢@swadha 可以请你详细说明一下,我不能只是复制和粘贴你的代码 您尝试过什么调试问题?为什么不使用完整的类名(包括命名空间)? @Nico 怎么样?对不起,我是新手 【参考方案1】:

你需要修改你的特质

ModelName::where 它尝试在 trait 中加载类,所以在这里使用 $ModelName-&gt;where $ModelName 已经是该类的实例,因此您可以通过 -&gt; 运算符调用函数

<?php 
namespace App\Traits;

trait DbTrait

    public function getAllz($ModelName ,$columnName ,$id)
        return $ModelName->where($columnName, $id)->get('*');
    

并调用这个函数

$this->getAllz(new ModelA, $id);

这样你就不需要在 trait 中导入类

你的最终代码会是这样的


use App\ModelA;
use App\ModelB;
use App\ModelC;
use App\Traits\DbTrait;

class DarsController extends Controller

    use DbTrait;

    public function A($id)
    
        return $this->getAllz(new ModelA,'column', $id);
    
    public function B($id)
    
        return $this->getAllz(new ModelB,'column', $id);
    

    public function C($id)
    
        return $this->getAllz(new ModelC,'column', $id);
    

【讨论】:

@thanks kamlesh,由于拼写错误,我编辑了问题,对此感到抱歉,我试过了,但它给了我一条消息“此请求没有可用的响应数据” @raamiin 你尝试了什么,你得到了什么错误。? 一切,你的回答,它没有给我数据库中的数据,所以我在网络标签内的谷歌开发工具中检查 @raamiin 因为在您编写代码时,所有模型都在寻找 dars_id 我仔细尝试了这个答案,错误改回“找不到类'ModelA'”【参考方案2】:

像在控制器类中所做的那样,导入将在您的 trait 中使用的类。

use App\ModelA;
use App\ModelB;
use App\ModelC;

【讨论】:

【参考方案3】:

你得到Class 'ModelA' not found 的原因是它在你的traits 目录中寻找那个类,但它找不到。所以你需要这个:

<?php 
namespace App\Traits;

trait DbTrait

    public function getAllz($ModelName , $id) 
        return app( "\App\\" . $ModelName )::where('column', $id)->get('*');
    

假设您已在 \App 命名空间下定义模型

【讨论】:

@thanks swadhwa 我一开始没有更改模型的目录(它在默认目录中),我使用的是 Visual Studio 代码,我粘贴了你的代码,它说期待') ',我是菜鸟 消息:“目标类 [\App\ModelA] 不存在。” @raamiin 啊废话我忘了转义反斜杠。你现在能检查一下吗?对不起。 谢谢,但“此请求没有可用的响应数据” @raamiin 这似乎是一个不相关的问题。我已经为您提供了解决方案。请接受这一点并发布一个新问题,我会调查的。谢谢。【参考方案4】:

如果你遵循这个,100% 应该可以工作

public function A($id) 
        //   return ModelA::where('column', $id)->get(*); works fine
           $model = new ModelName(); // new ModelName;
           $this->getAllz($model, $id);// throws an error




public function getAllz($ModelName , $id)
    return $ModelName->where('column', $id)->get('*');

【讨论】:

感谢 Ripon 当我 dd($this->getAllz($model, $id));我可以在网络选项卡中看到数据,但我无法得到我想要的 没有从方法 A 返回。这就是为什么你没有得到预期的结果。我认为

以上是关于在 laravel 控制器中使用特征的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5 - laracast 生成器

Laravel 在 jquery 中使用来自控制器的 json

如何在使用 Laravel 在控制器中发送邮件之前更改邮件配置?

在 vue 模板中使用从 laravel 控制器返回的对象

在laravel中验证从表单到控制器的数据?

(Laravel)如何在 1 条路线中使用 2 个控制器?