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

Kam*_*tti 5 php json yii yii2

我在Yii2中面临奇怪的问题我有一个查询,其中有一个与代理表的连接和一个(一对多)作业与任务的关系它工作正常但问题是它返回字符串中的所有内容.以下是查询:

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

和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",

    },
  ]
}
Run Code Online (Sandbox Code Playgroud)

如果你注意到像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",
},
Run Code Online (Sandbox Code Playgroud)

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

有人遇到过同样的问题吗?非常感谢您的帮助.提前致谢.

Gyt*_*mas 10

我想确保实际情况就是如此.我已经用非常相似的查询测试了这个,我的结果非常相似:

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

在我的情况下,我也得到所有类型的字符串.所以,如果你要检查输入及其类型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');
Run Code Online (Sandbox Code Playgroud)

如果没有写入(int)前缀将给出Not integer结果,而前缀将产生Integer.

如果您不想在每个函数中继续编写这些前缀,可以编写如下内容:

$data[0]['id'] = (int) $data[0]['id'];
Run Code Online (Sandbox Code Playgroud)

现在,$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;
}
Run Code Online (Sandbox Code Playgroud)

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

$data = User::getData();

return $this->render('user', [
            //...
            'data' => $data
        ]);
Run Code Online (Sandbox Code Playgroud)

然后在Viewer中你可以访问值(在正确的类型转换中),如下所示:

$data->query['columnName'];
Run Code Online (Sandbox Code Playgroud)

所以,对于ID检查:

($data->query['id'] === 10 ? exit('ok') : exit('nok'));
Run Code Online (Sandbox Code Playgroud)

您将得到响应ok(类型转换:整数,值:10).

  • 应该有自动类型转换而不是手动执行,是否有任何解决方法? (3认同)

ceb*_*ebe 7

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

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

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

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)