Laravel - 多次使用控制器

时间:2016-03-21 15:53:40

标签: php laravel

我正在将页面转换为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]);
    }
}

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

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

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

1 个答案:

答案 0 :(得分: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组件。