Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

yii2 POST parameters mapping

Tags:

php

mapping

yii2

i have some js script that send simular data:

    $.ajax({
        type: "POST",
        url: '/manage/add-shops/',
        data: {'id':id, 'shops': shops}

'shops' is array with ~1000 elements, so i should send it via POST. I have a yii2 Controller with method:

class ManageController extends Controller {
    public function actionAddShops($id, $shops=array()) {
       ....
    }

Routing is Ok, but i get this error:

"Missing required parameters: id"

It's look like that POST params doesn't mapped to method params. Thanks.

like image 590
arkhamvm Avatar asked Jan 29 '15 07:01

arkhamvm


2 Answers

You are right, for some reason, Yii2 only automatically binds GET variables, but unfortunately not POST.

However, you can easily do the magic binding; all you have to do is to override the runAction() of your controller. If you don't want to do it manually for every controller, just create a base controller and extend from it when required. Check the following snippet:

public function runAction($id, $params = [])
{
    // Extract the params from the request and bind them to params
    $params = \yii\helpers\BaseArrayHelper::merge(Yii::$app->getRequest()->getBodyParams(), $params);
    return parent::runAction($id, $params);
}

Then you will be able to access in your controller action $id and $shops normally as you used to do in Yii1.

Hope this helps.

like image 93
smich Avatar answered Sep 29 '22 05:09

smich


So, there is no native POST mapping, but we can implement it, like this:

class OurUrlRule extends UrlRule implements UrlRuleInterface {
    public function parseRequest($manager, $request, $add_post = true, $add_files = true) {
        $result = parent::parseRequest($manager, $request);
        if($result !== false) {
            list($route, $params) = $result;
            if($add_post    === true) {
                $params = array_merge($params,$_POST);
            }
            if($add_files   === true) {
                $params = array_merge($params,$_FILES);
            }
            return [$route, $params];
        }
        return false;
    }
}

And then, add to routes:

['pattern'=>'manage/<action:\S+>', 'route'=>'manage/<action>', 'suffix'=>'/', 'class' => 'app\components\OurUrlRule',]
like image 36
arkhamvm Avatar answered Sep 29 '22 07:09

arkhamvm