翻译进度
16
分块数量
7
参与人数

请求

这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。


HTTP Requests

介绍

Laravel 的 Illuminate\Http\Request 类提供了一种面向对象的方式来与当前由应用程序处理的 HTTP 请求进行交互,并检索提交请求的输入内容、Cookie 和文件。

请求与交互

访问请求

要通过依赖注入获取当前的 HTTP 请求实例,你应该在路由闭包或控制器方法中导入 Illuminate\Http\Request 类。传入的请求实例将由 Laravel 服务容器 自动注入:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * 存储新用户。
     */
    public function store(Request $request): RedirectResponse
    {
        $name = $request->input('name');

        // 存储用户...

        return redirect('/users');
    }
}

如上所述,你也可以在路由闭包上导入 Illuminate\Http\Request 类。服务容器将在执行时自动将传入请求注入到闭包中:

use Illuminate\Http\Request;

Route::get('/', function (Request $request) {
    // ...
});
php_yt 翻译于 1个月前

依赖注入和路由参数

如果你的控制器方法还需要从路由参数中接收输入,你应该在其他依赖项之后列出路由参数。例如,如果你的路由定义如下:

use App\Http\Controllers\UserController;
Route::put('/user/{id}', [UserController::class, 'update']);

你仍然可以类型提示 Illuminate\Http\Request 并通过以下方式定义控制器方法来访问你的 id 路由参数:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
    /**
     * 更新指定的用户。
     */
    public function update(Request $request, string $id): RedirectResponse
    {
        // 更新用户...
        return redirect('/users');
    }
}

请求路径、主机和方法

Illuminate\Http\Request 实例提供了多种方法来检查传入的 HTTP 请求,并扩展了 Symfony\Component\HttpFoundation\Request 类。我们将在下面讨论一些最重要的方法。

获取请求路径

path 方法返回请求的路径信息。因此,如果传入的请求指向 http://example.com/foo/barpath 方法将返回 foo/bar

$uri = $request->path();

检查请求路径 / 路由

is 方法允许你验证传入的请求路径是否与给定的模式匹配。使用此方法时,你可以使用 * 字符作为通配符:

if ($request->is('admin/*')) {
    // ...
}

使用 routeIs 方法,你可以确定传入的请求是否匹配了 命名路由

if ($request->routeIs('admin.*')) {
    // ...
}
Chen_bu_ting 翻译于 1个月前

检索请求 URL

要检索传入请求的完整 URL,你可以使用 url 或 fullUrl 方法。url 方法将返回不带查询字符串的 URL,而 fullUrl 方法包括查询字符串:

$url = $request->url();

$urlWithQueryString = $request->fullUrl();

如果你想将查询字符串数据附加到当前 URL,你可以调用 fullUrlWithQuery 方法。此方法将给定数组的查询字符串变量与当前查询字符串合并:

$request->fullUrlWithQuery(['type' => 'phone']);

如果你想获取当前 URL 而不包含给定的查询字符串参数,你可以使用 fullUrlWithoutQuery 方法:

$request->fullUrlWithoutQuery(['type']);

检索请求主机

你可以通过 hosthttpHost 和 schemeAndHttpHost 方法检索传入请求的 “host”:

$request->host();
$request->httpHost();
$request->schemeAndHttpHost();

检索请求方法

method 方法将返回 HTTP 的请求操作。可以使用 isMethod 方法验证 HTTP 操作是否匹配给定字符串:

$method = $request->method();

if ($request->isMethod('post')) {
    // ...
}

请求头

你可以使用 Illuminate\Http\Request 实例的 header 方法来检索请求头。如果请求中不存在头部信息,则会返回 null。然而,如果请求中不存在头部信息,header 方法接受一个可选的第二个参数,该参数将当作头部信息返回:

$value = $request->header('X-Header-Name');

$value = $request->header('X-Header-Name', 'default');
justin_g 翻译于 6天前

hasHeader 方法可用来判断请求中是否包含给定的头:

if ($request->hasHeader('X-Header-Name')) {
    // ...
}

为方便起见,可以使用 bearerToken 方法从 Authorization 头中检索承载令牌。如果没有这样的头,则会返回一个空字符串:

$token = $request->bearerToken();

请求 IP 地址

ip 方法可用来检索发出请求到你的应用程序的客户端的 IP 地址:

$ipAddress = $request->ip();

