Based on Yii 2.0, the API of RESTful-style web service service is realized. In the request parameter, only one parameter supports data filling and validation of multiple parameter values (ie array, list input) and validation.
1. Posthttp://api.channel-pub-api.localhost/qq/v1/articles?group_id=015ce30b116ce86058fa6ab4fea4ac63, as shown in Figure 1
{
"uuid": "e88e79faad9011e8a14554ee75d2ebc1",
"article_type_code": "standard",
"article_category_id": 1,
"title": "标题 - 20180904 - 1",
"author": "作者 - 20180904 - 1",
"source": "spider",
"source_user_id": 1,
"source_article_id": 1,
"content": "文章内容 - 20180904 - 1",
"cover_pic": "/upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif",
"cover_type": 1,
"tag": "",
"apply": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
}
Print request parameters:
Array
(
[uuid] => e88e79faad9011e8a14554ee75d2ebc1
[article_type_code] => standard
[article_category_id] => 1
[title] => 标题 - 20180904 - 1
[author] => 作者 - 20180904 - 1
[source] => spider
[source_user_id] => 1
[source_article_id] => 1
[content] => 文章内容 - 20180904 - 1
[cover_pic] => /upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif
[cover_type] => 1
[tag] =>
[apply] => 0
[original_platform] => 0
[original_url] =>
[original_author] =>
[group_id] => 015ce30b116ce86058fa6ab4fea4ac63
)
2. Posthttp://api.channel-pub-api.localhost/qq/v1/articles?group_id=015ce30b116ce86058fa6ab4fea4ac63, the request parameter UUID is the array format, as shown in Figure 2
{
"uuid": [
"e88e79faad9011e8a14554ee75d2ebc1",
"9f359272b00e11e8875654ee75d2ebc1"
],
"article_type_code": "standard",
"article_category_id": 1,
"title": "标题 - 20180904 - 1",
"author": "作者 - 20180904 - 1",
"source": "spider",
"source_user_id": 1,
"source_article_id": 1,
"content": "文章内容 - 20180904 - 1",
"cover_pic": "/upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif",
"cover_type": 1,
"tag": "",
"apply": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
}
Print request parameters:
Array
(
[uuid] => Array
(
[0] => e88e79faad9011e8a14554ee75d2ebc1
[1] => 9f359272b00e11e8875654ee75d2ebc1
)
[article_type_code] => standard
[article_category_id] => 1
[title] => 标题 - 20180904 - 1
[author] => 作者 - 20180904 - 1
[source] => spider
[source_user_id] => 1
[source_article_id] => 1
[content] => 文章内容 - 20180904 - 1
[cover_pic] => /upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif
[cover_type] => 1
[tag] =>
[apply] => 0
[original_platform] => 0
[original_url] =>
[original_author] =>
[group_id] => 015ce30b116ce86058fa6ab4fea4ac63
)
3. Check \QQ\RESTS\Article\CreateAction.php, when the value of UUID is a single string, it is filled with the verification code
/**
* Creates a new model.
* @return \yii\db\ActiveRecordInterface the model newly created
* @throws ServerErrorHttpException if there is any error when creating the model
*/
public function run()
{
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id);
}
$requestParams = Yii::$app->getRequest()->getBodyParams();
/* 判断请求体参数中租户ID是否存在 */
if (!isset($requestParams['group_id'])) {
$requestParams = ArrayHelper::merge($requestParams, ['group_id' => Yii::$app->params['groupId']]);
}
/* 标准(普通、图文)的文章发布参数 */
$qqArticleStandardCreateParam = new QqArticleStandardCreateParam();
// 把请求数据填充到模型中
if (!$qqArticleStandardCreateParam->load($requestParams, '')) {
return ['code' => 40009, 'message' => Yii::t('error', '40009')];
}
// 验证模型
if (!$qqArticleStandardCreateParam->validate()) {
$qqArticleStandardCreateParamResult = self::handleValidateError($qqArticleStandardCreateParam);
if ($qqArticleStandardCreateParamResult['status'] === false) {
return ['code' => $qqArticleStandardCreateParamResult['code'], 'message' => $qqArticleStandardCreateParamResult['message']];
}
}
/* 基于文章类型代码定义场景 */
$this->scenario = 'qq_article_' . $qqArticleStandardCreateParam->article_type_code . '_create';
/* 实例化多个模型 */
// 企鹅号的第三方服务平台应用的企鹅媒体用户
$qqTpAppPenguin = new QqTpAppPenguin([
'scenario' => $this->scenario,
]);
// 转换标准(普通、图文)的文章发布参数,多模型的填充、验证的实现
$requestParams[$qqTpAppPenguin->formName()]['uuid'] = $qqArticleStandardCreateParam->uuid;
$qqTpAppPenguinResult = self::handleLoadAndValidate($qqTpAppPenguin, $requestParams);
if ($qqTpAppPenguinResult['status'] === false) {
return ['code' => $qqTpAppPenguinResult['code'], 'message' => $qqTpAppPenguinResult['message']];
}
}
/**
* 处理模型填充与验证
* @param object $model 模型
* @param array $requestParams 请求参数
* @return array
* 格式如下:
*
* [
* 'status' => true, // 成功
* ]
*
* [
* 'status' => false, // 失败
* 'code' => 20004, // 返回码
* 'message' => '数据验证失败:企鹅号ID(UUID)是无效的。', // 说明
* ]
*
* @throws ServerErrorHttpException
*/
public static function handleLoadAndValidate($model, $requestParams)
{
// 把请求数据填充到模型中
if (!$model->load($requestParams)) {
return ['status' => false, 'code' => 40009, 'message' => Yii::t('error', '40009')];
}
// 验证模型
if (!$model->validate()) {
return self::handleValidateError($model);
}
return ['status' => true];
}
/**
* 处理模型错误
* @param object $model 模型
* @return array
* 格式如下:
*
* [
* 'status' => false, // 失败
* 'code' => 20004, // 返回码
* 'message' => '数据验证失败:代码是无效的。', // 说明
* ]
*
* @throws ServerErrorHttpException
*/
public static function handleValidateError($model)
{
if ($model->hasErrors()) {
$response = Yii::$app->getResponse();
$response->setStatusCode(422, 'Data Validation Failed.');
foreach ($model->getFirstErrors() as $message) {
$firstErrors = $message;
break;
}
return ['status' => false, 'code' => 20004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '20004'), ['firstErrors' => $firstErrors]))];
} elseif (!$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
}
}
4. Reference URL:https://www.yiiframework.com/doc/guide/2.0/zh-cn/input-tabular-input, edit \QQ\RESTS\Article\CreateAction.php, when the value of UUID is an array, it is filled with the verification code
/**
* Creates a new model.
* @return \yii\db\ActiveRecordInterface the model newly created
* @throws ServerErrorHttpException if there is any error when creating the model
*/
public function run()
{
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id);
}
$requestParams = Yii::$app->getRequest()->getBodyParams();
/* 判断请求体参数中租户ID是否存在 */
if (!isset($requestParams['group_id'])) {
$requestParams = ArrayHelper::merge($requestParams, ['group_id' => Yii::$app->params['groupId']]);
}
/* 标准(普通、图文)的文章发布参数 */
$qqArticleStandardCreateParam = new QqArticleStandardCreateParam();
// 把请求数据填充到模型中
if (!$qqArticleStandardCreateParam->load($requestParams, '')) {
return ['code' => 40009, 'message' => Yii::t('error', '40009')];
}
// 验证模型
if (!$qqArticleStandardCreateParam->validate()) {
$qqArticleStandardCreateParamResult = self::handleValidateError($qqArticleStandardCreateParam);
if ($qqArticleStandardCreateParamResult['status'] === false) {
return ['code' => $qqArticleStandardCreateParamResult['code'], 'message' => $qqArticleStandardCreateParamResult['message']];
}
}
/* 基于文章类型代码定义场景 */
$this->scenario = 'qq_article_' . $qqArticleStandardCreateParam->article_type_code . '_create';
/* 实例化多个模型 */
// 企鹅号的第三方服务平台应用的企鹅媒体用户
if (!is_array($requestParams['uuid'])) {
return ['code' => 40009, 'message' => Yii::t('error', '40009')];
}
$count = count($requestParams['uuid']);
// 创建一个初始的 $qqTpAppPenguins 数组包含一个默认的模型
$qqTpAppPenguins = [new QqTpAppPenguin([
'scenario' => $this->scenario,
])];
for($i = 1; $i < $count; $i++) {
$qqTpAppPenguins[] = new QqTpAppPenguin([
'scenario' => $this->scenario,
]);
}
foreach ($requestParams['uuid'] as $key => $uuid) {
// 转换标准(普通、图文)的文章发布参数,多模型的填充、验证的实现
$requestParams[$qqTpAppPenguins[0]->formName()][$key]['uuid'] = $uuid;
}
// 批量填充模型属性
if (!Model::loadMultiple($qqTpAppPenguins, $requestParams, $qqTpAppPenguins[0]->formName())) {
return ['code' => 40009, 'message' => Yii::t('error', '40009')];
}
// 批量验证模型
if (!Model::validateMultiple($qqTpAppPenguins)) {
$qqTpAppPenguinsResult = self::handleValidateMultipleError($qqTpAppPenguins);
if ($qqTpAppPenguinsResult['status'] === false) {
return ['code' => $qqTpAppPenguinsResult['code'], 'message' => $qqTpAppPenguinsResult['message']];
}
}
}
/**
* 处理模型填充与验证
* @param object $model 模型
* @param array $requestParams 请求参数
* @return array
* 格式如下:
*
* [
* 'status' => true, // 成功
* ]
*
* [
* 'status' => false, // 失败
* 'code' => 20004, // 返回码
* 'message' => '数据验证失败:企鹅号ID(UUID)是无效的。', // 说明
* ]
*
* @throws ServerErrorHttpException
*/
public static function handleLoadAndValidate($model, $requestParams)
{
// 把请求数据填充到模型中
if (!$model->load($requestParams)) {
return ['status' => false, 'code' => 40009, 'message' => Yii::t('error', '40009')];
}
// 验证模型
if (!$model->validate()) {
return self::handleValidateError($model);
}
return ['status' => true];
}
/**
* 处理模型错误
* @param object $model 模型
* @return array
* 格式如下:
*
* [
* 'status' => false, // 失败
* 'code' => 20004, // 返回码
* 'message' => '数据验证失败:代码是无效的。', // 说明
* ]
*
* @throws ServerErrorHttpException
*/
public static function handleValidateError($model)
{
if ($model->hasErrors()) {
$response = Yii::$app->getResponse();
$response->setStatusCode(422, 'Data Validation Failed.');
foreach ($model->getFirstErrors() as $message) {
$firstErrors = $message;
break;
}
return ['status' => false, 'code' => 20004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '20004'), ['firstErrors' => $firstErrors]))];
} elseif (!$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
}
}
/**
* 处理模型错误
* @param array $models 模型列表
* @return array
* 格式如下:
*
* [
* 'status' => false, // 失败
* 'code' => 20004, // 返回码
* 'message' => '数据验证失败:代码是无效的。', // 说明
* ]
*
* @throws ServerErrorHttpException
*/
public static function handleValidateMultipleError($models)
{
foreach ($models as $model) {
if ($model->hasErrors()) {
$response = Yii::$app->getResponse();
$response->setStatusCode(422, 'Data Validation Failed.');
foreach ($model->getFirstErrors() as $message) {
$firstErrors = $message;
break;
}
return ['status' => false, 'code' => 20004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '20004'), ['firstErrors' => $firstErrors]))];
}
}
throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
}
5. Posthttp://api.channel-pub-api.localhost/qq/v1/articles?group_id=015ce30b116ce86058fa6ab4fea4ac63, the request parameter uuid is a string format, the response fails, as expected
{
"uuid": "e88e79faad9011e8a14554ee75d2ebc1",
"article_type_code": "standard",
"article_category_id": 1,
"title": "标题 - 20180904 - 1",
"author": "作者 - 20180904 - 1",
"source": "spider",
"source_user_id": 1,
"source_article_id": 1,
"content": "文章内容 - 20180904 - 1",
"cover_pic": "/upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif",
"cover_type": 1,
"tag": "",
"apply": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
}
{
"code": 40009,
"message": "数据模型填充失败"
}
6. Posthttp://api.channel-pub-api.localhost/qq/v1/articles?group_id=015ce30b116ce86058fa6ab4fea4ac63, the request parameter uuid is in the array format, there is only 1 key-value pair, its value is wrong, the response fails, as expected
{
"uuid": [
"e88e79faad9011e8a14554ee75d2ebc10"
],
"article_type_code": "standard",
"article_category_id": 1,
"title": "标题 - 20180904 - 1",
"author": "作者 - 20180904 - 1",
"source": "spider",
"source_user_id": 1,
"source_article_id": 1,
"content": "文章内容 - 20180904 - 1",
"cover_pic": "/upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif",
"cover_type": 1,
"tag": "",
"apply": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
}
{
"code": 20004,
"message": "数据验证失败:企鹅号ID(UUID)是无效的。"
}
SELECT EXISTS(SELECT * FROM `cpa_qq_tp_app_penguin` WHERE (`cpa_qq_tp_app_penguin`.`uuid`='e88e79faad9011e8a14554ee75d2ebc10') AND (`status`=1))
7. Posthttp://api.channel-pub-api.localhost/qq/v1/articles?group_id=015ce30b116ce86058fa6ab4fea4ac63, the request parameter uuid is in the array format, there are 2 key-value pairs, its value is wrong, the response fails, which is as expected
{
"uuid": [
"e88e79faad9011e8a14554ee75d2ebc15",
"9f359272b00e11e8875654ee75d2ebc16"
],
"article_type_code": "standard",
"article_category_id": 1,
"title": "标题 - 20180904 - 1",
"author": "作者 - 20180904 - 1",
"source": "spider",
"source_user_id": 1,
"source_article_id": 1,
"content": "文章内容 - 20180904 - 1",
"cover_pic": "/upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif",
"cover_type": 1,
"tag": "",
"apply": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
}
{
"code": 20004,
"message": "数据验证失败:企鹅号ID(UUID)是无效的。"
}
SELECT EXISTS(SELECT * FROM `cpa_qq_tp_app_penguin` WHERE (`cpa_qq_tp_app_penguin`.`uuid`='e88e79faad9011e8a14554ee75d2ebc15') AND (`status`=1))
SELECT EXISTS(SELECT * FROM `cpa_qq_tp_app_penguin` WHERE (`cpa_qq_tp_app_penguin`.`uuid`='9f359272b00e11e8875654ee75d2ebc16') AND (`status`=1))
8. Posthttp://api.channel-pub-api.localhost/qq/v1/articles?group_id=015ce30b116ce86058fa6ab4fea4ac63, the request parameter uuid is in the array format, there are 2 key-value pairs, the first value is correct, the second value is wrong, the response fails, as expected
{
"uuid": [
"e88e79faad9011e8a14554ee75d2ebc1",
"9f359272b00e11e8875654ee75d2ebc16"
],
"article_type_code": "standard",
"article_category_id": 1,
"title": "标题 - 20180904 - 1",
"author": "作者 - 20180904 - 1",
"source": "spider",
"source_user_id": 1,
"source_article_id": 1,
"content": "文章内容 - 20180904 - 1",
"cover_pic": "/upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif",
"cover_type": 1,
"tag": "",
"apply": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
}
{
"code": 20004,
"message": "数据验证失败:企鹅号ID(UUID)是无效的。"
}
SELECT EXISTS(SELECT * FROM `cpa_qq_tp_app_penguin` WHERE (`cpa_qq_tp_app_penguin`.`uuid`='e88e79faad9011e8a14554ee75d2ebc1') AND (`status`=1))
SELECT EXISTS(SELECT * FROM `cpa_qq_tp_app_penguin` WHERE (`cpa_qq_tp_app_penguin`.`uuid`='9f359272b00e11e8875654ee75d2ebc16') AND (`status`=1))
9. Posthttp://api.channel-pub-api.localhost/qq/v1/articles?group_id=015ce30b116ce86058fa6ab4fea4ac63, the request parameter uuid is array format, there are 2 key-value pairs, the first value is wrong, the second value is correct, the response fails, as expected
{
"uuid": [
"e88e79faad9011e8a14554ee75d2ebc13",
"9f359272b00e11e8875654ee75d2ebc1"
],
"article_type_code": "standard",
"article_category_id": 1,
"title": "标题 - 20180904 - 1",
"author": "作者 - 20180904 - 1",
"source": "spider",
"source_user_id": 1,
"source_article_id": 1,
"content": "文章内容 - 20180904 - 1",
"cover_pic": "/upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif",
"cover_type": 1,
"tag": "",
"apply": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
}
{
"code": 20004,
"message": "数据验证失败:企鹅号ID(UUID)是无效的。"
}
SELECT EXISTS(SELECT * FROM `cpa_qq_tp_app_penguin` WHERE (`cpa_qq_tp_app_penguin`.`uuid`='e88e79faad9011e8a14554ee75d2ebc13') AND (`status`=1))
SELECT EXISTS(SELECT * FROM `cpa_qq_tp_app_penguin` WHERE (`cpa_qq_tp_app_penguin`.`uuid`='9f359272b00e11e8875654ee75d2ebc1') AND (`status`=1))
10. Posthttp://api.channel-pub-api.localhost/qq/v1/articles?group_id=015ce30b116ce86058fa6ab4fea4ac63, the request parameter uuid is in the array format, there are 2 key-value pairs, the value is correct, the response is successful, and it is in line with the expected
{
"uuid": [
"e88e79faad9011e8a14554ee75d2ebc1",
"9f359272b00e11e8875654ee75d2ebc1"
],
"article_type_code": "standard",
"article_category_id": 1,
"title": "标题 - 20180904 - 1",
"author": "作者 - 20180904 - 1",
"source": "spider",
"source_user_id": 1,
"source_article_id": 1,
"content": "文章内容 - 20180904 - 1",
"cover_pic": "/upload/Image/mrtp/2018/08/30/1_8a2fa998c0624c0ebee6eb72c5434e7a.gif",
"cover_type": 1,
"tag": "",
"apply": 0,
"original_platform": 0,
"original_url": "",
"original_author": ""
}
{
"code": 10000,
"message": "发布文章类型:标准(普通、图文)的文章成功"
}
SELECT EXISTS(SELECT * FROM `cpa_qq_tp_app_penguin` WHERE (`cpa_qq_tp_app_penguin`.`uuid`='e88e79faad9011e8a14554ee75d2ebc1') AND (`status`=1))
SELECT EXISTS(SELECT * FROM `cpa_qq_tp_app_penguin` WHERE (`cpa_qq_tp_app_penguin`.`uuid`='9f359272b00e11e8875654ee75d2ebc1') AND (`status`=1))
11. Conclusive conclusion: If there are several key-value pairs in the array, the same number of verification procedures will be executed, and the subsequent values will not fail because a certain value fails to verify. It will no longer be verified, and it will come to an end for the time being, and subsequent optimizations will be realized to realize that when a certain value fails to verify, the subsequent value will no longer be verified, but directly respond to failure.

