【问题标题】:Laravel method that can be used by multiple controllers and commands. Where should it be?可以被多个控制器和命令使用的 Laravel 方法。它应该在哪里?
【发布时间】:2023-03-17 16:04:01
【问题描述】:

我想定义一个可供多个控制器和命令使用的“全局”方法。在 Laravel 5.4 中应该放在哪里?

假设我有以下控制器。我将如何调用“全局”方法,以及该“全局”方法的确切位置?

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;

use App\Flight;

class FlightsController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Index
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $flights = Flight::where('active', 1)
               ->orderBy('name', 'desc')
               ->take(10)
               ->get();

        foreach ($flights as $flight) {
            if ( $flight->price == 0 )
            {
                $output = "some value";
            }
            else
            {
                $output = "some other value";
            }
        }

        return view('flights.index')
                ->with(['output'   => $output])
                ;
    }
}

【问题讨论】:

    标签: php laravel laravel-5 eloquent laravel-5.4


    【解决方案1】:

    当你想要一个获取许多模型的方法,并且你想在很多地方使用它时,把它放在一个 Repository 中:

    class FlightRepository
    {
        public function getLastTenFlights()
        {
            return Flight::where('active', 1)
               ->orderBy('name', 'desc')
               ->take(10)
               ->get();
        }
    }
    

    例如来自您的控制器:

    public function index( FlightRepository $repo )
    {
        $flights = $repo->getLastTenFlights();
    
        //if you want you can put this additional login in the method too... 
        foreach ($flights as $flight) {
            if ( $flight->price == 0 )
            {
                $output = "some value";
            }
            else
            {
                $output = "some other value";
            }
        }
    
        return view('flights.index')
                ->with(['output'   => $output])
                ;
    }
    

    【讨论】:

    • 谢谢@Moppo。我原以为 Laravel 开发人员会计划在 Laravel's directory structure 中的存储库?他们有别的名字吗?
    • @user3489502 :他们没有自己的目录。您可以将它们放置在您喜欢的任何位置。对于一个小项目app/Repositories 很好
    • 它和我们所说的辅助函数一样吗?谢谢,只是想了解框架中使用的命名法。
    • @user3489502 :它不仅仅是一个简单的辅助函数:您可以将其视为一个类,您可以在其中放置有关飞行模型的所有方法
    【解决方案2】:

    您可以创建一个对象并在需要时调用该对象。

    查看示例:

    FlighRepository = new FlighRepository;
    
    FlighRepository->index();
    

    【讨论】:

      【解决方案3】:

      我个人更喜欢查询范围而不是存储库,所以我会这样做:

      class Flight extends Model
      {
      
          // model setup
      
          /**
           * Scope query to get last 10 flights.
           *
           * @param \Illuminate\Database\Eloquent\Builder $query
           * @return \Illuminate\Database\Eloquent\Builder
           */
          public function scopeLastTen($query)
          {
              return $query->where('active', 1)->orderBy('name', 'desc')->take(10);
          }
      
          // rest of model
      }
      

      您可以像当前使用它一样使用它,只是它更具可读性:

      $flights = Flight::lastTen()->get();
      

      这还具有能够将其他查询链接起来的优点。例如,假设您想要美国航空公司的最后十个航班,您可以这样做:

      $flights = Flight::lastTen()->where('airline', 'American')->get();
      // equivalent to
      // $flights = Flight::where('airline', 'American')->lastTen()->get();
      

      【讨论】:

      • 谢谢@Samsquanch,我想的不是$flights,而是$output,查询的结果+附加逻辑。
      • @user3489502 在这种情况下,您可能会混合使用我的答案和存储库答案。范围将数据提供给存储库,您可以在其中执行业务逻辑。
      【解决方案4】:

      我认为服务是存储控制器和命令之间共享的功能的最佳选择。您可以使用服务容器 (https://laravel.com/docs/5.5/container) 访问它们。

      【讨论】:

      • 感谢您的链接,所以它基本上是一个类似@Moppo 提议的存储库。
      • 其实不是。像往常一样的存储库旨在用于数据获取/操作。服务没有这样的限制。但是,确实,在这种特殊情况下,存储库是最好的选择。
      猜你喜欢
      • 1970-01-01
      • 2015-10-08
      • 2012-01-16
      • 2011-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-03
      • 1970-01-01
      相关资源
      最近更新 更多