S
S
Sergey Erin2021-06-21 11:33:39
Yii
Sergey Erin, 2021-06-21 11:33:39

How to optimize controller in Yii2?

Good day! In the project, some controller actions contain a lot of selections from the database, for example

/** @var Question|null $question */
$question = Question::findOne([
    'url' => $slug,
    'deleted' => 0,
    'moderated' => 0
]);

$id = $question->id;

/** @var Question $question Вопрос */
$question = Question::find()
    ->with('screenshot')
    ->select([
        Question::tableName() . '.*',
        'SUM(views) as totalViews'
    ])
    ->joinWith('postView')
    ->with(['category', 'subcat'])
    ->where([Question::tableName() . '.slug' => $slug])
    ->one();

/** @var array $lastQuestions */
$lastQuestions = Question::find()
    ->where([
        'moderated' => 0,
        'deleted' => 0
    ])
    ->andWhere('id != ' . $question->id)
    ->orderBy('published_date DESC')
    ->limit(4)
    ->all();

/** @var array $similarQuestions */
$similarQuestions = Question::find()
    ->where([
        'moderated' => 0,
        'deleted' => 0
    ])
    ->andWhere(['not in', 'id', ArrayHelper::getColumn($lastQuestions, 'id')])
    ->andWhere('id != ' . $question->id)
    ->limit(6)
    ->all();

$countComment = QuestionComment::find()
    ->where([
        'id' => $id,
        'deleted' => 0,
    ])
    ->count();

The documentation advises to make controllers lighter. Tell me how you can optimize such controller code and in general what material can you advise on the best development practices in Yii? Thanks in advance!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
vitaly_74, 2021-06-21
@artalexs

About the material: https://elisdn.ru/blog/search?q=yii2
or use the DTO pattern - and put all the queries you need in the action into it and it will turn out something like this:
$dto->similarQuestions()
or you can go more next and create an Active Query as done here https://github.com/ElisDN/yii2-demo-catalog/blob/m...
and then you can do this:
$dto->questions()->similar();
$dto->questions()->last();
$dto->questions()->count(); //or use a link here and call count as a property.
Well, in the future, if you need to, just optimize the questions queries either in the DTO file or its components directly in the QuestionsSubQuery file (or just call it QuestionsQuery)

I
Ilya, 2021-06-21
@rpsv

Code snippet: Question::find(), generates an ActiveQuery, inherit from the standard one, and implement frequently used constructs in it.
Documentation: https://www.yiiframework.com/doc/guide/2.0/en/db-a...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question