在 Laravel 5.4 的查询生成器中添加 lists() 方法

Posted

技术标签:

【中文标题】在 Laravel 5.4 的查询生成器中添加 lists() 方法【英文标题】:Add lists() method in Query Builder in Laravel 5.4 【发布时间】:2017-09-09 19:48:22 【问题描述】:

我知道 Laravel 已删除 lists() 函数并将函数签名移动为 pluck()。但是,对于想要从 Laravel 4.x 升级到 Laravel 5.4 的人来说,这会导致很多工作。

因此,我试图找到一种方法来在我的代码中使用现有函数,即lists(),并在调用此函数时使用pluck()->toArray()

我尝试了以下方法。

方法一

class BaseModel extends  Illuminate\Database\Query\Builder
public function __call($method, $args)

    return call_user_func_array($this->method,$args);


public function lists($column)
return $this->pluck($column)->toArray();

不起作用!原因:这需要与 BaseModel 类一起扩展。但是,它已经扩展了 Eloquent 模型类。

方法二

尝试使用 trait 添加所需功能

listsWorkAround.php

<?php
trait listsWorkAround
 
  function lists($column)
    return $this->pluck($column)->toArray();
  

Model.php

<?php
namespace App;

use Watson\Rememberable\Rememberable;
use Illuminate\Database\Eloquent\Model as Eloquent;

abstract class Model extends Eloquent

    use listsWorkAround;
    use Rememberable;

不,不是没有成功。

方法3

尝试添加 ServiceProvider 并为 Builder 类添加 macro 函数,即在这种情况下为 lists。 但是,问题是最终返回的实体是一个 Collection,因为它是使用 Builder 的 __call 函数返回的。但是,所需的实体是 Array

编辑:我用于方法 3 的代码

<?php
namespace Providers;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\ServiceProvider;

class ListsWorkAround extends ServiceProvider

    /**
     * @inheritdoc
     */
    public function register()
    
        Builder::macro("lists", function ($column)         
            return $this->pluck($column)->toArray();
        );
    

但是,正如我所说,这仍然会返回 Collection。

【问题讨论】:

你能不能只复制原始的 lists 方法并将其添加到你自己的 trait 中? 你能展示你尝试的方法 3 的代码吗? @patricus 请查看代码。谢谢。 【参考方案1】:

如果你真的愿意,你可以将 lists 宏宏到查询生成器、Eloquent 生成器和集合中

宏查询生成器:

Illuminate\Database\Query\Builder::macro('lists', function ($column, $key = null) 
    return $this->pluck($column, $key)->all(); 
);


DB::table('users')->lists('email');

【讨论】:

谢谢!.. 这行得通!但是,我仍然不想将Model::XXX-&gt;lists(); 更改为DB::table()-&gt;XX-&gt;lists()。因此,我将macro 添加到 Eloquent 中,它似乎有效。发布我尝试过的答案。【参考方案2】:

所以,这就是我最终为使其工作而做的事情,即lists() in Model::XXX-&gt;lists()

..../config/app.php

中添加了这个
'providers' => [
 ...
 ...
 \App\Providers\ListsWorkAround::class,
],

这是提供者类文件。

ListsWorkAround.php

<?php
/**
 * Created by PhpStorm.
 * User: ateeq-ahmed
 * Date: 14/4/17
 * Time: 11:25 AM
 */

namespace App\Providers;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Support\ServiceProvider;

class ListsWorkAround extends ServiceProvider

    /**
     * @inheritdoc
     */
    public function register()
    
        Builder::macro("lists", function ($column, $key = null) 
            return $this->pluck($column, $key)->all();
        );

        QueryBuilder::macro("lists", function ($column, $key = null) 
            return $this->pluck($column, $key)->all();
        );
    

【讨论】:

我没有创建新的服务提供商,而是将其添加到AppServiceProvider,并且效果很好。

以上是关于在 Laravel 5.4 的查询生成器中添加 lists() 方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 laravel 5.4 中编写 mysql 查询?

在laravel 5.4中调用一个成员函数where()on float

laravel框架 5.4 关于验证和添加存在的bug

如何在 Laravel 5.4 中添加自定义用户提供程序

在 laravel 5.4 mix 上添加 jQuery

在 laravel 5.4 中检索软删除的用户帖子