如何访问我在 Laravel 4 中手动发送的请求的查询字符串参数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16597420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 02:26:38  来源:igfitidea点击:

How can I access query string parameters for requests I've manually dispatched in Laravel 4?

apirequestlaravelrouteslaravel-4

提问by Kevin Mitchell

I'm writing a simple API, and building a simple web application on top of this API.

我正在编写一个简单的 API,并在此 API 之上构建一个简单的 Web 应用程序。

Because I want to "consume my own API" directly, I first Googled and found this answer on StackOverflow which answers my initial question perfectly: Consuming my own Laravel API

因为我想直接“使用我自己的 API”,所以我首先用谷歌搜索并在 StackOverflow 上找到了这个答案,它完美地回答了我最初的问题:使用我自己的 Laravel API

Now, this works great, I'm able to access my API by doing something like:

现在,这很好用,我可以通过执行以下操作来访问我的 API:

$request = Request::create('/api/cars/'.$id, 'GET');
$instance = json_decode(Route::dispatch($request)->getContent());

This is great! But, my API also allows you to add an optional fieldsparameter to the GET query string to specify specific attributes that should be returned, such as this:

这很棒!但是,我的 API 还允许您向GET 查询字符串添加一个可选的字段参数,以指定应返回的特定属性,例如:

http://cars.com/api/cars/1?fields=id,color

Now the way I actually handle this in the API is something along the lines of this:

现在我在 API 中实际处理这个的方式是这样的:

public function show(Car $car)
{
     if(Input::has('fields'))
     {
          //Here I do some logic and basically return only fields requested
          ....
     ...
 }

I would assume that I could do something similar as I did with the query string parameter-less approach before, something like this:

我假设我可以做一些类似于我之前使用查询字符串无参数方法所做的事情,如下所示:

$request = Request::create('/api/cars/' . $id . '?fields=id,color', 'GET');
$instance = json_decode(Route::dispatch($request)->getContent());

BUT, it doesn't seem so. Long story short, after stepping through the code it seems that the Requestobject is correctly created (and it correctly pulls out the fieldsparameter and assigns id,colorto it), and the Route seems to be dispatched OK, but within my API controller itself I do not know how to access the fieldparameter. Using Input::get('fields')(which is what I use for "normal" requests) returns nothing, and I'm fairly certain that's because the static Inputis referencing or scoping to the initial request the came in, NOT the new request I dispatched "manually" from within the app itself.

但是,似乎并非如此。长话短说,在单步执行代码之后,似乎Request对象已正确创建(并且它正确地提取了fields参数并为其分配了id、color),并且路由似乎已正常调度,但在我的 API 控制器本身中我不知道如何访问字段参数。使用Input::get('fields')(这是我用于“正常”请求的内容)不返回任何内容,而且我相当肯定这是因为静态Input引用或限定了传入的初始请求,而不是我从内部“手动”发送的新请求应用程序本身。

So, my question is really how should I be doing this? Am I doing something wrong? Ideally I'd like to avoid doing anything ugly or special in my API controller, I'd like to be able to use Input::get for the internally dispatched requests and not have to make a second check , etc.

所以,我的问题真的是我应该怎么做?难道我做错了什么?理想情况下,我希望避免在我的 API 控制器中做任何丑陋或特殊的事情,我希望能够将 Input::get 用于内部调度的请求,而不必进行第二次检查等。

回答by Jason Lewis

You are correct in that using Inputis actually referencing the current request and not your newly created request. Your input will be available on the request instance itself that you instantiate with Request::create().

您是正确的,因为 usingInput实际上是引用当前请求而不是您新创建的请求。您的输入将在您使用 实例化的请求实例本身上可用Request::create()

If you were using (as you should be) Illuminate\Http\Requestto instantiate your request then you can use $request->input('key')or $request->query('key')to get parameters from the query string.

如果您正在使用(应该如此)Illuminate\Http\Request来实例化您的请求,那么您可以使用$request->input('key')$request->query('key')从查询字符串中获取参数。

Now, the problem here is that you might not have your Illuminate\Http\Requestinstance available to you in the route. A solution here (so that you can continue using the Inputfacade) is to physically replace the input on the current request, then switch it back.

现在,这里的问题是您可能无法Illuminate\Http\Request在路由中使用您的实例。这里的一个解决方案(以便您可以继续使用Input外观)是物理替换当前请求上的输入,然后将其切换回来。

// Store the original input of the request and then replace the input with your request instances input.
$originalInput = Request::input();

Request::replace($request->input());

// Dispatch your request instance with the router.
$response = Route::dispatch($request);

// Replace the input again with the original request input.
Request::replace($originalInput);

This should work (in theory) and you should still be able to use your original request input before and after your internal API request is made.

这应该有效(理论上),并且您仍然可以在内部 API 请求之前和之后使用原始请求输入。

回答by santacruz

I was also just facing this issue and thanks to Jason's great answers I was able to make it work.

我也刚刚面临这个问题,多亏了 Jason 的出色回答,我才得以解决这个问题。

Just wanted to add that I found out that the Route also needs to be replaced. Otherwise Route::currentRouteName()will return the dispatched route later in the script.

只是想补充一点,我发现Route也需要更换。否则Route::currentRouteName()将在脚本后面返回调度的路由。

More details to this can be found on my blog post.

更多细节可以在我的博客文章中找到。

I also did some tests for the stacking issue and called internal API methods repeatedly from within each other with this approach. It worked out just fine! All requests and routes have been set correctly.

我还对堆栈问题进行了一些测试,并使用这种方法从彼此内部重复调用内部 API 方法。效果很好!所有请求和路由都已正确设置。

回答by Tho

If you want to invoke an internal API and pass parameters via an array (instead of query string), you can do like this:

如果要调用内部 API 并通过数组(而不是查询字符串)传递参数,可以这样做:

$request = Request::create("/api/cars", "GET", array(
   "id" => $id,
   "fields" => array("id","color")
));
$originalInput = Request::input();//backup original input
Request::replace($request->input());
$car = json_decode(Route::dispatch($request)->getContent());//invoke API
Request::replace($originalInput);//restore orginal input

Ref: Laravel : calling your own API

参考:Laravel:调用你自己的 API