【问题标题】:Laravel: Dependency injection and static custom method for all my modelsLaravel:我所有模型的依赖注入和静态自定义方法
【发布时间】:2019-12-23 02:44:59
【问题描述】:

我创建了一个帮助类来搜索和过滤我的 laravel 模型(方法使用 tntsearch 和自定义范围),目前它可以正常工作,但我想对其进行一些改进,遗憾的是证明很难实现我想要的:

我想改进的地方:

1) 能够在我的所有 laravel 模型上静态调用搜索方法,如下所示:

Model::search();

目前我必须实例化该类并调用如下方法:

 $results = $searchHelper->search($request, $filters);

2)现在我还必须将两个参数传递给构造函数,在我的类中,我尝试在构造魔术方法中进行依赖注入,但我仍然必须将请求和过滤器作为参数传递......

它在我的控制器中的外观:

public function search(Request $request, QueryFilters $filters)
    {
        $search = new Search($request, $filters);


        $posts = $search->search('Post', ['postcategory', 'author', 'favorites']);

        return response()->json([
            'message' => 'Encontramos unas coincidencias',
            'posts' => $posts,
        ], 200);   
    }

我的助手类:

<?php
namespace App\Helpers;


use Illuminate\Http\Request;
use App\Filters\QueryFilters;
use App\Filters\Filterable;


class Search
{

    public $request;
    public $filters;

    public function __construct(Request $request, QueryFilters $filters)
    {
        $this->request = $request;
        $this->filters = $filters;
    }

    public function search( $model, $relationships = [] )
    {
        $model = app("App\Models\".$model."); 

        $results = $model::search($this->request->input('search'), '')->get(); 

        if(!$results->isEmpty())
        {
            $ids = implode(',', $results->pluck('id')->toArray());
            $filters->merge(['whereIn' => $ids]);    
        }

        $results = $model::filter($this->filters)->with($relationships)->paginate(10);

        return $results; 
    }


}

我想这样调用方法,不向构造函数传递参数(DI 应该处理),静态调用方法

Appointments::search();

【问题讨论】:

  • 什么是QueryFilters?它来自哪里?
  • 它是另一个辅助类,它接受请求对象并为每个 GET 参数构建一个查询

标签: php laravel


【解决方案1】:

您可以像这样定义 Searchable 特征(而不是您的 Search 类):

trait Searchable
{
    public static function search($relationships = [])
    {
        //You may use the `resolve` method to resolve a class instance.
        $request = resolve(\Illuminate\Http\Request::class);
        //or $request = request();
        $filters = resolve(\App\Filters\QueryFilters::class);

        //rename the other `search` function on your model to `doSearch` to resolve conflicts
        $results = self::doSearch($request->input('search'), '')->get();
        //or using request helper function
        //$results = self::doSearch(request('search'), '')->get(); 

        if(!$results->isEmpty())
        {
            $ids = implode(',', $results->pluck('id')->toArray());
            $filters->merge(['whereIn' => $ids]);    
        }

        $results = self::filter($filters)->with($relationships)->paginate(10);

        return $results; 
    }

}

并在你的 Eloquent 模型上实现这个 Searchable 合约:

class Appointment extends Model
{
    use Searchable;

    //...
}

现在你可以打电话了:

Appointment::search();

【讨论】:

  • 会得到一个'非静态方法不应该被静态调用......'
  • @lagbox 谢谢,将函数设为静态并将另一个 search 函数重命名为 doSearch 以解决冲突。
  • 这看起来不错,但我得到“不在对象上下文中使用 $this”
  • 没关系,我改用 self 来修复它,谢谢!
【解决方案2】:

如果您希望某个方法可用于所有模型,您可以使用该方法创建一个新模型。然后扩展您希望从该新模型中搜索可用的每个模型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-27
    相关资源
    最近更新 更多