【问题标题】:Laravel - Using controller multiple timesLaravel - 多次使用控制器
【发布时间】:2016-03-21 15:53:39
【问题描述】:

我正在将一个页面转换为 Laravel。 我曾经有一个 PHP 脚本 (GET) 可以处理来自任何表的选择查询。我所要做的就是发送 table 参数,它会返回结果。

这个想法是有一个这样的控制器:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use DB;

class Projects extends Controller
{
    /**
     * Get projects based on the table
     *
     * @return Response
     */
    public function index($table)
    {
        $result = DB::select("SELECT projectid FROM `" . $table . "` WHERE isClass=1 LIMIT 10");

        return view('pages.allviews', ['results' => $result]);
    }
}

问题是该页面将执行此查询 3 次。 发生这种情况,控制器会在执行后立即创建视图,唯一的解决方案是在控制器中重复查询 3 次。

我想避免这样做,我想将控制器与页面需要的内容分开,并能够在页面需要的时间执行它。概括是关键。

有没有办法做到这一点,并保持这种抽象,而不必创建新的控制器?

【问题讨论】:

  • 创建另一个类,只要它的命名空间正确,您可以在需要时引用它。
  • 你能给我举个例子,我如何为同一个视图引用它三次吗?
  • 使用 \path\for\namespace\classname,然后 $this->data['grabbed_stuff'] = classname::method(); 然后是 view('some.view',$this->data)。 $grabbed_stuff 将显示在您的视图中

标签: php laravel


【解决方案1】:

有很多方法可以做到这一点,但最重要的是,您应该将查询逻辑从控制器提取到一个单独的类中,以便您可以重用该对象。基本上,存储库类对此很有用,但也可以创建查询对象。无论如何,让我们保持简单。因此,正如我所提到的,您有很多选择,并且根据您的项目,您可以决定策略。

在您的情况下,您可以简单地使用DB::table() 方法并将其缓存一段时间,以便在接下来的后续调用中返回缓存的结果。立即查看示例:

$limit = 10;
$table = 'users';
$select = ['id', 'name'];
$result = \Cache::remember($table, 60, function() use ($table, $select, $limit) {
    return \DB::table($table)->limit($limit)->get($select);
});

然后要访问缓存的查询,您可以使用:

if(\Cache::has('users')) {
    $users = \Cache::get('users');
}

因此,虽然这可能会解决您的问题,但我建议您创建一个单独的类并将该查询逻辑(带有缓存)保留在该类中,例如:

namespace Some\Namespace;

use DB, Cache;

class CachedQuery {

    public function getResult($table, $select = '*', $limit = 10, $timeout = 60)
    {
        return Cache::remember($table, $timeout, function() use ($table, $select, $limit) {
            return DB::table($table)->limit($limit)->get($select);
        });
    }
}

然后像这样使用它:

use Some\Namespace\CachedQuery;

class SomeController extends Controller {
    public function index(CachedQuery $cachedQuery, $table)
    {
        // The $table parameter is required, rest are optional
        $result = $cachedQuery->getResult($table, ['projectid']);
    }
}

另外,您可以使用IoC/Service Container 对象来临时存储数据。此外,可以创建一个接口并将该接口绑定到一个类以从 Service Container 中获取它,但我尽可能保持简单。希望你明白了。另外,检查Cache 组件。

【讨论】:

  • 谢谢,很有用。但是想象一下,我想在一个视图中进行很多查询,所有这些查询都不同,并且每个查询都有一个控制器。如何为同一个视图调用每个控制器?
  • 好吧,你不应该从视图中进行查询。
  • 那么,考虑到这是正常行为和可能的常见用途,我应该怎么做呢?只需在页面内调用查询,只要我需要它?或者有没有抽象的方法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-14
  • 1970-01-01
  • 2020-02-29
  • 1970-01-01
  • 2021-01-19
  • 1970-01-01
相关资源
最近更新 更多