背景说明
在做api的时候,我们返回一个资源后,前端在使用时很可能需要这个资源的相关联的其他资源。比如获取一个user时,还需要同时获取相应的city信息或者phone信息。而我们的get/user是可以在不同的场景下使用的,比如有的场景下可能仅需要获取相关的city,有的场景下可能仅需要获取相关的phone,又或者有的场景下什么也不需要或者都需要。
所以我们为laravel做了一个按需load的功能。根据用户传入的include字段(这个字段名随意设置即可)来进行按需load。
使用示例
假设原本前端收到的数据是这样的:
{
"user":{
"…":"…"
}
}
我们需要这个"user"加载city,则在请求时传入include=user.city。
如果还需要同时加载更多,使用","分开include=user.city,user.phone
这样的得到的结果就是
{
"user":{
"…":"…",
"city":{}
"phone":{}
}
}
代码
处理类:
class ResultHandler
{
public static function handleInclude($responseData,$extsStr){
if ($extsStr&&is_string($extsStr))
{
//分解出所有的include项目
//例$extsStr="user.city,user.phone",$exts=["user.city","user.phone"]
$exts=explode(',',$extsStr);
$loadItems=[];
for ($i = 0,$length=count($exts); $i < $length; $i++)
{
$ext=$exts[$i];
//求出需要被拓展的字段名(第一个.之前的部分)
//例$objName="user"
$objName=strstr($ext, '.', TRUE);
//求出需要拓展的字段名(第一个.之后的部分)
//例$loadName="city"及$loadName="phone"
$loadName=substr(strstr($ext, '.', false),1);
if (isset($loadItems[$objName]))
{
array_push($loadItems[$objName],$loadName);
}else{
$loadItems[$objName]=[$loadName];
}
}
try
{
//为user加载city及phone
foreach ($loadItems as $key=>$value)
{
$responseData[$key]->load($value);
}
}
catch (\Exception $exception)
{
}
}
return $responseData;
}
}
调用:
$result=["user"=>$user];
$result=ResultHandler::handleInclude($result,$this->request->input("include"));
缺陷:
按需调用的话,性能可能会差一些;
安全性也会差一些;