Clean Urls with GET Params

I built a search form which is working fine. But my url on search is a long long string containing all field names (even the not used ones). This is ugly. On the other hand, if I use POST, url is clean but the search won’t work.

How do I get a clean url using GET? Or… How does it work well with POST?

The search form:

<div class="sysactivitylog-search">


    <?php $form = ActiveForm::begin([

        'action' => ['index'],

        'method' => 'get', // if I change this to POST it doesn't work, but url is clean.

    ]); ?>

....... the usual stuff ....

The search method within model:

    public function search($params)


        $query = Sysactivitylog::find();

        $dataProvider = new ActiveDataProvider([

            'query' => $query,

            'sort' => ['defaultOrder' => ['inserted_date' => SORT_DESC]],

            'pagination' => ['pageSize' => 100],



        if (!$this->validate()) {

            // uncomment the following line if you do not want to return any records when validation fails

            // $query->where('0=1');

            return $dataProvider;



            'id' => $this->id,

            'inserted_date' => $this->inserted_date,


        $query->andFilterWhere(['like', 'username', $this->username])

            ->andFilterWhere(['like', 'func', $this->func])

            ->andFilterWhere(['like', 'ip_user', $this->ip_user])

            ->andFilterWhere(['like', 'description', $this->description]);

           $query->andFilterWhere(['>=', 'date(inserted_date)', $this->from_date])

               ->andFilterWhere(['<=', 'date(inserted_date)', $this->to_date]);

        return $dataProvider;



The controller:

    public function actionIndex()


            $searchModel = new SysactivitylogSearch();

            $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

            //note: if instead of Yii::$app->request->queryParams i use Yii::$app->request->post() it will work.

            //but then search fields on gridview headers won't work.

            return $this->render('index', [

                'searchModel' => $searchModel,

                'dataProvider' => $dataProvider,



Technical standards aren’t about aesthetics. Query params belong to the query string part of the URL and there’s nothing wrong with it in your case because

  • search engines won’t fill and send search forms so no URL-optimization required

  • human visitors are very unlikely to type search URLs manually and they don’t really care what the browser shows them in the address bar.

Thank you phtamas for your answer.

I know all that… But I really don´t want my users to play with urls trying to guess things. Besides, from my personal point of view… it’s ugly. There is nothing wrong in avoiding uglyness if possible.

But I agree with you. This is not of course a major issue…

I will try making it work with POST somehow.

To those who may be interested:

The solution is working with POST. Ever. In order to do so, your activeform for search (if you have one) must use POST instead of GET. Then your gridview must use pjax. Just wrap your gridview between pjax begin and end like this:

 <?php \yii\widgets\Pjax::begin(['id' => 'some-id-you-like', 

            'timeout' => false, 

            'enablePushState' => false, 

            'clientOptions' => ['method' => 'POST']]); ?>

    <?= GridView::widget([

    ... your gridview usual configuration...

    ... if you are using kartik gridview dont set 'pjax'=>true

    ]); ?>

    <?php \yii\widgets\Pjax::end(); ?>

And then, in your controller, replace…

$dataProvider = $searchModel->search(Yii::$app->request->queryParams);

By this…

$dataProvider = $searchModel->search(Yii::$app->request->post());

All works well, and no more text book urls…

Beside search engine, which in application behind authentication does not apply, having search parameter on the url is useful for the user so they can save the link with all the parameter to be reused for future search.

For normal non complex search it does not make big difference, but for advanced search in which the user need to fill many filed to seek the information he need, it can make the difference.

On the other hand if the users are not aware of this possibility (and most are not), only few use it

Is setting "enablePushState" to false not enough?

I believe you don’t have to use post method.

One thing we must not miss is the fact that pjax enables the browser to store the history of the ajax-updated results. "Back" button will not bring you to the previous page, but to the same page with the last search parameters. Or, after you have moved to a detail page from the current search result, "back" button will not reset the search parameters but restore them to display the same result.

Isn’t it handy? I think it outweighs the ugliness, if any.