php - Yii2: how to populate a Gridview column using a SQL query?

I have a GridView with two columns: Id and Lastname.

The Id columns works great but I have a problem with the Lastname column: I need to execute a simple SQL query SELECT lastname FROM persons to complete the Lastname column.

I don't know how to do it. This is what I tried:

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        'id',
        [
            'label' => 'Lastname',
            'value' => function() {
                $myQuery = 'SELECT lastname FROM persons';
                return = Yii::$app->getDb()->createCommand($myQuery)->queryAll(); // Problem here.
            }
        ]
    ]
)] ?>

My DataProvider of my PersonsSearch.php model (is it possible to add my sql query here?):

public function search($params)
{
    $query = Persons::find();

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
        'sort' => [
            'defaultOrder' => [
                'id' => SORT_ASC
            ]
        ],
    ]);

    $this->load($params);

    if (!$this->validate()) {
        return $dataProvider;
    }

    $query->andFilterWhere([
        'id' => $this->id,
    ]);

    $query->andFilterWhere(['ilike', 'id', $this->id]);

    return $dataProvider;
}

Answer

Solution:

What do you have in $dataprovider? If it is loaded with objects from persons table, you can call it like id - lastname or you can call it like that:

[
            'label' => 'Lastname',
            'value' => function($model) {
                 return $model->lastname;
            }
]

In PersonsSearch.php

public function rules()
{
    return [
        [['id'], 'integer'],
        [['lastname'], 'safe'],
    ];
}

and search function

public function search($params)
{
    $query = Persons::find();

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
        'sort' => [
            'defaultOrder' => [
                'id' => SORT_ASC
            ]
        ],
    ]);

    $this->load($params);

    if (!$this->validate()) {
        return $dataProvider;
    }

    $query->andFilterWhere([
        'id' => $this->id,
    ]);

    $query->andFilterWhere(['ilike', 'id', $this->id]);
    $query->andFilterWhere(['like', 'lastname', $this->lastname]);

    return $dataProvider;
}

Other way when you have

 [
                'label' => 'Lastname',
                'value' => function($model) {
                     return $model->getLastName();
                }
    ]

Create function in Persons.php model with name getLastName()

public function getLastName(){
   $myQuery = 'SELECT lastname FROM persons'; //maybe you have where condition "where id = {$this->id}" ?
   $result = Yii::$app->getDb()->createCommand($myQuery)->queryOne();
   if($result){
        return $result['lastname'];
   }
}

If you have many rows, then use queryAll() and foreach the result.

Source