如果你想检索一个包含所有客户端 IP 地址的数组,包括所有代理转发的 IP 地址,你可以使用 ips 方法。「原始」 客户端 IP 地址将位于数组的末端:

$ipAddresses = $request->ips();

通常,应该将 IP 地址视为不可信的、用户控制的输入,并仅出于信息目的使用。

内容协商

Laravel 提供了几个方法通过请求的 Accept 头来检查进来的请求的请求内容类型。首先,getAcceptableContentTypes 方法将返回一个数组,包含请求头中所有的 Accept :

$contentTypes = $request->getAcceptableContentTypes();

accepts 方法接受一个内容类型的数组,如果数组和请求中的 accept 匹配,返回 true ,否则返回 false

if ($request->accepts(['text/html', 'application/json'])) {
    // ...
}

你可以使用 prefers 方法来确定请求最倾向于给定数组中的哪种内容类型。如果请求不接受任何提供的内容类型,将返回 null :

$preferred = $request->prefers(['text/html', 'application/json']);
justin_g 翻译于 6天前

由于许多应用只返回 HTML 或 JSON,你可以使用 expectsJson 方法快速判断传入请求是否期望一个 JSON 响应:

if ($request->expectsJson()) {
    // ...
}

PSR-7 请求

PSR-7 标准定义了 HTTP 消息(包括请求和响应)的接口。如果你想获取一个 PSR-7 请求实例而不是 Laravel 请求实例,首先需要安装几个库。Laravel 使用 Symfony HTTP Message Bridge 组件,将典型的 Laravel 请求和响应转换为兼容 PSR-7 的实现:

composer require symfony/psr-http-message-bridge
composer require nyholm/psr7

安装完这些库后,你可以在路由闭包或控制器方法中通过类型提示 PSR-7 请求接口来获取 PSR-7 请求:

use Psr\Http\Message\ServerRequestInterface;

Route::get('/', function (ServerRequestInterface $request) {
    // ...
});

[!注意]
I如果你从路由或控制器返回一个 PSR-7 响应实例,框架会自动将其转换回 Laravel 响应实例并显示。

输入(Input)

获取输入

获取所有输入数据

你可以使用 all 方法以数组形式获取请求的所有输入数据。无论请求是来自 HTML 表单还是 XHR 请求,都可使用此方法:

$input = $request->all();

你也可以使用 collect 方法,以 集合(collection) 的形式获取请求的所有输入数据:

$input = $request->collect();
无与伦比 翻译于 1天前

collect 方法还允许你获取请求输入中的某个子集,并以集合(Collection)的形式返回:

$request->collect('users')->each(function (string $user) {
    // ...
});

获取单个输入值

通过几个简单的方法,你可以从 Illuminate\Http\Request 实例中访问所有用户输入,而无需担心请求使用了哪种 HTTP 动作。无论 HTTP 动作是什么,input 方法都可以用来获取用户输入:

$name = $request->input('name');

你可以给 input 方法传入第二个参数作为默认值,如果请求中没有该输入值,则返回默认值:

$name = $request->input('name', 'Sally');

当处理包含数组输入的表单时,可以使用“点”符号访问数组元素:

$name = $request->input('products.0.name');

$names = $request->input('products.*.name');

你也可以不传任何参数调用 input 方法,以获取所有输入值的关联数组:

$input = $request->input();

从查询字符串中获取输入

虽然 input 方法会从整个请求载荷(包括查询字符串)中获取值,但 query 方法仅会从查询字符串中获取值:

$name = $request->query('name');

如果请求中没有该查询字符串值,会返回 query 方法第二个参数的默认值:

$name = $request->query('name', 'Helen');

你也可以不传参数调用 query 方法,以获取所有查询字符串值的关联数组:

$query = $request->query();
无与伦比 翻译于 1天前

获取 JSON 输入值

当向应用发送 JSON 请求时,只要请求的 Content-Type 头正确设置为 application/json,你就可以通过 input 方法访问 JSON 数据。你甚至可以使用“点”语法来获取嵌套在 JSON 数组或对象中的值:

$name = $request->input('user.name');

获取可字符串化(Stringable)的输入值

你可以不用直接获取原始的字符串,而是用 string 方法获取请求数据作为一个 Illuminate\Support\Stringable 实例:

$name = $request->string('name')->trim();

获取整型输入值

要以整数形式获取输入值,可以使用 integer 方法。该方法会尝试将输入值强制转换为整数。如果输入不存在或者转换失败,将返回你指定的默认值。这对分页或其他数字类型输入特别有用:

