web-dev-qa-db-fra.com

yii2 POST cartographie des paramètres

j'ai un script JS qui envoie des données similaires:

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

'shops' est un tableau avec ~ 1000 éléments, je dois donc l'envoyer via POST. J'ai un contrôleur yii2 avec la méthode suivante:

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

Le routage est bon, mais j'obtiens cette erreur:

"Missing required parameters: id"

On dirait que POST les paramètres ne sont pas associés aux paramètres de méthode. Merci.

7
arkhamvm

Donc, il n'y a pas de mappage POST natif, mais nous pouvons l'implémenter, comme ceci:

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;
    }
}

Et puis, ajoutez aux routes:

['pattern'=>'manage/<action:\S+>', 'route'=>'manage/<action>', 'suffix'=>'/', 'class' => 'app\components\OurUrlRule',]
1
arkhamvm

Vous avez raison, pour une raison quelconque, Yii2 ne lie automatiquement que les variables GET, mais malheureusement pas POST. 

Cependant, vous pouvez facilement faire la liaison magique; tout ce que vous avez à faire est de remplacer la runAction() de votre contrôleur. Si vous ne voulez pas le faire manuellement pour chaque contrôleur, créez simplement un contrôleur de base et étendez-le à la demande. Vérifiez l'extrait suivant:

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);
}

Ensuite, vous pourrez accéder dans votre contrôleur aux actions $id et $shops normalement comme vous le faisiez dans Yii1.

J'espère que cela t'aides.

6
smich