Laravel: Up & Running 中文版
  • Laravel Up and Running A Framework for Building Modern PHP Apps
  • 为什么是Laravel
    • 为什么使用框架
    • “自己写”
    • 一致性与灵活性
    • 简短PHP Web框架历史
      • Ruby on Rails
      • PHP框架的涌入
      • CodeIgniter的优劣
      • Laravel 1, 2,和 3
      • Laravel 4
      • Laravel 5
    • Laravel 特别之处
      • Laravel哲学
      • Laravel如何让开发者感到幸福
      • Laravel 社区
    • 是如何运作的
    • 为什么是Laravel
  • 创建Laravel开发环境
    • 系统要求
    • Composer
    • 本地开发环境
      • Laravel Valet
      • Laravel Homestead
    • 创建一个新的Laravel项目
      • 使用Laravel安装工具安装Laravel
      • 使用Composer的create-project功能安装Laravel
      • Lambo:一款增强的"Laravel New"工具
    • Laravel的目录结构
      • 文件夹
      • 其他零散文件
    • 配置
      • .env文件
    • 运行
    • 测试
    • 总结
  • 路由与控制器
    • MVC HTTP和REST简介
      • 什么是MVC
      • HTTP verbs
      • 什么是REST
    • 定义路由
      • Route Verbs
      • 处理路由
      • 路由参数
      • 路由命名
    • 路由组
      • 中间件
        • 在控制器内应用中间件
        • 频率限制
      • 路径前缀
      • 兜底路由
      • 子域路由
      • 命名空间前缀
      • 名称前缀
    • 路由签名
      • 添加签名
      • 修改路由可以访问签名链接
    • 视图
      • 直接使用Route::view()返回简单路由
      • 使用View Composer在视图间共享变量
    • 控制器
      • 获取用户输入
      • 将依赖注入到控制器
      • 资源控制器
      • API 资源控制器
      • 单动作控制器
    • 路由模型绑定
      • 隐式路由模型绑定
      • 自定义路由模型绑定
    • 路由缓存
    • 表单请求方法伪造
      • Laravel内的HTTP verb
      • HTML 表单中的HTTP方法伪造
    • CSRF保护
    • 重定向
      • redirect()->to()
      • redirect()->route()
      • redirect()->back()
      • 其他重定向方法
      • redirect()->with()
    • 关于请求
    • 自定义响应
      • response()->make()
      • response()->json() 和 ->jsonp()
      • response()->download(), ->streamDownload(), 和 ->file()
    • 测试
    • 总结
  • Blade 模板引擎
    • 输出数据
    • 控制结构
      • 条件
      • 循环
    • 模板继承
      • 包含视图
      • 使用堆栈
      • 使用组件与插槽
    • 视图Composer和服务注入
      • 使用视图composers绑定数据到视图
      • Blade 服务注入
    • 自定义Blade指令
      • 自定义指令传参
      • 示例:多租户的自定义Blade指令
      • 更简单的if语句自定义指令
    • 测试
    • 总结
  • 数据库和Eloquent
    • 配置
      • 数据库连接
      • 其他数据库配置选项
      • 定义迁移
        • 创建一个迁移
        • 创建表格
        • 创建字段
        • 构建额外属性
        • 丢弃表格
        • 修改字段
        • 索引和外键
      • 运行迁移
    • 填充
      • 创建一个填充
      • 模型工厂
    • 查询器
      • DB facade的基础用法
      • 原生SQL
      • 使用查询器
      • 事务
    • Eloquent介绍
      • 创建和定义Eloquent模型
      • 使用Eloquent检索数据
      • 使用Eloquent插入和更新
      • 使用Eloquent删除
      • 作用域
      • 使用访问,赋值和属性转换自定义字段
      • Eloquent集合
      • Eloquent序列化
      • Eloquent关系
      • 子记录更新父记录时间戳
    • Eloquent事件
    • 测试
    • 总结
  • 前端组件
    • Laravel 混合
      • Mix 文件夹结构
      • 运行Mix
      • Mix提供了什么
    • 前端预设和授权脚手架
      • 前端预设
    • 分页
    • 信息包
      • 命名错误包
    • 字符串助手,多元化和本地化
      • 字符串助手和多元化
      • 本地化
    • 测试
      • 测试Message和错误包
      • 翻译和本地化
    • 总结
  • 收集和处理用户数据
    • 注入一个请求对象
      • $request->all()
      • $request->except()和$request->only()
      • $request->has()
      • $request->input()
      • $request->method() 和->isMethod()
      • 数组输入
      • JSON 输入($request->json())
    • 路由数据
      • 来自请求
      • 来自路由参数
    • 上传文件
    • 验证
      • Request对象上的validate()
      • 手动验证
      • 自定义验证规则
      • 显示验证错误信息
    • 表单请求
      • 创建一个表单请求
      • 使用表单请求
    • Eloquent 模型批量赋值
    • {{ 与 {!!
    • 测试
    • 总结
  • Artisan 和 Tinker
    • Artisan 介绍
    • 基础Artisan命令
      • 选项
      • 分组的命令
    • 编写自定义Artisan命令
      • 一个简单的命令
      • 参数和选项
      • 使用输入
      • 提示
      • 输出
      • 基于闭包的命令
    • 在普通代码调用Artisan命令
    • Tinker
    • Laravel Dump 服务
    • 测试
    • 总结
  • 用户认证与授权
    • 用户模型与迁移
    • 使用auth()全局辅助和Auth Facade
    • 认证控制器
      • RegisterController
      • LoginController
      • ResetPasswordController
      • ForgotPasswordController
      • VerificationController
    • Auth::routes()
    • 认证脚手架
    • ”记住我“
    • 手动认证用户
    • 手动登出用户
    • 认证中间件
    • 邮箱验证
    • Blade认证指令
    • 守卫
      • 更改默认守卫
      • 不更改默认使用其他守卫
      • 添加新守卫
      • 闭包请求守卫
      • 创建一个自定义用户提供者
      • 非关系数据库的自定义用户提供者
    • 认证事件
    • 授权(ACL)和角色
      • 定义授权角色
      • Gate Facade(注入Gate)
      • 资源Gates
      • 授权中间件
      • 控制器授权
      • 检查用户实例
      • Blade检查
      • 拦截检查
      • 策略
    • 测试
    • 总结
  • 请求,响应,和中间件
    • Laravel的请求生命周期
      • 启动应用程序
      • 服务提供者
    • 请求对象
      • 在Laravel获取一个请求对象
      • 获取请求的基本信息
    • 响应对象
      • 在控制器内使用和创建响应对象
      • 序列化响应类型
    • Laravel和中间件
      • 中间件介绍
      • 创建自定义中间件
      • 绑定中间件
      • 给中间件传参
    • 可信代理
    • 测试
    • 总结
  • 容器
    • 依赖注入简介
    • 依赖注入与Laravel
    • app()全局辅助函数
    • 如何连接容器
    • 绑定类到容器
      • 绑定到闭包
      • 绑定到单例,Aliases和实例
      • 绑定具体实例到接口
      • 上下文绑定
    • Laravel框架内的构造注入
    • 方法注入
    • Facades和容器
      • Facade是如何工作的
      • 实时Facades
    • 服务提供者
    • 测试
    • 总结
  • 测试
  • 编写APIs
    • REST基础-JSON APIs
    • 控制器组织和JSON返回
    • 读取和发送Headers
      • 在Laravel中发送响应头
      • 在Laravel中读取请求头
    • Eloquent 分页
    • 排序和过滤
      • 排序你的API 结果
      • 过滤你的API结果
    • 转换结果
    • API 资源
      • 创建一个资源类
      • 资源集合
      • 嵌套关系
      • 对API资源使用分页
      • 有条件地应用属性
      • API资源的更多自定义
    • API 认证和Laravel Passport
      • OAuth 2.0 简介
      • 安装Passport
      • Passport的API
      • Passport的有效授权类型
      • 使用Passport API和vue组件管理客户端和令牌
      • Passport 作用域
      • 部署Passport
    • API Token认证
    • 自定义404响应
      • 触发回退路由
    • 测试
    • 总结
  • 存储和检索
Powered by GitBook
On this page

Was this helpful?

  1. 请求,响应,和中间件
  2. 响应对象

序列化响应类型

有一些特殊的响应类型用于视图,下载,文件以及JSON,每个都是一个预定义的宏,可以轻松地复用头或内容结构。

视图响应

在第4章中,我们使用全局view()函数演示如何返回模板,例如-view('view.name.here')或者类似的内容。但是如果你要自定义头,HTTP状态码,或者其他的内容,可以如示例10-7一样使用view()

Example 10-7. Using the view() response type
Route::get('/', function (XmlGetterService $xml) { 
    $data = $xml->get();
    return response()
        ->view('xml-structure', $data)
        ->header('Content-Type', 'text/xml');
});

下载响应

有时,您希望应用程序强制用户的浏览器下载文件,无论您是在Laravel中创建文件,还是从数据库或受保护的位置为其提供服务。download()响应类型简化了这一过程。

所需的第一个参数是希望浏览器下载的文件的路径。如果是生成的文件,则需要将其临时保存到某个位置。

可选的第二个参数是下载文件的文件名(例如export.csv)。如果您不在此处传递字符串,它将自动生成。可选的第三个参数允许您传递一个头数组。示例10-8说明了download()响应类型的使用。

Example 10-8. Using the download() response type
public function export() {
    return response()
        ->download('file.csv', 'export.csv', ['header' => 'value']);
}

public function otherExport() {
    return response()->download('file.pdf'); 
}

如果要在返回下载响应后从磁盘中删除原始文件,可以在download()方法之后链式调用deleteFileAfterSend()方法:

public function export() {
    return response()
        ->download('file.csv', 'export.csv')
        ->deleteFileAfterSend();
}

文件响应

文件响应类似于下载响应,但它允许浏览器显示文件而不是强制下载。这在图像和PDF中最常见。

所需的第一个参数是文件名,可选的第二个参数可以是一个头数组(参见示例10-9)。

Example 10-9. Using the file() response type
public function invoice($id) {
    return response()->file("./invoices/{$id}.pdf", ['header' => 'value']); 
}

JSON响应

JSON响应非常常见,即使它们对程序来说并不是特别复杂,但它们也有一个定制的响应。

JSON响应将传递的数据转换为JSON(使用json_encode())并将内容类型设置为application/json。您也可以选择使用setCallback()方法来创建JSONP响应,而不是JSON,如示例10-10所示。

Example 10-10. Using the json() response type
public function contacts() {
    return response()->json(Contact::all()); 
}

public function jsonpContacts(Request $request) {
    return response()
        ->json(Contact::all())
        ->setCallback($request->input('callback'));
}

public function nonEloquentContacts() {
    return response()->json(['Tom', 'Jerry']); 
}

重定向响应

重定向通常不是在response()帮助程序上调用的,因此它们与我们已经讨论过的其他自定义响应类型略有不同,但它们仍然只是一种不同的响应。重定向,从Laravel路由返回,向用户发送重定向(通常是301)到另一页或返回到上一页。

从技术上讲,您可以从response()调用重定向,如返回response()->redirectTo('/')。 但更常见的是,您将使用特定于重定向的全局帮助程序。

有一个全局redirect()函数可用于创建重定向响应,还有一个全局back()函数是redirect()->back()的快捷方式。

就像大多数全局帮助程序一样,redirect()全局函数既可以传递参数,也可以用于获取其类的实例,然后链式调用该实例方法。 如果你不链式调用,只是传递参数,redirect()的执行方式与redirect()-> to()相同; 它需要一个字符串并重定向到该字符串URL。 例10-11显示了它的一些使用例子.

Example 10-11. Examples of using the redirect() global helper
return redirect('account/payment');
return redirect()->to('account/payment');
return redirect()->route('account.payment');
return redirect()->action('AccountController@showPayment');
// If redirecting to an external domain
return redirect()->away('https://tighten.co');
// If named route or controller needs parameters
return redirect()->route('contacts.edit', ['id' => 15]);
return redirect()->action('ContactsController@edit', ['id' => 15]);

你也可以重定向”回“之前的页面,当处理和验证用户输入特别有用,如示例10-12显示了验证例子。

Example 10-12. Redirect back with input
public function store() {
    // If validation fails...
    return back()->withInput(); 
}

最后,你可以在重定向的同时闪存数据到session,通常携带错误或者成功消息,如示例10-13。

Example 10-13. Redirect with flashed data
Route::post('contacts', function () { 
    // Store the contact
    return redirect('dashboard')->with('message', 'Contact created!');
});
Route::get('dashboard', function () {
    // Get the flashed data from session--usually handled in Blade template 
    echo session('message');
});

自定义响应宏

还可以使用宏创建自己的自定义响应类型。这允许您定义对响应及其提供的内容进行的一系列修改。

让我们重新创建json()自定义响应类型,只是为了看它是如何工作的。 与往常一样,您应该为这些类型的绑定创建自定义服务提供程序,但是现在我们只需将它放在AppServiceProvider中,如例10-14所示。

Example 10-14. Creating a custom response macro
class AppServiceProvider {
    public function boot() {
        Response::macro('myJson', function ($content) { 
        return response(json_encode($content))
            ->withHeaders(['Content-Type' => 'application/json']);
         }); 
    }

然后,我们可以像之前json()一样使用宏:

return response()->myJson(['name' => 'Sangeetha']);

这将返回一编码过的json数组,然后带有JSON头。

响应式接口

如果你想自定义发送的响应并且宏不能满足需求,或者如果你希望任何对象都能够以“响应”的形式返回,并具有自己的逻辑用于显示,响应式接口正用于此(Laravel 5.5可用)。

响应式接口,Illuminate\Contracts\Support\Responsable指示其实现者必须要有toResponse方法,需要返回一个Illuminate对象。示例10-15说明如何创建响应式对象。

Example 10-15. Creating a simple Responsable object
use Illuminate\Contracts\Support\Responsable;
class MyJson implements Responsable {
    public function __construct($content) {
        $this->content = $content;
    }
    public function toResponse() {
        return response(json_encode($this->content))
            ->withHeaders(['Content-Type' => 'application/json']);
    }

然后我们像宏一样调用。

return new MyJson(['name' => 'Sangeetha']);

这可能看起来像是相对于响应宏的大量工作。但是,当您处理更复杂的控制器操作时,可响应的界面确实很好用。一个常见的示例是使用它来创建视图模型(或视图对象),如示例10-16中所示。

Example 10-16. Using Responsable to create a view object
use Illuminate\Contracts\Support\Responsable;
class GroupDonationDashboard implements Responsable {
    public function __construct($group) {
        $this->group = $group;
    }
    public function budgetThisYear() {
        // ...
    }
    public function giftsThisYear() {
        // ...
    }
    public function toResponse() {
        return view('groups.dashboard')
            ->with('annual_budget', $this->budgetThisYear())
            ->with('annual_gifts_received', $this->giftsThisYear());
    }

在这种情况下,它开始变得更有意义,将复杂的视图移动到一个专用的、可测试的对象中,并保持控制器干净。这是一个控制器,它使用了那个响应对象.

class GroupController {
    public function index(Group $group) {
        return new GroupDonationsDashboard($group); 
    }

Previous在控制器内使用和创建响应对象NextLaravel和中间件

Last updated 5 years ago

Was this helpful?