$perPage = $request->integer('per_page');

获取布尔型输入值

处理 HTML 元素如复选框时,应用可能收到一些“真假值”实际上是字符串,比如 "true""on"。为方便起见,可以使用 boolean 方法将这些值作为布尔值获取。boolean 方法对 1, "1", true, "true", "on""yes" 返回 true,其它所有值返回 false

$archived = $request->boolean('archived');

获取数组输入值

包含数组的输入值可以通过 array 方法获取。该方法会始终把输入值转换成数组。如果请求中没有给定名称的输入值,则返回空数组:

$versions = $request->array('versions');
无与伦比 翻译于 1天前

Retrieving Date Input Values

For convenience, input values containing dates / times may be retrieved as Carbon instances using the date method. If the request does not contain an input value with the given name, null will be returned:

$birthday = $request->date('birthday');

The second and third arguments accepted by the date method may be used to specify the date's format and timezone, respectively:

$elapsed = $request->date('elapsed', '!H:i', 'Europe/Madrid');

If the input value is present but has an invalid format, an InvalidArgumentException will be thrown; therefore, it is recommended that you validate the input before invoking the date method.

Retrieving Enum Input Values

Input values that correspond to PHP enums may also be retrieved from the request. If the request does not contain an input value with the given name or the enum does not have a backing value that matches the input value, null will be returned. The enum method accepts the name of the input value and the enum class as its first and second arguments:

use App\Enums\Status;

$status = $request->enum('status', Status::class);

You may also provide a default value that will be returned if the value is missing or invalid:

$status = $request->enum('status', Status::class, Status::Pending);

If the input value is an array of values that correspond to a PHP enum, you may use the enums method to retrieve the array of values as enum instances:

use App\Enums\Product;

$products = $request->enums('products', Product::class);

Retrieving Input via Dynamic Properties

You may also access user input using dynamic properties on the Illuminate\Http\Request instance. For example, if one of your application's forms contains a name field, you may access the value of the field like so:

$name = $request->name;

When using dynamic properties, Laravel will first look for the parameter's value in the request payload. If it is not present, Laravel will search for the field in the matched route's parameters.

Retrieving a Portion of the Input Data

If you need to retrieve a subset of the input data, you may use the only and except methods. Both of these methods accept a single array or a dynamic list of arguments:

$input = $request->only(['username', 'password']);

$input = $request->only('username', 'password');

$input = $request->except(['credit_card']);

$input = $request->except('credit_card');

[!WARNING]
The only method returns all of the key / value pairs that you request; however, it will not return key / value pairs that are not present on the request.

Input Presence

You may use the has method to determine if a value is present on the request. The has method returns true if the value is present on the request:

if ($request->has('name')) {
    // ...
}

When given an array, the has method will determine if all of the specified values are present:

if ($request->has(['name', 'email'])) {
    // ...
}

The hasAny method returns true if any of the specified values are present:

if ($request->hasAny(['name', 'email'])) {
    // ...
}

The whenHas method will execute the given closure if a value is present on the request:

$request->whenHas('name', function (string $input) {
    // ...
});

A second closure may be passed to the whenHas method that will be executed if the specified value is not present on the request:

$request->whenHas('name', function (string $input) {
    // The "name" value is present...
}, function () {
    // The "name" value is not present...
});

If you would like to determine if a value is present on the request and is not an empty string, you may use the filled method:

if ($request->filled('name')) {
    // ...
}

If you would like to determine if a value is missing from the request or is an empty string, you may use the isNotFilled method:

if ($request->isNotFilled('name')) {
    // ...
}

When given an array, the isNotFilled method will determine if all of the specified values are missing or empty:

if ($request->isNotFilled(['name', 'email'])) {
    // ...
}

The anyFilled method returns true if any of the specified values is not an empty string:

if ($request->anyFilled(['name', 'email'])) {
    // ...
}

The whenFilled method will execute the given closure if a value is present on the request and is not an empty string:

$request->whenFilled('name', function (string $input) {
    // ...
});

A second closure may be passed to the whenFilled method that will be executed if the specified value is not "filled":

$request->whenFilled('name', function (string $input) {
    // The "name" value is filled...
}, function () {
    // The "name" value is not filled...
});

To determine if a given key is absent from the request, you may use the missing and whenMissing methods:

if ($request->missing('name')) {
    // ...
}

$request->whenMissing('name', function () {
    // The "name" value is missing...
}, function () {
    // The "name" value is present...
});

