yii2 POST 参数映射
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 参数没有映射到方法参数。
谢谢
class ManageController extends Controller {
public function actionAddShops() {
var_dump($_POST);
}
给你。
因此,没有原生 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',]
当您将参数传递给控制器操作时,这些参数只有在 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'];
}
$.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}
然后检查它是否可以完美运行。
你是对的,出于某种原因,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
。
希望对您有所帮助。
只需添加到您的控制器:
public function bindActionParams($action, $params)
{
return array_merge($params, Yii::$app->getRequest()->getBodyParams());
}
actionAddShops 将从 post body 接收 $id 和 $shops。
我有一些发送模拟数据的 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 参数没有映射到方法参数。 谢谢
class ManageController extends Controller {
public function actionAddShops() {
var_dump($_POST);
}
给你。
因此,没有原生 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',]
当您将参数传递给控制器操作时,这些参数只有在 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'];
}
$.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}
然后检查它是否可以完美运行。
你是对的,出于某种原因,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
。
希望对您有所帮助。
只需添加到您的控制器:
public function bindActionParams($action, $params)
{
return array_merge($params, Yii::$app->getRequest()->getBodyParams());
}
actionAddShops 将从 post body 接收 $id 和 $shops。