Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何将自定义请求传递给Api资源_Php_Laravel_Api - Fatal编程技术网

Php 如何将自定义请求传递给Api资源

Php 如何将自定义请求传递给Api资源,php,laravel,api,Php,Laravel,Api,我有自定义请求类: 类ApiRequest扩展了FormRequest { ... 公共函数locale() { $lang=$this->header('Accept-Language'); 返回$lang?$lang:'uz'; } } 和API追索权: class SomeResource扩展了JsonResource { 公共功能待命($request) { 返回[ 'id'=>this->id, ... ]; } } 但是我不能在SomeResource中使用apirest的方法l

我有自定义请求类:

类ApiRequest扩展了FormRequest
{
...
公共函数locale()
{
$lang=$this->header('Accept-Language');
返回$lang?$lang:'uz';
}
}
和API追索权:

class SomeResource扩展了JsonResource
{
公共功能待命($request)
{
返回[
'id'=>this->id,
...
];
}
}
但是我不能在SomeResource中使用apirest的方法
locale()
。因为
toArray()
只接受
\illumb\Http\Request

有没有想过我会通过我的课程进入这个领域?或者您提供更好的解决方案。

应该接收模型实例,而不是模型本身。这是一个例子:

apirest.php

ApiRequest extends Request {

    public function authorize() { /** your logic */ }

    public function rules() { /** your logic */ }

}
MyCoolController extends Controller {

    public function myFunction(ApiRequest $request)
    {
        $lang = $request->header('Accept-Language') ?? 'uz';
        \App::setLocale($lang); // <--

        $model = MyModel::find($request->get('id'));

        return new SomeResource($model);
    }
}
mycolcontroller.php

ApiRequest extends Request {

    public function authorize() { /** your logic */ }

    public function rules() { /** your logic */ }

}
MyCoolController extends Controller {

    public function myFunction(ApiRequest $request)
    {
        $lang = $request->header('Accept-Language') ?? 'uz';
        \App::setLocale($lang); // <--

        $model = MyModel::find($request->get('id'));

        return new SomeResource($model);
    }
}
MyCoolController扩展控制器{
公共函数myFunction(APIRESQUEST$request)
{
$lang=$request->header('Accept-Language')??“uz”;
\App::setLocale($lang);//get('id');
返回新的SomeResource($model);
}
}

我创建了一个基本资源类,所有其他资源类都使用我的自定义方法对其进行扩展:

class BaseResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }

    protected function locale($request)
    {
        $lang = $request->header('Accept-Language');
        return $lang ? $lang : 'uz';
    }
}
我在儿童课上使用它:

class SomeResource extends BaseResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        $lang = $this->locale($request);

        return [
            'id' => $this->id,
            'hash' => $this->hash,
            'name'  => $this->translation('name', $this->locale($request)),
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

创建响应时,容器中绑定的请求实例被注入JSON资源类

实现所需功能的一种方法是创建扩展标准请求类的自定义请求,然后将其绑定到容器中,作为请求实例用于请求的其余部分。这可以在专门分配给API组的中间件中完成,也可以只在特定的控制器中完成

当生成响应时,这将被注入JSON资源类中的
toArray()
方法中,并且您的自定义方法将可用

自定义请求类

class ApiRequest extends Request
{
    ...
    public function locale()
    {
        $lang = $this->header('Accept-Language');
        return $lang ? $lang : 'uz';
    }
}
API中间件

class ApiMiddleware
{
    ...
    public function handle($request, $next)
    {
        $request = app()->instance('request', ApiRequest::createFrom($request));
        
        return $next($request);
    }
}
class SomeResource extends JsonResource
{
    public function toArray($request)
    {
        // $request is now instanceof ApiRequest

        return [
            'id' => $this->id,
            'locale' => $request->locale()
        ];
    }
}
JSON资源

class ApiMiddleware
{
    ...
    public function handle($request, $next)
    {
        $request = app()->instance('request', ApiRequest::createFrom($request));
        
        return $next($request);
    }
}
class SomeResource extends JsonResource
{
    public function toArray($request)
    {
        // $request is now instanceof ApiRequest

        return [
            'id' => $this->id,
            'locale' => $request->locale()
        ];
    }
}

您如何通过API资源传递请求?用这些代码更新你的答案。我在控制器中使用它:返回新的SomeResource(User::find(2)),laravel自动获取它。我不想每次在控制器中获取请求头,所以我想用某种方式对其进行泛化。你可以将该逻辑放在中间件中,这只是一个示例。我的观点是,您不应该在API资源中使用请求。请记住,该类将应用于每个模型实例(如果您使用静态选项传递对象集合:
SomeResource::collection($models);
),因此在我看来效率不是很高。请参阅我的解决方案below@SomeDev见我上面的评论:v。再说一次,这只是一个建议,请牢记在心。