Yii2:定义除';ID';
我正试图利用yii2restapi(基于高级模板)创建我自己的服务。我当前正在成功使用以下URL返回一条“文章”记录: 我现在正试图复制此代码,以便它适用于其他记录类型。我的新记录有一个名为“key”的主键,我想通过它进行搜索。因此,我需要将参数名称“id”更改为“key” 有人能解释一下如何在此URL上指定“id”以外的参数吗?每当我省略id作为参数时,我都会得到一个“错误的请求:缺少必需的参数:id”。我不明白这个必需的参数来自何处,以及如何更改或添加它 相关类别如下所示:Yii2:定义除';ID';,yii2,yii2-advanced-app,Yii2,Yii2 Advanced App,我正试图利用yii2restapi(基于高级模板)创建我自己的服务。我当前正在成功使用以下URL返回一条“文章”记录: 我现在正试图复制此代码,以便它适用于其他记录类型。我的新记录有一个名为“key”的主键,我想通过它进行搜索。因此,我需要将参数名称“id”更改为“key” 有人能解释一下如何在此URL上指定“id”以外的参数吗?每当我省略id作为参数时,我都会得到一个“错误的请求:缺少必需的参数:id”。我不明白这个必需的参数来自何处,以及如何更改或添加它 相关类别如下所示: class A
class ArticleController extends ActiveController
{
/**
* @var string
*/
public $modelClass = 'frontend\modules\api\v1\resources\Article';
/**
* @var array
*/
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items'
];
/**
* @inheritdoc
*/
public function actions()
{
return [
'index' => [
'class' => 'yii\rest\IndexAction',
'modelClass' => $this->modelClass,
'prepareDataProvider' => [$this, 'prepareDataProvider']
],
'view' => [
'class' => 'yii\rest\ViewAction',
'modelClass' => $this->modelClass,
'findModel' => [$this, 'findModel']
],
'options' => [
'class' => 'yii\rest\OptionsAction'
]
];
}
/**
* @return ActiveDataProvider
*/
public function prepareDataProvider()
{
return new ActiveDataProvider(array(
'query' => Article::find()->published()
));
}
/**
* @param $id
* @return array|null|\yii\db\ActiveRecord
* @throws HttpException
*/
public function findModel($id)
{
$model = Article::find()
->published()
->andWhere(['id' => (int) $id])
->one();
if (!$model) {
throw new HttpException(404);
}
return $model;
}
}
class Article extends \common\models\Article implements Linkable
{
public function fields()
{
return ['id', 'slug', 'category_id', 'title', 'body', 'published_at'];
}
public function extraFields()
{
return ['category'];
}
/**
* Returns a list of links.
*
* @return array the links
*/
public function getLinks()
{
return [
Link::REL_SELF => Url::to(['article/view', 'id' => $this->id], true)
];
}
}
提前谢谢
编辑:“前端”文件夹结构中的urlManager规范如下:
<?php
return [
'class'=>'yii\web\UrlManager',
'enablePrettyUrl'=>true,
'showScriptName'=>false,
'rules'=> [
// Pages
['pattern'=>'page/<slug>', 'route'=>'page/view'],
// Articles
['pattern'=>'article/index', 'route'=>'article/index'],
['pattern'=>'article/attachment-download', 'route'=>'article/attachment-download'],
['pattern'=>'article/<slug>', 'route'=>'article/view'],
// Api
['class' => 'yii\rest\UrlRule', 'controller' => 'api/v1/article', 'only' => ['index', 'view', 'options']],
['class' => 'yii\rest\UrlRule', 'controller' => 'api/v1/user', 'only' => ['index', 'view', 'options']]
]
];
只需像往常一样在ArticleController
中创建新方法即可:
public function actionView2($your_desired_parameter) {
$article = Article::find()->where(['your_desired_parameter'=>$your_desired_parameter]);
if (!$article->exists())
throw new NotFoundHttpException();
return $article->one();
}
我不知道这是否是官方的做法,但我已经创造了一个额外的行动来应对这种情况。“id”参数似乎来自于反映动作中的“run”方法调用,因此我可以使用另一个名为“key”的参数的唯一方法是定义如下所示的函数:
class ExtraAction extends Action // in yii/rest
{
public function run($key) // NOTE: The name 'key' is reflected and then becomes an expected parameter
{
$model = $this->findModel($key);
if (!$model) {
throw new HttpException(404);
}
return $model;
}
}
完成后,我需要更改actions()定义,如下所示:
'view' => [
'class' => 'yii\rest\ExtraAction',
'modelClass' => $this->modelClass,
'findModel' => [$this, 'findModel']
],
然后,控制器中的findModel($id)将接收GET URL中定义的“key”参数(例如api/v1/article?key=blah123)
然后,我可以基于我拥有的不同唯一密钥执行查找:
public function findModel($id)
{
$model = Record::find()
->andWhere(['key_field' => $id])
->one();
}
我不知道这是否是正确的做法,但在这种情况下似乎确实有效 这可以通过在配置文档中向urlmanager添加规则来实现
例如:
'rules' => [
[ 'class' => 'yii\rest\UrlRule',
'pluralize' => false,
'controller' => [
'yourController',
],
'patterns' => [
'PUT,PATCH {id}' => 'update',
'DELETE {id}' => 'delete',
'GET,HEAD {id}' => 'view',
'GET,HEAD {key}' => 'view',
'POST' => 'create',
'GET,HEAD' => 'index',
'{id}' => 'options',
'OPTIONS' => 'options',
'PUT,PATCH {key}' => 'update',
],
'tokens' => [
'{id}' => '<id:\\d[\\d,]*>',
'{type}' => '<type:\\w[\\w,]*>',
'{key}' => '<key:\\w[\\w,]*>',
],
],
]
并将密钥参数添加到操作中
class ViewAction extends \yii\rest\ViewAction {
public function run($id = null, $key = null)
{
// your code
}
}
现在你应该可以这样做了
GET your/{keyparam}->wil resolve to yourController->ViewAction
检查ViewAction docs:,默认情况下需要接收$id
参数。我要做的是创建一个新操作,比如说view2
,然后添加您需要的功能。看起来您使用的规则与通常实现的规则不同。您还可以显示您的urlManager
设置吗?谢谢您的回复,@gmc。如果我按照您的建议创建一个新方法,您是否知道(或者可以让我参考文档)在哪里配置了“id”值?@Salem,我不确定在哪里可以找到urlManager设置(我有点新手)。您可以在配置文件中找到它。它是定义url规则的地方。你会在我之前评论中链接的文档中看到它。谢谢@gmc,尽管我需要在控制器中添加“view2”操作吗?如果是,我的“类”属性应该是什么?如果我将其设置为“ViewAction”,它将再次坚持我需要提供id。我不是100%确定,但我认为您不需要将其添加到此处。很遗憾,添加“actionView2”无效(“未找到页面”)。我似乎需要添加一个操作,但如果我将“查看”操作复制并粘贴为“查看2”,我再次需要提供一个“id”(即使使用您提到的代码)。Hi@Tim,您能告诉我在我的示例中只接受GET URL中的“key”而不接受“id”的具体设置吗?我已经尝试了所有这些设置的许多排列,但不知道如何省略'id'参数。不幸的是,这些文档对我来说并不是不言自明的。我尝试添加一个模式,说“GET,HEAD{key}”=>“view”,但这不起作用。@SimpleGuy对我的反应太晚表示歉意,但我已经更新了我的答案如何配置控制器和相应的视图,希望能有所帮助
class ViewAction extends \yii\rest\ViewAction {
public function run($id = null, $key = null)
{
// your code
}
}