我正在Laravel 8的博客应用上工作。
在FrontendController控制器中,我有:
namespace App\Http\Controllers;
use App\Models\Settings;
use App\Models\ArticleCategory;
class FrontendController extends Controller
{
protected $site_settings;
protected $theme_directory;
protected $site_name;
protected $tagline;
protected $owner_name;
protected $article_categories;
public function __construct()
{
$this->site_settings = Settings::first();
$this->theme_directory = $this->site_settings['theme_directory'] ?? null;
$this->site_name = $this->site_settings['site_name'] ?? null;
$this->tagline = $this->site_settings['tagline'] ?? null;
$this->owner_name = $this->site_settings['owner_name'] ?? null;
// Article categories
$this->article_categories = ArticleCategory::all();
}
}ArticlesController控制器扩展了上面的一个控制器:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\ArticleCategory;
use App\Models\Article;
class ArticlesController extends FrontendController {
// Articles per page
protected $per_page = 12;
public function index(Request $request) {
// Search query
$qry = $request->input('search');
$articles = Article::where('title', 'like', '%' . $qry . '%')
->orWhere('short_description', 'like', '%' . $qry . '%')
->orWhere('content', 'like', '%' . $qry . '%')
->orderBy('id', 'desc')
->paginate($this->per_page);
// Search results count
if ($request->input('search')){
$article_count = Article::where('title', 'like', '%' . $qry . '%')
->orWhere('short_description', 'like', '%' . $qry . '%')
->orWhere('content', 'like', '%' . $qry . '%')
->count();
}
return view('themes/' . $this->theme_directory . '/templates/index',
[
'theme_directory' => $this->theme_directory,
'search_query' => $qry,
'site_name' => $this->site_name,
'tagline' => $this->tagline,
'owner_name' => $this->owner_name,
'categories' => $this->article_categories,
'articles' => $articles,
'article_count' => $article_count ?? null
]
);
}
public function category($category_id) {
$category = ArticleCategory::where('id', $category_id)->first();
$articles = Article::where('category_id', $category_id)->paginate($this->per_page);
return view('themes/' . $this->theme_directory . '/templates/index',
[
'theme_directory' => $this->theme_directory,
'site_name' => $this->site_name,
'tagline' => $this->tagline,
'owner_name' => $this->owner_name,
'categories' => $this->article_categories,
'category' => $category,
'articles' => $articles
]
);
}
public function show($slug) {
// Single article
$article = Article::where('slug', $slug)->first();
return view('themes/' . $this->theme_directory . '/templates/single',
[
'theme_directory' => $this->theme_directory,
'site_name' => $this->site_name,
'tagline' => $this->tagline,
'owner_name' => $this->owner_name,
'categories' => $this->article_categories,
'article' => $article
]
);
}
}posts列表视图(index.blade.php):
@extends('themes/' .$theme_directory . '/layout')
@section('content')
{{ $site_name }}
@if(isset($category))
{{ $category->name }}
@else
{{ $tagline }}
@endif
@if (isset($search_query))
We found {{ $article_count }} posts containing {{ $search_query }}:
@endif
@if (count($articles))
@foreach ($articles as $article)
{{ $article->title }}
{{ $article->short_description }}
Posted by
{{ $article->user->first_name }} {{ $article->user->last_name }}
on {{ date('j F, Y', strtotime($article->created_at)) }}
@endforeach
@endif
@if($articles->hasPages())
← Newer Posts
Older Posts →
@endif
@endsection发布于 2022-08-03 15:22:25
在这两个控制器中减少代码重复的最佳方法是什么?
如果第一个设置记录和$article_categories中的这四个值适用于所有视图,那么它们可以与所有的观点共享。将使用App\Providers\AppServiceProvider的boot()方法中的View facade的share()方法。然后可能不需要在FrontEndController的构造函数中包含这些行,并且成员变量也可以被消除。
否则,如果设置记录中的值仅适用于某些视图,则可以定义辅助方法(S)以获取要发送到视图的数据。在两个方法index()和show()中,前四个条目被重复,因此这些条目可以通过一个新的助手方法返回,而另一个数据输入--例如articles或article --可以通过array_merge()或数组联合算子添加--即+。
在FrontEndController构造函数中,可以使用循环来迭代需要从设置记录中设置的属性。
在ArticlesController::show()方法中,可以提取这三行:
文章:哪里(“标题”,“喜欢”,“%”)。$qry。->orWhere('short_description','like','%‘。$qry。->orWhere(“内容”、“喜欢”、“%”)。$qry。“%”)
并分配给像$articlesQuery这样的局部变量,然后可以用来生成$articles和$article_count。
是否有任何代码优化的机会?
如果site_settings只在构造函数中使用,那么它可能不需要是一个成员变量--它可以只是一个局部变量。
在ArticlesController::category()方法中,使用查询获取类别的行:
$category =第一类:其中(‘id’,$category_id)->first();
可以使用firstWhere()方法进行简化:
$category = ArticleCategory::firstWhere('id', $category_id);同样的情况也适用于show()方法的第一行,即逐条查找文章。
ArticlesController::$per_page是否得到与12不同的值?如果没有,则可以将其声明为常数。
变量解析 (也称为字符串内插)可以用来简化'%' . $qry . '%'到”%$qry%”的实例。
发布于 2022-08-06 07:57:26
关于设计的想法:
因为Settings是一个模型,最后返回了一些配置和结构的响应。我肯定会鼓励您将它作为API资源使用。您可以将数据设置为所需的结构/格式(您正在使用FrontEndController ),但它似乎是一种资源功能。在这里阅读文档:https://laravel.com/docs/9.x/eloquent-resources
另一点,请查看存储库模式。您将有一个单独的层与数据库交互(检索,创建..。等)。因此,您可以为Settings或Articles创建一个存储库--例如,获取它们,并将它们交给它们的参考资料,根据响应的需要组装它们。
https://codereview.stackexchange.com/questions/278491
复制相似问题