Merging Additional Input

Sometimes you may need to manually merge additional input into the request's existing input data. To accomplish this, you may use the merge method. If a given input key already exists on the request, it will be overwritten by the data provided to the merge method:

$request->merge(['votes' => 0]);

The mergeIfMissing method may be used to merge input into the request if the corresponding keys do not already exist within the request's input data:

$request->mergeIfMissing(['votes' => 0]);

Old Input

Laravel allows you to keep input from one request during the next request. This feature is particularly useful for re-populating forms after detecting validation errors. However, if you are using Laravel's included validation features, it is possible that you will not need to manually use these session input flashing methods directly, as some of Laravel's built-in validation facilities will call them automatically.

Flashing Input to the Session

The flash method on the Illuminate\Http\Request class will flash the current input to the session so that it is available during the user's next request to the application:

$request->flash();

You may also use the flashOnly and flashExcept methods to flash a subset of the request data to the session. These methods are useful for keeping sensitive information such as passwords out of the session:

$request->flashOnly(['username', 'email']);

$request->flashExcept('password');

Flashing Input Then Redirecting

Since you often will want to flash input to the session and then redirect to the previous page, you may easily chain input flashing onto a redirect using the withInput method:

return redirect('/form')->withInput();

return redirect()->route('user.create')->withInput();

return redirect('/form')->withInput(
    $request->except('password')
);

Retrieving Old Input

To retrieve flashed input from the previous request, invoke the old method on an instance of Illuminate\Http\Request. The old method will pull the previously flashed input data from the session:

$username = $request->old('username');

Laravel also provides a global old helper. If you are displaying old input within a Blade template, it is more convenient to use the old helper to repopulate the form. If no old input exists for the given field, null will be returned:

<input type="text" name="username" value="{{ old('username') }}">

Cookies

Retrieving Cookies From Requests

All cookies created by the Laravel framework are encrypted and signed with an authentication code, meaning they will be considered invalid if they have been changed by the client. To retrieve a cookie value from the request, use the cookie method on an Illuminate\Http\Request instance:

$value = $request->cookie('name');

Input Trimming and Normalization

By default, Laravel includes the Illuminate\Foundation\Http\Middleware\TrimStrings and Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull middleware in your application's global middleware stack. These middleware will automatically trim all incoming string fields on the request, as well as convert any empty string fields to null. This allows you to not have to worry about these normalization concerns in your routes and controllers.

Disabling Input Normalization

If you would like to disable this behavior for all requests, you may remove the two middleware from your application's middleware stack by invoking the $middleware->remove method in your application's bootstrap/app.php file:

use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
use Illuminate\Foundation\Http\Middleware\TrimStrings;

->withMiddleware(function (Middleware $middleware) {
    $middleware->remove([
        ConvertEmptyStringsToNull::class,
        TrimStrings::class,
    ]);
})

If you would like to disable string trimming and empty string conversion for a subset of requests to your application, you may use the trimStrings and convertEmptyStringsToNull middleware methods within your application's bootstrap/app.php file. Both methods accept an array of closures, which should return true or false to indicate whether input normalization should be skipped:

->withMiddleware(function (Middleware $middleware) {
    $middleware->convertEmptyStringsToNull(except: [
        fn (Request $request) => $request->is('admin/*'),
    ]);

    $middleware->trimStrings(except: [
        fn (Request $request) => $request->is('admin/*'),
    ]);
})

Files

Retrieving Uploaded Files

You may retrieve uploaded files from an Illuminate\Http\Request instance using the file method or using dynamic properties. The file method returns an instance of the Illuminate\Http\UploadedFile class, which extends the PHP SplFileInfo class and provides a variety of methods for interacting with the file:

$file = $request->file('photo');

$file = $request->photo;

You may determine if a file is present on the request using the hasFile method:

if ($request->hasFile('photo')) {
    // ...
}

Validating Successful Uploads

In addition to checking if the file is present, you may verify that there were no problems uploading the file via the isValid method:

if ($request->file('photo')->isValid()) {
    // ...
}

File Paths and Extensions

The UploadedFile class also contains methods for accessing the file's fully-qualified path and its extension. The extension method will attempt to guess the file's extension based on its contents. This extension may be different from the extension that was supplied by the client:

$path = $request->photo->path();

$extension = $request->photo->extension();

Other File Methods

There are a variety of other methods available on UploadedFile instances. Check out the API documentation for the class for more information regarding these methods.

