yii2 开机自检参数映射


yii2 POST parameters mapping

我有一些发送模拟数据的JS脚本:

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

'shops' 是包含 ~1000 个元素的数组,所以我应该通过 POST 发送它。我有一个带有方法的 yii2 控制器:

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

路由正常,但我收到此错误:

"Missing required parameters: id"

看起来 POST 参数没有映射到方法参数。谢谢。

你是对的,出于某种原因,Yii2 只自动绑定 GET 变量,但不幸的是不是 POST。

但是,您可以轻松地进行魔术绑定;您所要做的就是覆盖控制器的runAction()。如果您不想为每个控制器手动执行此操作,只需创建一个基本控制器并在需要时从中扩展即可。检查以下代码片段:

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

然后,您将能够像以前在 Yii1 中一样正常访问控制器操作$id$shops

希望这有帮助。

所以,没有原生的 POST 映射,但我们可以实现它,就像这样:

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

然后,添加到路由:

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

只需添加到您的控制器:

public function bindActionParams($action, $params)
{
    return array_merge($params, Yii::$app->getRequest()->getBodyParams());
}

和动作添加商店将从帖子正文接收$id和$shops。

将参数传递给控制器操作时,这些参数仅在 url 的 GET 中可用。如果你通过 POST 发送参数,那么你需要通过 Yii::$app->request->post 方法访问它们。

所以你的函数最终看起来像这样;

enter class ManageController extends Controller {
public function actionAddShops() {
   $post = Yii::$app->request->post();
   $id = $post['id'];
   $shops = $post['shops'];
}
class ManageController extends Controller {
    public function actionAddShops() {
       var_dump($_POST);
    }

给你。

$.ajax({
    type: "POST",
    url: '/manage/add-shops/',
    data: {'id':id, 'shops': shops}
class ManageController extends Controller {
public function actionAddShops($id, $shops=array()) {
   ....
}

我从您的代码中了解到的是,您正在使用 POST 方法通过 ajax 传递值,但是如果您在控制器中使用带有参数的操作方法,则意味着此操作需要使用 GET 方法。因此,只需将您的 ajax 方法更改为

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

然后检查它会完美运行。