首页 > 解决方案 > id 属性在 laravel 的 map 函数中返回值 0

问题描述

代码

   $drillDownChart = Loan::select('loan_type AS name')
                           ->groupBy('loan_type')
                           ->where('transaction_year', $transyear)
                           ->where('invalid', false)
                           ->get();

    $drillDownChart->map(function($val)use($loanChartArr) {
        $val->id = $val->name;
        $val->data = $loanChartArr;
        return $val;
    });

输出 var_dump(json_encode($drillDownChart));

string(340) "[{"name":"Hospitalization","id":0,"data":[[1,0],[2,0],[3,0],[4,0],[5,2],[6,1],[7,3],[8,1],[9,1],[10,0],[11,0],[12,0]]},{"name":"Salary","id":0,"data":[[1,0],[2,0],[3,0],[4,0],[5,2],[6,1],[7,3],[8,1],[9,1],[10,0],[11,0],[12,0]]},{"name":"Emergency","id":0,"data":[[1,0],[2,0],[3,0],[4,0],[5,2],[6,1],[7,3],[8,1],[9,1],[10,0],[11,0],[12,0]]}]"

应该返回“ $val->id = $val->name;Hospitalization”、“Salary”和“Emergency”,但它返回 0。请注意,如果我将“id”更改为“ID”,它会显示正确的输出。

$drillDownChart->map(function($val)use($loanChartArr) {
    $val->ID = $val->name;
    $val->data = $loanChartArr;
    return $val;
});

输出:

string(373) "[{"name":"Hospitalization","ID":"Hospitalization","data":[[1,0],[2,0],[3,0],[4,0],[5,2],[6,1],[7,3],[8,1],[9,1],[10,0],[11,0],[12,0]]},{"name":"Salary","ID":"Salary","data":[[1,0],[2,0],[3,0],[4,0],[5,2],[6,1],[7,3],[8,1],[9,1],[10,0],[11,0],[12,0]]},{"name":"Emergency","ID":"Emergency","data":[[1,0],[2,0],[3,0],[4,0],[5,2],[6,1],[7,3],[8,1],[9,1],[10,0],[11,0],[12,0]]}]"

这里有什么问题?在这种情况下,“id”是否仅限于在 laravel 中使用?请帮忙。谢谢你。

标签: phparrayslaravellaravel-5.8

解决方案


默认情况下,Laravel 假设你的模型有一个名为idtype的主键int

因此,该id属性被强制转换为int. 这就像有这个默认演员表:

protected $casts = [
    'id' => 'int'
];

因此,当您访问 时id,您的string(例如“住院”)将被转换为int. 结果是0

如果你真的想保留你当前的代码,你将不得不做一些 hacky 的东西,比如为id属性设置一个访问器:

public function getIdAttribute($value)
{
    return $value;
}

这样,演员表将被覆盖,您将能够以您想要的方式检索名称。

但是,我建议不要id在运行时手动更改,这显然是代码异味,表明您项目的这一部分不太正确。


对于那些喜欢进一步挖掘的人,这就是我解释的所有内容发生的地方:

vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php

/**
* Get the casts array.
*
* @return array
*/
public function getCasts()
{
    if ($this->getIncrementing()) {
        return array_merge([$this->getKeyName() => $this->getKeyType()], $this->casts);
    }

    return $this->casts;
}

当你尝试访问一个属性 ( $this->id) 时,Laravel 将确定它是否有一个访问器,这是否是一个关系......最后,将它转换为正确的类型。

要获得演员表,它将调用->getCasts().

首先,此方法将检查您的模型是否自动递增(可以通过将属性设置为 来禁用$incrementingfalse

如果是这种情况,它将获取主键名称(默认->getKeyName()情况id下)及其类型(默认->getKeyType()情况int下)。

该密钥对将与$casts模型的属性合并。


推荐阅读