Storing Uploaded Files

To store an uploaded file, you will typically use one of your configured filesystems. The UploadedFile class has a store method that will move an uploaded file to one of your disks, which may be a location on your local filesystem or a cloud storage location like Amazon S3.

The store method accepts the path where the file should be stored relative to the filesystem's configured root directory. This path should not contain a filename, since a unique ID will automatically be generated to serve as the filename.

The store method also accepts an optional second argument for the name of the disk that should be used to store the file. The method will return the path of the file relative to the disk's root:

$path = $request->photo->store('images');

$path = $request->photo->store('images', 's3');

If you do not want a filename to be automatically generated, you may use the storeAs method, which accepts the path, filename, and disk name as its arguments:

$path = $request->photo->storeAs('images', 'filename.jpg');

$path = $request->photo->storeAs('images', 'filename.jpg', 's3');

[!NOTE]
For more information about file storage in Laravel, check out the complete file storage documentation.

Configuring Trusted Proxies

When running your applications behind a load balancer that terminates TLS / SSL certificates, you may notice your application sometimes does not generate HTTPS links when using the url helper. Typically this is because your application is being forwarded traffic from your load balancer on port 80 and does not know it should generate secure links.

To solve this, you may enable the Illuminate\Http\Middleware\TrustProxies middleware that is included in your Laravel application, which allows you to quickly customize the load balancers or proxies that should be trusted by your application. Your trusted proxies should be specified using the trustProxies middleware method in your application's bootstrap/app.php file:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(at: [
        '192.168.1.1',
        '10.0.0.0/8',
    ]);
})

In addition to configuring the trusted proxies, you may also configure the proxy headers that should be trusted:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(headers: Request::HEADER_X_FORWARDED_FOR |
        Request::HEADER_X_FORWARDED_HOST |
        Request::HEADER_X_FORWARDED_PORT |
        Request::HEADER_X_FORWARDED_PROTO |
        Request::HEADER_X_FORWARDED_AWS_ELB
    );
})

[!NOTE]
If you are using AWS Elastic Load Balancing, the headers value should be Request::HEADER_X_FORWARDED_AWS_ELB. If your load balancer uses the standard Forwarded header from RFC 7239, the headers value should be Request::HEADER_FORWARDED. For more information on the constants that may be used in the headers value, check out Symfony's documentation on trusting proxies.

信任所有代理

如果你使用的是 Amazon AWS 或其他「云」负载均衡器提供商,则可能不知道实际负载均衡器的 IP 地址。在这种情况下,你可以使用 * 来信任所有代理:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(at: '*');
})

配置可信任的 Host

默认情况下,Laravel 将响应它接收到的所有请求,而不管 HTTP 请求的 Host 标头的内容是什么。此外,在 web 请求期间生成应用程序的绝对 URL 时,将使用 Host 标头的值。

通常情况下,你应该配置你的 Web 服务器(如 Nginx 或 Apache)仅向匹配给定主机名的应用程序发送请求。然而,如果你没有直接自定义你的 Web 服务器的能力,可以通过为你的应用程序启用 Illuminate\Http\Middleware\TrustHosts 中间件,指示 Laravel 仅响应特定主机名的请求。

为了启用 TrustHosts 中间件,你应该在应用程序 bootstrap/app.php 文件中,调用 trustHosts 中间件方法。通过使用该方法中的 at 参数,你可以指定应用程序应该响应的主机名。具有其他 Host 标头值的传入请求将被拒绝:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustHosts(at: ['laravel.test']);
})

默认情况下,来自应用程序 URL 子域名的请求也会自动被信任。如果你想禁用这种行为,可以使用 subdomains 参数:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustHosts(at: ['laravel.test'], subdomains: false);
})

如果你需要访问应用程序的配置文件或数据库来确定你的可信任的主机,你可以再 at 参数提供一个闭包:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustHosts(at: fn () => config('app.trusted_hosts'));
})
dkp 翻译于 2个月前

本文章首发在 LearnKu.com 网站上。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
贡献者:7
讨论数量: 2
发起讨论 只看当前版本


xiaolongxia
在一个控制器中调用另一个控制器中的del方法
0 个点赞 | 14 个回复 | 分享 | 课程版本 5.8
LiJIna
laravel文档的api文档点进去,报错502,请问有新的地址吗?
0 个点赞 | 2 个回复 | 问答 | 课程版本 5.3