繁体   English   中英

Yii2 Active Record JSON 响应,类型转换问题

[英]Yii2 Active Record JSON response, type casting issue

我在 Yii2 中遇到了奇怪的问题我有一个查询,它与代理表有一个连接,并且工作与任务的(一对多)关系工作正常,但问题是它返回字符串中的所有内容。 下面是查询:

 $query = self::find()
        ->select("job.*, agent.first_name,agent.last_name")
        ->leftJoin('agent', 'job.agent_id = agent.id')
        ->with('tasks')
        ->asArray()
        ->all();

和 JSON 编码的结果:

{
  "success": true,
  "data": [
  {
  "id": "10",
  "customer_id": "1",
  "job_type": "normal",
  "created": "2016-06-22 10:19:25",
  "first_name": "Shayan",
  "last_name": "",
  "tasks": [
    {
      "id": "10",
      "job_id": "10",
      "title": "bring food",
      "instruction": null,
      "created": "2016-06-22 10:19:25",

    },
    {
      "id": "10",
      "job_id": "10",
      "title": "bring pizza",
      "instruction": null,
      "created": "2016-06-22 10:19:25",

    },
  ]
}

如果您注意到 id、customer_id 和 job_id 等字段,它们都是整数,但它以字符串形式返回。 但是如果我从上面的查询中删除 ->asArray() 它返回有效的类型转换但问题是它跳过关系和 leftJoin 代理表字段,它只返回作业表字段这里是从上面的查询中删除 ->asArray() 后的响应。

{
"success": true,
"data": [

 {
  "id": 10,
  "customer_id": 1,
  "name": null,
  "job_type": "normal",
  "created": "2016-06-22 10:19:25",
},

如果您在上面的响应中注意到它没有完全跳过代理表 first_name、last_name 和关系数据任务,但 id 和 customer_id 是整数。

有没有人遇到同样的问题? 您的帮助将不胜感激。 提前致谢。

我想确保情况确实如此。 我自己用非常相似的查询对此进行了测试,结果非常相似:

array(2) {
  [0]=>
  array(5) {
    ["id"]=>
    string(1) "1"
    ["name"]=>
    string(5) "Admin"
    // ...
  }
// ...
}

就我而言,我还将所有类型都作为字符串。 因此,如果您要使用if ($data[0]['id'] === 1)检查输入及其类型,则会得到false结果,因为它是string

但是您需要做的是在变量之前添加(int)以将其转换为不同的类型转换。 这将是: (int) $data[0]['id']

然后var_dump((int) $data[0]['id']); (在我的情况下)将给出int(1)而不是string(1) "1"

您还可以签入条件:

((int) $data[0]['id'] === 1) ? exit('Integer') : exit('Not integer');

不写(int)作为前缀将给出Not integer结果,而 with prefix 将产生Integer

如果你不想在每个函数中都写这些前缀,你可以这样写:

$data[0]['id'] = (int) $data[0]['id'];

现在$data[0]['id']在将来的使用中将是integer


新解决方案:

这个新的解决方案将返回一个带有数组的对象,而不仅仅是数组。

// Method that gives data back. In this case, user with ID == 10.
public static function getData()
{
    $dataProvider = new ActiveDataProvider([
        'query' => self::findOne(['id' => 10])->attributes
    ]);

    return $dataProvider;
}

在 Controller 中,您(一如既往)传递此对象:

$data = User::getData();

return $this->render('user', [
            //...
            'data' => $data
        ]);

然后在查看器中,您可以像这样访问值(以正确的类型转换):

$data->query['columnName'];

所以,对于身份证检查:

($data->query['id'] === 10 ? exit('ok') : exit('nok'));

你会得到响应ok (类型转换:整数,值:10)。

这是预期的行为,也记录在案

注意:虽然这种方法可以节省内存并提高性能,但它更接近较低的 DB 抽象层,你将失去大部分 Active Record 功能。 一个非常重要的区别在于列值的数据类型。 当您在 Active Record 实例中返回数据时,列值将根据实际列类型自动进行类型转换; 另一方面,当您以数组形式返回数据时,列值将是字符串(因为它们是未经任何处理的 PDO 结果),而不管它们的实际列类型。

对于第二个问题,要检索活动记录类中的附加字段,您必须在类中为它们创建附加属性:

class MyRecord extends \yii\db\ActiveRecord
{
    public $first_name;
    public $last_name;

    // ...
}

方法“asArray”将所有变量的类型转换为字符串。 因此你不应该使用它。

您可以在文档中找到正确的解决方案: https : //www.yiiframework.com/doc/guide/2.0/en/rest-resources#overriding-extra-fields

您需要在 API 请求的 URI 中使用“字段”和“扩展”参数。

例如: http://localhost/posts?fields=id,title&expand=author

首先添加与模型的关系:

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAuthor()
    {
        return $this->hasOne(Profile::class, ['id' => 'author_id']);
    }

您还需要向模型添加字段和 extraFields 方法:

public function fields()
    {
        return ['id', 'title'];
    }

    public function extraFields()
    {
        return ['author'];
    }

并更改响应:

public function actionIndex()
{
    return new ActiveDataProvider([
        'query' => Post::find(),
    ]);
}

PS 很抱歉发布了 necroposting,但我最近遇到了同样的问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM