├── artisan.md
├── authentication.md
├── billing.md
├── blade.md
├── cache.md
├── collections.md
├── container.md
├── contracts.md
├── contributing.md
├── contributions.md
├── controllers.md
├── database.md
├── documentation.md
├── elixir.md
├── eloquent-collections.md
├── eloquent-mutators.md
├── eloquent-relationships.md
├── eloquent-serialization.md
├── eloquent.md
├── encryption.md
├── envoy.md
├── errors.md
├── events.md
├── facades.md
├── filesystem.md
├── hashing.md
├── helpers.md
├── homestead.md
├── installation.md
├── license.md
├── lifecycle.md
├── localization.md
├── mail.md
├── middleware.md
├── migrations.md
├── packages.md
├── pagination.md
├── providers.md
├── queries.md
├── queues.md
├── readme.md
├── redis.md
├── releases.md
├── requests.md
├── responses.md
├── routing.md
├── scheduling.md
├── seeding.md
├── session.md
├── structure.md
├── testing.md
├── upgrade.md
├── validation.md
└── views.md
/artisan.md:
--------------------------------------------------------------------------------
1 | # Artisan 控制台
2 |
3 | - [介绍](#introduction)
4 | - [编写命令](#writing-commands)
5 | - [命令结构](#command-structure)
6 | - [命令 I/O](#command-io)
7 | - [定义输入期望值](#defining-input-expectations)
8 | - [获取输入值](#retrieving-input)
9 | - [输入提示](#prompting-for-input)
10 | - [编写输出](#writing-output)
11 | - [注册命令](#registering-commands)
12 | - [通过代码调用命令](#calling-commands-via-code)
13 |
14 |
15 | ## 介绍
16 |
17 | Artisan是包含在Laravel中命令行界面的名字。 它提供了很多有用的命令用于开发你的程序。它是基于强大的Symfony控制台组件开发。想要查看所有可用的Artisan命令,你可以使用‘list’命令:
18 |
19 | php artisan list
20 |
21 | 每个命令也包含了一个帮助界面去显示和描述该命令可用的参数和选项。要查看帮助界面,可以使用‘help’命令:
22 |
23 | php artisan help migrate
24 |
25 |
26 | ## 编写命令
27 |
28 | 除了Artisan提供的命令,你也可以创建自定义命令在你的程序中使用。你可以把你的自定义命令保存到`app/Console/Commands`目录中;尽管如此,你也可以选择保存到任意地方只要你的命令能被自动加载基于你的`composer.json`配置。
29 |
30 | 要编写一个新命令,你可以用这个Artisan命令`make:console`生成一个命令存根来帮助你开始:
31 |
32 | php artisan make:console SendEmails
33 |
34 | 上面这个命令会在`app/Console/Commands/SendEmails.php`上生成一个类。 创建命令的时候,这个`--command`选项可以用来定义终端命令名字:
35 |
36 | php artisan make:console SendEmails --command=emails:send
37 |
38 |
39 | ### 命令结构
40 |
41 | 你的命令生成之后,你应该填写这个类的`signature`和`description`属性,这两个属性用来显示你的命令在`list`界面。
42 |
43 | 当你的命令被执行的时候,`handle`方法会被调用。你可以在这个方法中编写任意命令逻辑。让我们来看一个例子命令。
44 |
45 | 记住这个:我们可以在命令的构造器中注入任何我们需要的依赖。Laravel [service container](/docs/{{version}}/container)会自动注入所有类型提示的依赖在构造器中。为了更好的代码复用性,保持你的命令轻量和让他们顺从程序服务去完成他们的任务是一个好习惯。
46 |
47 | drip = $drip;
90 | }
91 |
92 | /**
93 | * Execute the console command.
94 | *
95 | * @return mixed
96 | */
97 | public function handle()
98 | {
99 | $this->drip->send(User::find($this->argument('user')));
100 | }
101 | }
102 |
103 |
104 | ## 命令 I/O
105 |
106 |
107 | ### 定义输入期望值
108 |
109 | 编写命令的时候,一般是通过参数或者选项获取用户的输入。Laravel通过使用你的命令的`signature`属性让定义你期望的用户输入变得很方便。这个`signature`属性允许你通过一种简单的,有表现力的,易读的语法定义命令的名字,参数和选项。
110 |
111 | 所有用户输入的参数和选项会被包入大括号中,例如:
112 |
113 | /**
114 | * The name and signature of the console command.
115 | *
116 | * @var string
117 | */
118 | protected $signature = 'email:send {user}';
119 |
120 | 在这个例子中,这个命令定义了一个必填参数:`user`。你也可以把参数设为可选和给可选参数定义默认值:
121 |
122 | // 可选参数...
123 | email:send {user?}
124 |
125 | // 可选参数和默认值...
126 | email:send {user=foo}
127 |
128 | 选项,像参数一样,也是一种用户输入形式。虽然如此,他们在命令行中输入的时候需要加两个短横线(`--`)作为前缀。我们可以这样定义选项在signature中:
129 |
130 | /**
131 | * The name and signature of the console command.
132 | *
133 | * @var string
134 | */
135 | protected $signature = 'email:send {user} {--queue}';
136 |
137 | 在这个例子中,这个`--queue`选项在调用这个Artisan命令的时候可以被指定。如果传递了`--queue`选项,它的值为`true`。否则,它的值为`false`:
138 |
139 | php artisan email:send 1 --queue
140 |
141 | 你也可以让用户给这个选项赋值通过在选项后加等于号`=`,来指示这个值将会由用户来指定:
142 |
143 | /**
144 | * The name and signature of the console command.
145 | *
146 | * @var string
147 | */
148 | protected $signature = 'email:send {user} {--queue=}';
149 |
150 | 这个例子中,用户可以像这样给这个选项赋值:
151 |
152 | php artisan email:send 1 --queue=default
153 |
154 | 你也可以给这个选项指定默认值:
155 |
156 | email:send {user} {--queue=default}
157 |
158 | #### 输入描述
159 |
160 | 你可以为参数和选项定义描述如下通过冒号分割参数与描述:
161 |
162 | /**
163 | * The name and signature of the console command.
164 | *
165 | * @var string
166 | */
167 | protected $signature = 'email:send
168 | {user : The ID of the user}
169 | {--queue= : Whether the job should be queued}';
170 |
171 |
172 | ### 获取输入
173 |
174 | 当你的命令执行的时候,很明显你需要获取你的命令接收的参数及选项的值。想要获取这些值,你可以使用`argument` 和 `option`方法:
175 |
176 | 获取某个参数的值,使用`argument`方法:
177 |
178 | /**
179 | * Execute the console command.
180 | *
181 | * @return mixed
182 | */
183 | public function handle()
184 | {
185 | $userId = $this->argument('user');
186 |
187 | //
188 | }
189 |
190 | 如果你需要获取所有参数的值来作为一个数组,调用无参方法`argument`:
191 |
192 | $arguments = $this->argument();
193 |
194 | 通过`option`方法可以获取选项的值,就像获取参数的值一样简单。和`argument`方法一样,通过调用无参方法`option`可以获取到所有的选项值来作为一个数组:
195 |
196 | // Retrieve a specific option...
197 | $queueName = $this->option('queue');
198 |
199 | // Retrieve all options...
200 | $options = $this->option();
201 |
202 | 如果参数和选项不存在,将返回空值`null`。
203 |
204 |
205 | ### 输入提示
206 |
207 | 为了显示输出,在你的命令执行过程中你可能需要向用户请求输入一些信息。这个`ask`方法就可以通过既定的问题提示用户,然后获取用户输入的信息并返回给你的命令:
208 |
209 | /**
210 | * Execute the console command.
211 | *
212 | * @return mixed
213 | */
214 | public function handle()
215 | {
216 | $name = $this->ask('What is your name?');
217 | }
218 |
219 | 这个`secret`方法和`ask`方法类似,但在用户输入时输入信息用户不可见。这个方法会很有用当要求用户输入一些敏感信息的时候,例如密码:
220 |
221 | $password = $this->secret('What is the password?');
222 |
223 | #### 请求确认
224 |
225 | 如果你需要请求用户做一个简单确认,你可以使用`confirm`方法。默认这个方法会返回`false`。虽然如此,如果用户输入了`y`作为回应,这个方法会返回`true`。
226 |
227 | if ($this->confirm('Do you wish to continue? [y|N]')) {
228 | //
229 | }
230 |
231 | #### 给用户一个选择
232 |
233 | `anticipate`方法用来为可能的选择做自动填充。用户仍然可以填任何答案而无视这些选项。
234 |
235 | $name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);
236 |
237 | 如果你需要让用户必须从给定的选项中选,你可以使用`choice`方法。用户选择答案的索引,但答案的值返回给你。你可以设定返回默认值如果什么都没有选的话:
238 |
239 | $name = $this->choice('What is your name?', ['Taylor', 'Dayle'], false);
240 |
241 |
242 | ### 编写输出
243 |
244 | 使用`info`,`comment`,`question`和`error`方法,可以发送输出到命令行。这些方法中的每一个都会根据他们的目的使用合适的ANSI颜色来显示。
245 |
246 | 使用`info`方法来显示信息。一般情况下,在命令行中会显示为绿色文本:
247 |
248 | /**
249 | * Execute the console command.
250 | *
251 | * @return mixed
252 | */
253 | public function handle()
254 | {
255 | $this->info('Display this on the screen');
256 | }
257 |
258 | 使用`error`方法来显示错误信息。一般情况下,在命令行中会显示为红色文本:
259 |
260 | $this->error('Something went wrong!');
261 |
262 | #### 表格布局
263 |
264 | `table`方法让以正确格式显示多行多列数据变得很容易。只需要把表头和记录传给这个方法。宽和高都会被动态计算出来根据传入的数据:
265 |
266 | $headers = ['Name', 'Email'];
267 |
268 | $users = App\User::all(['name', 'email'])->toArray();
269 |
270 | $this->table($headers, $users);
271 |
272 | #### 进度条
273 |
274 | 对于耗时任务,显示一个进度条是很有帮助的。使用输出对象,我们可以开始,推进和停止进度。你必须定义总步数当开始进度的时候,然后在每一步完成之后推进进度:
275 |
276 | $users = App\User::all();
277 |
278 | $this->output->progressStart(count($users));
279 |
280 | foreach ($users as $user) {
281 | $this->performTask($user);
282 |
283 | $this->output->progressAdvance();
284 | }
285 |
286 | $this->output->progressFinish();
287 |
288 | 想了解更多高级选项,请查看 [Symfony Progress Bar component documentation](http://symfony.com/doc/2.7/components/console/helpers/progressbar.html).
289 |
290 |
291 | ## 注册命令
292 |
293 | 当你的命令完成之后,你需要注册才可以使用。这个可以在`app/Console/Kernel.php`文件中完成。
294 |
295 | 在这个文件中,你会发现一个命令列表在`commands`属性中。要注册你的命令,只需要简单的把类名加到列表中。当Artisan启动时,所有在这个属性中的命令都会被[service container](/docs/{{version}}/container)解析和用Artisan注册:
296 |
297 | protected $commands = [
298 | 'App\Console\Commands\SendEmails'
299 | ];
300 |
301 |
302 | ## 通过代码调用命令
303 |
304 | 有时候你可能希望执行一个Artisan命令在命令行之外。例如,你希望触发一个Artisan命令在一个路由或者控制器里。你可以通过`Artisan` facade的`call`方法去完成它。`call`方法接收命令名作为第一个参数,命令参数数组作为第二个参数。退出代码(exit code)将被返回:
305 |
306 | Route::get('/foo', function () {
307 | $exitCode = Artisan::call('email:send', [
308 | 'user' => 1, '--queue' => 'default'
309 | ]);
310 |
311 | //
312 | });
313 |
314 | 使用`Artisan` facade的`queue`方法,你甚至可以把命令放入队列,这样他们就可以在后台通过[queue workers](/docs/{{version}}/queues)被处理:
315 |
316 | Route::get('/foo', function () {
317 | Artisan::queue('email:send', [
318 | 'user' => 1, '--queue' => 'default'
319 | ]);
320 |
321 | //
322 | });
323 |
324 | 如果你需要指定的选项不接收字符串,例如`migrate:refresh`命令的`--force`选项,你可以传递一个布尔值`true` 或者 `false`:
325 |
326 | $exitCode = Artisan::call('migrate:refresh', [
327 | '--force' => true,
328 | ]);
329 |
330 | ### 从其他命令中调用命令
331 |
332 | 有时你希望从已有Artisan命令中调用其它命令。你可以使用`call`方法。这个`call`方法接收命令名和命令参数数组作为参数:
333 |
334 | /**
335 | * Execute the console command.
336 | *
337 | * @return mixed
338 | */
339 | public function handle()
340 | {
341 | $this->call('email:send', [
342 | 'user' => 1, '--queue' => 'default'
343 | ]);
344 |
345 | //
346 | }
347 |
348 | 如果你想调用另一个命令并忽略它所有的输出,你可以使用`callSilent`方法。`callSilent`方法接收的参数和`call`方法一样:
349 |
350 | $this->callSilent('email:send', [
351 | 'user' => 1, '--queue' => 'default'
352 | ]);
353 |
--------------------------------------------------------------------------------
/blade.md:
--------------------------------------------------------------------------------
1 | # 模板Blade
2 |
3 | - [简介](#introduction)
4 | - [模板继承](#template-inheritance)
5 | - [定义布局](#defining-a-layout)
6 | - [扩展布局](#extending-a-layout)
7 | - [显示数据](#displaying-data)
8 | - [控制器](#control-structures)
9 | - [服务依赖](#service-injection)
10 | - [Blade扩展](#extending-blade)
11 |
12 |
13 | ## 简介
14 |
15 | Laravel提供了一个简单强大的模板引擎. 与其他的PHP模板引擎不一样的是,Blade在Views中允许使用PHP代码. Blade视图发生变化时,就会被解析成PHP代码,并且缓存起来,所以Blade不会对你的应用程序产生任何负担。 Blade视图文件以‘blade.php’结尾,所有文件都放在'resources/views'文件夹中。
16 |
17 |
18 | ## 模板继承
19 |
20 |
21 | ### 定义布局
22 |
23 | Blade两个主要的优点就是_模板继承_和_模块化_.在这之前,先看一个简单的例子。首先,我们先看一个“master”布局页面。由于大多数的web应用都使用相同的布局,所以我们只需要定义一种Blade视图。
24 |
25 |
26 |
27 |
28 |
29 | App Name - @yield('title')
30 |
31 |
32 | @section('sidebar')
33 | This is the master sidebar.
34 | @show
35 |
36 |
37 | @yield('content')
38 |
39 |
40 |
41 |
42 | 这个文件是非常经典的HTTML标记。需要注意的是,这里面有`@section`和`@yield`命令。`@section`和字面上的意思一样,它定义了内容的一部分,而`@yield`命令用来表示给出的section的内容。
43 |
44 | 现在我们已经定义了应用的布局,接下来我们对这个布局继承一个子页面。
45 |
46 |
47 | ### 布局扩展
48 |
49 | 当定义子页面时,我们就可以用Blade的`@extends`命令来说明这个子页面'inherit'(继承)的是哪个。`@extends`一个Blade布局的视图可以将内容注入到用`@section`命令的布局中的某一个部分。记住,在上面的这个例子中,我们是用`@yield`命令来展示布局中的这些部分内容。
50 |
51 |
52 |
53 | @extends('layouts.master')
54 |
55 | @section('title', 'Page Title')
56 |
57 | @section('sidebar')
58 | @@parent
59 |
60 | This is appended to the master sidebar.
61 | @endsection
62 |
63 | @section('content')
64 | This is my body content.
65 | @endsection
66 |
67 | 在这个例子中,'sidebar'部分就是利用`@@parent`命令来将内容追加到布局中的sidebar中。这个视图被渲染时,`@@parent`命令就会被布局中的内容所替换。
68 |
69 | 当然,这些简单的PHP视图,路由会调用`view`帮助方法将这些Blade视图返回。
70 |
71 | Route::get('blade', function () {
72 | return view('child');
73 | });
74 |
75 |
76 | ## 展示数据
77 |
78 | 在Blade视图中展示数据时,需要将变量放在大括号中括起来。请看下面的路由的例子:
79 |
80 | Route::get('greeting', function () {
81 | return view('welcome', ['name' => 'Samantha']);
82 | });
83 |
84 | 如果想展示`name`的内容,可以用下面的方法:
85 |
86 | Hello, {{ $name }}.
87 |
88 | 当然,你不会被局限于使用视图中的变量,你也可以用PHP方法输出结果。事实上,你在Blade中可以任意使用PHP代码来输出语句:
89 |
90 | The current UNIX timestamp is {{ time() }}.
91 |
92 | > **Note:** Blade 中的`{{}}`语句会自动调用PHP的`htmlentities`方法来抵御XSS攻击。
93 |
94 | #### Blade & JavaScript 框架
95 |
96 | 由于JavaScript框架在浏览器中大都使用大括号来表示表达式,你可以使用`@`符号来告诉Blade引擎这个表达式不需要解析。例如:
97 |
98 | Laravel
99 |
100 | Hello, @{{ name }}.
101 |
102 | 这个例子中,这个`@`符号在Blade中会被删掉;然而,`{{name}}`表达式在Blade引擎中会保持不变,这样JavaScript框架就会对它进行处理。
103 |
104 | #### 三元运算
105 |
106 | 有的时候你想输入一个变量时,但是你可能不确定这个变量是否被定义了。在PHP代码中,我们就需要这么写,但是这样有点啰嗦:
107 |
108 | {{ isset($name) ? $name : 'Default' }}
109 |
110 | 高兴的是,Blade提供了一个简单快捷的三元运算表示方法。
111 |
112 | {{ $name or 'Default' }}
113 |
114 | 这个例子中,`$name`如果存在,就会被展示。如果不存在,就会输出一个默认的`Default`。
115 |
116 | #### 展示非转义的数据
117 |
118 | 默认情况下,Blade 中的`{{ }}`语句会自动调用PHP中的`htmlentities`方法转义来抵御XSS攻击。如果你不想让数据被转义,可以用下面的语法:
119 |
120 | Hello, {!! $name !!}.
121 |
122 | > **Note:** 在应用程序中输出用户的输入的数据要非常小心。我们经常会用双花括号表示我们需要转义成HTML实体。
123 |
124 |
125 | ## 控制结构
126 |
127 | 除了模板集成和展示动态数据,Blade也提供了简单的PHP结构控制结构,比如条件语句和循环语句。这些短标签和PHP控制语句一起使用,非常简洁优雅,对PHP非常友好。
128 |
129 | #### 条件语句
130 |
131 | 条件语句中可以使用`@if`,`@elseif`,`@endif`命令,这些命令跟PHP的使用方式一样:
132 |
133 | @if (count($records) === 1)
134 | I have one record!
135 | @elseif (count($records) > 1)
136 | I have multiple records!
137 | @else
138 | I don't have any records!
139 | @endif
140 |
141 | 为了更方便,Blade还提供了一个`@unless`命令:
142 |
143 | @unless (Auth::check())
144 | You are not signed in.
145 | @endunless
146 |
147 | #### 循环
148 |
149 | 除了条件语句,Blade还提供了一个简单的命令来对应PHP中的循环结构。他们跟PHP的用法是一样的:
150 |
151 | @for ($i = 0; $i < 10; $i++)
152 | The current value is {{ $i }}
153 | @endfor
154 |
155 | @foreach ($users as $user)
156 | This is user {{ $user->id }}
157 | @endforeach
158 |
159 | @forelse ($users as $user)
160 | {{ $user->name }}
161 | @empty
162 | No users
163 | @endforelse
164 |
165 | @while (true)
166 | I'm looping forever.
167 | @endwhile
168 |
169 | #### 包含子视图
170 |
171 | Blade中的`@include`命令,让你在一个已有的视图里面包含一个Blade视图变得更加容易。被包含的视图可以使用所有的父级视图中的变量:
172 |
173 |
174 | @include('shared.errors')
175 |
176 |
179 |
180 |
181 | 尽管包含的视图可以继承父级视图的所有数据变量,你也仍然可以在包含的视图中对数据进行扩展:
182 |
183 | @include('view.name', ['some' => 'data'])
184 |
185 | #### 注释
186 |
187 | Blade 也允许你在视图中注释。但是你的应用程序只能包含HTML注释:
188 |
189 | {{-- This comment will not be present in the rendered HTML --}}
190 |
191 |
192 | ## 服务注入
193 |
194 | `@inject` 可以将Laravel中的服务[服务容器](/docs/{{version}}/container)注入进来.`@inject`的第一个参数将会被定义成service的名称,第二个参数是用来被处理的class/interface:
195 |
196 | @inject('metrics', 'App\Services\MetricsService')
197 |
198 |
199 | Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
200 |
201 |
202 |
203 | ## Blade 扩展
204 |
205 | Blade甚至允许你定义你的习惯用法。你可以使用`directive`方式来注册一个命令。当Blade编译器遇到这个命令时,他就会调用回调方法来处理这些参数。
206 |
207 | 下面的例子就是创建了一个`@datetime($var)`的命令来格式化给定的`$var`:
208 |
209 | format('m/d/Y H:i'); ?>";
227 | });
228 | }
229 |
230 | /**
231 | * Register bindings in the container.
232 | *
233 | * @return void
234 | */
235 | public function register()
236 | {
237 | //
238 | }
239 | }
240 |
241 | 你可以看到,Laravel中的`with`帮助方法在下面的语句中会被使用。这个`with`方法用链式方式简单的返回一个object/value,最终的PHP语句是这样的:
242 |
243 | format('m/d/Y H:i'); ?>
244 |
245 |
246 |
--------------------------------------------------------------------------------
/container.md:
--------------------------------------------------------------------------------
1 | # Service Container
2 |
3 | - [Introduction](#introduction)
4 | - [Binding](#binding)
5 | - [Binding Interfaces To Implementations](#binding-interfaces-to-implementations)
6 | - [Contextual Binding](#contextual-binding)
7 | - [Tagging](#tagging)
8 | - [Resolving](#resolving)
9 | - [Container Events](#container-events)
10 |
11 |
12 | ## Introduction
13 |
14 | The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are "injected" into the class via the constructor or, in some cases, "setter" methods.
15 |
16 | Let's look at a simple example:
17 |
18 | mailer = $mailer;
42 | }
43 |
44 | /**
45 | * Purchase a podcast.
46 | *
47 | * @return void
48 | */
49 | public function handle()
50 | {
51 | //
52 | }
53 | }
54 |
55 | In this example, the `PurchasePodcast` job needs to send e-mails when a podcast is purchased. So, we will **inject** a service that is able to send e-mails. Since the service is injected, we are able to easily swap it out with another implementation. We are also able to easily "mock", or create a dummy implementation of the mailer when testing our application.
56 |
57 | A deep understanding of the Laravel service container is essential to building a powerful, large application, as well as for contributing to the Laravel core itself.
58 |
59 |
60 | ## Binding
61 |
62 | Almost all of your service container bindings will be registered within [service providers](/docs/{{version}}/providers), so all of these examples will demonstrate using the container in that context. However, there is no need to bind classes into the container if they do not depend on any interfaces. The container does not need to be instructed how to build these objects, since it can automatically resolve such "concrete" objects using PHP's reflection services.
63 |
64 | Within a service provider, you always have access to the container via the `$this->app` instance variable. We can register a binding using the `bind` method, passing the class or interface name that we wish to register along with a `Closure` that returns an instance of the class:
65 |
66 | $this->app->bind('HelpSpot\API', function ($app) {
67 | return new HelpSpot\API($app['HttpClient']);
68 | });
69 |
70 | Notice that we receive the container itself as an argument to the resolver. We can then use the container to resolve sub-dependencies of the object we are building.
71 |
72 | #### Binding A Singleton
73 |
74 | The `singleton` method binds a class or interface into the container that should only be resolved one time, and then that same instance will be returned on subsequent calls into the container:
75 |
76 | $this->app->singleton('FooBar', function ($app) {
77 | return new FooBar($app['SomethingElse']);
78 | });
79 |
80 | #### Binding Instances
81 |
82 | You may also bind an existing object instance into the container using the `instance` method. The given instance will always be returned on subsequent calls into the container:
83 |
84 | $fooBar = new FooBar(new SomethingElse);
85 |
86 | $this->app->instance('FooBar', $fooBar);
87 |
88 |
89 | ### Binding Interfaces To Implementations
90 |
91 | A very powerful feature of the service container is its ability to bind an interface to a given implementation. For example, let's assume we have an `EventPusher` interface and a `RedisEventPusher` implementation. Once we have coded our `RedisEventPusher` implementation of this interface, we can register it with the service container like so:
92 |
93 | $this->app->bind('App\Contracts\EventPusher', 'App\Services\RedisEventPusher');
94 |
95 | This tells the container that it should inject the `RedisEventPusher` when a class needs an implementation of `EventPusher`. Now we can type-hint the `EventPusher` interface in a constructor, or any other location where dependencies are injected by the service container:
96 |
97 | use App\Contracts\EventPusher;
98 |
99 | /**
100 | * Create a new class instance.
101 | *
102 | * @param EventPusher $pusher
103 | * @return void
104 | */
105 | public function __construct(EventPusher $pusher)
106 | {
107 | $this->pusher = $pusher;
108 | }
109 |
110 |
111 | ### Contextual Binding
112 |
113 | Sometimes you may have two classes that utilize the same interface, but you wish to inject different implementations into each class. For example, when our system receives a new Order, we may want to send an event via [PubNub](http://www.pubnub.com/) rather than Pusher. Laravel provides a simple, fluent interface for defining this behavior:
114 |
115 | $this->app->when('App\Handlers\Commands\CreateOrderHandler')
116 | ->needs('App\Contracts\EventPusher')
117 | ->give('App\Services\PubNubEventPusher');
118 |
119 | You may even pass a Closure to the `give` method:
120 |
121 | $this->app->when('App\Handlers\Commands\CreateOrderHandler')
122 | ->needs('App\Contracts\EventPusher')
123 | ->give(function () {
124 | // Resolve dependency...
125 | });
126 |
127 |
128 | ### Tagging
129 |
130 | Occasionally, you may need to resolve all of a certain "category" of binding. For example, perhaps you are building a report aggregator that receives an array of many different `Report` interface implementations. After registering the `Report` implementations, you can assign them a tag using the `tag` method:
131 |
132 | $this->app->bind('SpeedReport', function () {
133 | //
134 | });
135 |
136 | $this->app->bind('MemoryReport', function () {
137 | //
138 | });
139 |
140 | $this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');
141 |
142 | Once the services have been tagged, you may easily resolve them all via the `tagged` method:
143 |
144 | $this->app->bind('ReportAggregator', function ($app) {
145 | return new ReportAggregator($app->tagged('reports'));
146 | });
147 |
148 |
149 | ## Resolving
150 |
151 | There are several ways to resolve something out of the container. First, you may use the `make` method, which accepts the name of the class or interface you wish to resolve:
152 |
153 | $fooBar = $this->app->make('FooBar');
154 |
155 | Secondly, you may access the container like an array, since it implements PHP's `ArrayAccess` interface:
156 |
157 | $fooBar = $this->app['FooBar'];
158 |
159 | Lastly, but most importantly, you may simply "type-hint" the dependency in the constructor of a class that is resolved by the container, including [controllers](/docs/{{version}}/controllers), [event listeners](/docs/{{version}}/events), [queue jobs](/docs/{{version}}/queues), [middleware](/docs/{{version}}/middleware), and more. In practice, this is how most of your objects are resolved by the container.
160 |
161 | The container will automatically inject dependencies for the classes it resolves. For example, you may type-hint a repository defined by your application in a controller's constructor. The repository will automatically be resolved and injected into the class:
162 |
163 | users = $users;
186 | }
187 |
188 | /**
189 | * Show the user with the given ID.
190 | *
191 | * @param int $id
192 | * @return Response
193 | */
194 | public function show($id)
195 | {
196 | //
197 | }
198 | }
199 |
200 |
201 | ## Container Events
202 |
203 | The service container fires an event each time it resolves an object. You may listen to this event using the `resolving` method:
204 |
205 | $this->app->resolving(function ($object, $app) {
206 | // Called when container resolves object of any type...
207 | });
208 |
209 | $this->app->resolving(function (FooBar $fooBar, $app) {
210 | // Called when container resolves objects of type "FooBar"...
211 | });
212 |
213 | As you can see, the object being resolved will be passed to the callback, allowing you to set any additional properties on the object before it is given to its consumer.
214 |
--------------------------------------------------------------------------------
/contracts.md:
--------------------------------------------------------------------------------
1 | # Contracts
2 |
3 | - [Introduction](#introduction)
4 | - [Why Contracts?](#why-contracts)
5 | - [Contract Reference](#contract-reference)
6 | - [How To Use Contracts](#how-to-use-contracts)
7 |
8 |
9 | ## Introduction
10 |
11 | Laravel's Contracts are a set of interfaces that define the core services provided by the framework. For example, a `Illuminate\Contracts\Queue\Queue` contract defines the methods needed for queueing jobs, while the `Illuminate\Contracts\Mail\Mailer` contract defines the methods needed for sending e-mail.
12 |
13 | Each contract has a corresponding implementation provided by the framework. For example, Laravel provides a queue implementation with a variety of drivers, and a mailer implementation that is powered by [SwiftMailer](http://swiftmailer.org/).
14 |
15 | All of the Laravel contracts live in [their own GitHub repository](https://github.com/illuminate/contracts). This provides a quick reference point for all available contracts, as well as a single, decoupled package that may be utilized by package developers.
16 |
17 | ### Contracts Vs. Facades
18 |
19 | Laravel's [facades](/docs/{{version}}/facades) provide a simple way of utilizing Laravel's services without needing to type-hint and resolve contracts out of the service container. However, using contracts allows you to define explicit dependencies for your classes. For most applications, using a facade is just fine. However, if you really need the extra loose coupling that contracts can provide, keep reading!
20 |
21 |
22 | ## Why Contracts?
23 |
24 | You may have several questions regarding contracts. Why use interfaces at all? Isn't using interfaces more complicated? Let's distil the reasons for using interfaces to the following headings: loose coupling and simplicity.
25 |
26 | ### Loose Coupling
27 |
28 | First, let's review some code that is tightly coupled to a cache implementation. Consider the following:
29 |
30 | cache = $cache;
50 | }
51 |
52 | /**
53 | * Retrieve an Order by ID.
54 | *
55 | * @param int $id
56 | * @return Order
57 | */
58 | public function find($id)
59 | {
60 | if ($this->cache->has($id)) {
61 | //
62 | }
63 | }
64 | }
65 |
66 | In this class, the code is tightly coupled to a given cache implementation. It is tightly coupled because we are depending on a concrete Cache class from a package vendor. If the API of that package changes our code must change as well.
67 |
68 | Likewise, if we want to replace our underlying cache technology (Memcached) with another technology (Redis), we again will have to modify our repository. Our repository should not have so much knowledge regarding who is providing them data or how they are providing it.
69 |
70 | **Instead of this approach, we can improve our code by depending on a simple, vendor agnostic interface:**
71 |
72 | cache = $cache;
89 | }
90 | }
91 |
92 | Now the code is not coupled to any specific vendor, or even Laravel. Since the contracts package contains no implementation and no dependencies, you may easily write an alternative implementation of any given contract, allowing you to replace your cache implementation without modifying any of your cache consuming code.
93 |
94 | ### Simplicity
95 |
96 | When all of Laravel's services are neatly defined within simple interfaces, it is very easy to determine the functionality offered by a given service. **The contracts serve as succinct documentation to the framework's features.**
97 |
98 | In addition, when you depend on simple interfaces, your code is easier to understand and maintain. Rather than tracking down which methods are available to you within a large, complicated class, you can refer to a simple, clean interface.
99 |
100 |
101 | ## Contract Reference
102 |
103 | This is a reference to most Laravel Contracts, as well as their Laravel "facade" counterparts:
104 |
105 | Contract | References Facade
106 | ------------- | -------------
107 | [Illuminate\Contracts\Auth\Guard](https://github.com/illuminate/contracts/blob/master/Auth/Guard.php) | Auth
108 | [Illuminate\Contracts\Auth\PasswordBroker](https://github.com/illuminate/contracts/blob/master/Auth/PasswordBroker.php) | Password
109 | [Illuminate\Contracts\Bus\Dispatcher](https://github.com/illuminate/contracts/blob/master/Bus/Dispatcher.php) | Bus
110 | [Illuminate\Contracts\Broadcasting\Broadcaster](https://github.com/illuminate/contracts/blob/master/Broadcasting/Broadcaster.php) |
111 | [Illuminate\Contracts\Cache\Repository](https://github.com/illuminate/contracts/blob/master/Cache/Repository.php) | Cache
112 | [Illuminate\Contracts\Cache\Factory](https://github.com/illuminate/contracts/blob/master/Cache/Factory.php) | Cache::driver()
113 | [Illuminate\Contracts\Config\Repository](https://github.com/illuminate/contracts/blob/master/Config/Repository.php) | Config
114 | [Illuminate\Contracts\Container\Container](https://github.com/illuminate/contracts/blob/master/Container/Container.php) | App
115 | [Illuminate\Contracts\Cookie\Factory](https://github.com/illuminate/contracts/blob/master/Cookie/Factory.php) | Cookie
116 | [Illuminate\Contracts\Cookie\QueueingFactory](https://github.com/illuminate/contracts/blob/master/Cookie/QueueingFactory.php) | Cookie::queue()
117 | [Illuminate\Contracts\Encryption\Encrypter](https://github.com/illuminate/contracts/blob/master/Encryption/Encrypter.php) | Crypt
118 | [Illuminate\Contracts\Events\Dispatcher](https://github.com/illuminate/contracts/blob/master/Events/Dispatcher.php) | Event
119 | [Illuminate\Contracts\Filesystem\Cloud](https://github.com/illuminate/contracts/blob/master/Filesystem/Cloud.php) |
120 | [Illuminate\Contracts\Filesystem\Factory](https://github.com/illuminate/contracts/blob/master/Filesystem/Factory.php) | File
121 | [Illuminate\Contracts\Filesystem\Filesystem](https://github.com/illuminate/contracts/blob/master/Filesystem/Filesystem.php) | File
122 | [Illuminate\Contracts\Foundation\Application](https://github.com/illuminate/contracts/blob/master/Foundation/Application.php) | App
123 | [Illuminate\Contracts\Hashing\Hasher](https://github.com/illuminate/contracts/blob/master/Hashing/Hasher.php) | Hash
124 | [Illuminate\Contracts\Logging\Log](https://github.com/illuminate/contracts/blob/master/Logging/Log.php) | Log
125 | [Illuminate\Contracts\Mail\MailQueue](https://github.com/illuminate/contracts/blob/master/Mail/MailQueue.php) | Mail::queue()
126 | [Illuminate\Contracts\Mail\Mailer](https://github.com/illuminate/contracts/blob/master/Mail/Mailer.php) | Mail
127 | [Illuminate\Contracts\Queue\Factory](https://github.com/illuminate/contracts/blob/master/Queue/Factory.php) | Queue::driver()
128 | [Illuminate\Contracts\Queue\Queue](https://github.com/illuminate/contracts/blob/master/Queue/Queue.php) | Queue
129 | [Illuminate\Contracts\Redis\Database](https://github.com/illuminate/contracts/blob/master/Redis/Database.php) | Redis
130 | [Illuminate\Contracts\Routing\Registrar](https://github.com/illuminate/contracts/blob/master/Routing/Registrar.php) | Route
131 | [Illuminate\Contracts\Routing\ResponseFactory](https://github.com/illuminate/contracts/blob/master/Routing/ResponseFactory.php) | Response
132 | [Illuminate\Contracts\Routing\UrlGenerator](https://github.com/illuminate/contracts/blob/master/Routing/UrlGenerator.php) | URL
133 | [Illuminate\Contracts\Support\Arrayable](https://github.com/illuminate/contracts/blob/master/Support/Arrayable.php) |
134 | [Illuminate\Contracts\Support\Jsonable](https://github.com/illuminate/contracts/blob/master/Support/Jsonable.php) |
135 | [Illuminate\Contracts\Support\Renderable](https://github.com/illuminate/contracts/blob/master/Support/Renderable.php) |
136 | [Illuminate\Contracts\Validation\Factory](https://github.com/illuminate/contracts/blob/master/Validation/Factory.php) | Validator::make()
137 | [Illuminate\Contracts\Validation\Validator](https://github.com/illuminate/contracts/blob/master/Validation/Validator.php) |
138 | [Illuminate\Contracts\View\Factory](https://github.com/illuminate/contracts/blob/master/View/Factory.php) | View::make()
139 | [Illuminate\Contracts\View\View](https://github.com/illuminate/contracts/blob/master/View/View.php) |
140 |
141 |
142 | ## How To Use Contracts
143 |
144 | So, how do you get an implementation of a contract? It's actually quite simple.
145 |
146 | Many types of classes in Laravel are resolved through the [service container](/docs/{{version}}/container), including controllers, event listeners, middleware, queued jobs, and even route Closures. So, to get an implementation of a contract, you can just "type-hint" the interface in the constructor of the class being resolved.
147 |
148 | For example, take a look at this event listener:
149 |
150 | redis = $redis;
174 | }
175 |
176 | /**
177 | * Handle the event.
178 | *
179 | * @param NewUserRegistered $event
180 | * @return void
181 | */
182 | public function handle(NewUserRegistered $event)
183 | {
184 | //
185 | }
186 | }
187 |
188 | When the event listener is resolved, the service container will read the type-hints on the constructor of the class, and inject the appropriate value. To learn more about registering things in the service container, check out [its documentation](/docs/{{version}}/container).
189 |
--------------------------------------------------------------------------------
/contributing.md:
--------------------------------------------------------------------------------
1 | # Contribution Guidelines
2 |
3 | If you are submitting documentation for the **current stable release**, submit it to the corresponding branch. For example, documentation for Laravel 5.0 would be submitted to the `5.0` branch. Documentation intended for the next release of Laravel should be submitted to the `master` branch.
--------------------------------------------------------------------------------
/contributions.md:
--------------------------------------------------------------------------------
1 | # Contribution Guide
2 |
3 | - [Bug Reports](#bug-reports)
4 | - [Core Development Discussion](#core-development-discussion)
5 | - [Which Branch?](#which-branch)
6 | - [Security Vulnerabilities](#security-vulnerabilities)
7 | - [Coding Style](#coding-style)
8 |
9 |
10 | ## Bug Reports
11 |
12 | To encourage active collaboration, Laravel strongly encourages pull requests, not just bug reports. "Bug reports" may also be sent in the form of a pull request containing a failing test.
13 |
14 | However, if you file a bug report, your issue should contain a title and a clear description of the issue. You should also include as much relevant information as possible and a code sample that demonstrates the issue. The goal of a bug report is to make it easy for yourself - and others - to replicate the bug and develop a fix.
15 |
16 | Remember, bug reports are created in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the bug report will automatically see any activity or that others will jump to fix it. Creating a bug report serves to help yourself and others start on the path of fixing the problem.
17 |
18 | The Laravel source code is managed on Github, and there are repositories for each of the Laravel projects:
19 |
20 | - [Laravel Framework](https://github.com/laravel/framework)
21 | - [Laravel Application](https://github.com/laravel/laravel)
22 | - [Laravel Documentation](https://github.com/laravel/docs)
23 | - [Laravel Cashier](https://github.com/laravel/cashier)
24 | - [Laravel Envoy](https://github.com/laravel/envoy)
25 | - [Laravel Homestead](https://github.com/laravel/homestead)
26 | - [Laravel Homestead Build Scripts](https://github.com/laravel/settler)
27 | - [Laravel Website](https://github.com/laravel/laravel.com)
28 | - [Laravel Art](https://github.com/laravel/art)
29 |
30 |
31 | ## Core Development Discussion
32 |
33 | Discussion regarding bugs, new features, and implementation of existing features takes place in the `#internals` channel of the [LaraChat](http://larachat.co) Slack team. Taylor Otwell, the maintainer of Laravel, is typically present in the channel on weekdays from 8am-5pm (UTC-06:00 or America/Chicago), and sporadically present in the channel at other times.
34 |
35 |
36 | ## Which Branch?
37 |
38 | **All** bug fixes should be sent to the latest stable branch. Bug fixes should **never** be sent to the `master` branch unless they fix features that exist only in the upcoming release.
39 |
40 | **Minor** features that are **fully backwards compatible** with the current Laravel release may be sent to the latest stable branch.
41 |
42 | **Major** new features should always be sent to the `master` branch, which contains the upcoming Laravel release.
43 |
44 | If you are unsure if your feature qualifies as a major or minor, please ask Taylor Otwell in the `#laravel-dev` IRC channel (Freenode).
45 |
46 |
47 | ## Security Vulnerabilities
48 |
49 | If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed.
50 |
51 |
52 | ## Coding Style
53 |
54 | Laravel follows the [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) coding standard and the [PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md) autoloading standard.
55 |
--------------------------------------------------------------------------------
/database.md:
--------------------------------------------------------------------------------
1 | # Database: Getting Started
2 |
3 | - [Introduction](#introduction)
4 | - [Running Raw SQL Queries](#running-queries)
5 | - [Listening For Query Events](#listening-for-query-events)
6 | - [Database Transactions](#database-transactions)
7 | - [Using Multiple Database Connections](#accessing-connections)
8 |
9 |
10 | ## Introduction
11 |
12 | Laravel makes connecting with databases and running queries extremely simple across a variety of database back-ends using either raw SQL, the [fluent query builder](/docs/{{version}}/queries), and the [Eloquent ORM](/docs/{{version}}/eloquent). Currently, Laravel supports four database systems:
13 |
14 | - MySQL
15 | - Postgres
16 | - SQLite
17 | - SQL Server
18 |
19 |
20 | ### Configuration
21 |
22 | Laravel makes connecting with databases and running queries extremely simple. The database configuration for your application is located at `config/database.php`. In this file you may define all of your database connections, as well as specify which connection should be used by default. Examples for all of the supported database systems are provided in this file.
23 |
24 | By default, Laravel's sample [environment configuration](/docs/{{version}}/installation#environment-configuration) is ready to use with [Laravel Homestead](/docs/{{version}}/homestead), which is a convenient virtual machine for doing Laravel development on your local machine. Of course, you are free to modify this configuration as needed for your local database.
25 |
26 |
27 | #### Read / Write Connections
28 |
29 | Sometimes you may wish to use one database connection for SELECT statements, and another for INSERT, UPDATE, and DELETE statements. Laravel makes this a breeze, and the proper connections will always be used whether you are using raw queries, the query builder, or the Eloquent ORM.
30 |
31 | To see how read / write connections should be configured, let's look at this example:
32 |
33 | 'mysql' => [
34 | 'read' => [
35 | 'host' => '192.168.1.1',
36 | ],
37 | 'write' => [
38 | 'host' => '196.168.1.2'
39 | ],
40 | 'driver' => 'mysql',
41 | 'database' => 'database',
42 | 'username' => 'root',
43 | 'password' => '',
44 | 'charset' => 'utf8',
45 | 'collation' => 'utf8_unicode_ci',
46 | 'prefix' => '',
47 | ],
48 |
49 | Note that two keys have been added to the configuration array: `read` and `write`. Both of these keys have array values containing a single key: `host`. The rest of the database options for the `read` and `write` connections will be merged from the main `mysql` array.
50 |
51 | So, we only need to place items in the `read` and `write` arrays if we wish to override the values in the main array. So, in this case, `192.168.1.1` will be used as the "read" connection, while `192.168.1.2` will be used as the "write" connection. The database credentials, prefix, character set, and all other options in the main `mysql` array will be shared across both connections.
52 |
53 |
54 | ## Running Raw SQL Queries
55 |
56 | Once you have configured your database connection, you may run queries using the `DB` facade. The `DB` facade provides methods for each type of query: `select`, `update`, `insert`, `delete`, and `statement`.
57 |
58 | #### Running A Select Query
59 |
60 | To run a basic query, we can use the `select` method on the `DB` facade:
61 |
62 | $users]);
81 | }
82 | }
83 |
84 | The first argument passed to the `select` method is the raw SQL query, while the second argument is any parameter bindings that need to be bound to the query. Typically, these are the values of the `where` clause constraints. Parameter binding provides protection against SQL injection.
85 |
86 | The `select` method will always return an `array` of results. Each result within the array will be a PHP `StdClass` object, allowing you to access the values of the results:
87 |
88 | foreach ($users as $user) {
89 | echo $user->name;
90 | }
91 |
92 | #### Using Named Bindings
93 |
94 | Instead of using `?` to represent your parameter bindings, you may execute a query using named bindings:
95 |
96 | $results = DB::select('select * from users where id = :id', ['id' => 1]);
97 |
98 | #### Running An Insert Statement
99 |
100 | To execute an `insert` statement, you may use the `insert` method on the `DB` facade. Like `select`, this method takes the raw SQL query as its first argument, and bindings as the second argument:
101 |
102 | DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
103 |
104 | #### Running An Update Statement
105 |
106 | The `update` method should be used to update existing records in the database. The number of rows affected by the statement will be returned by the method:
107 |
108 | $affected = DB::update('update users set votes = 100 where name = ?', ['John']);
109 |
110 | #### Running A Delete Statement
111 |
112 | The `delete` method should be used to delete records from the database. Like `update`, the number of rows deleted will be returned:
113 |
114 | $deleted = DB::delete('delete from users');
115 |
116 | #### Running A General Statement
117 |
118 | Some database statements should not return any value. For these types of operations, you may use the `statement` method on the `DB` facade:
119 |
120 | DB::statement('drop table users');
121 |
122 |
123 | ### Listening For Query Events
124 |
125 | If you would like to receive each SQL query executed by your application, you may use the `listen` method. This method is useful for logging queries or debugging. You may register your query listener in a [service provider](/docs/{{version}}/providers):
126 |
127 |
160 | ## Database Transactions
161 |
162 | To run a set of operations within a database transaction, you may use the `transaction` method on the `DB` facade. If an exception is thrown within the transaction `Closure`, the transaction will automatically be rolled back. If the `Closure` executes successfully, the transaction will automatically be committed. You don't need to worry about manually rolling back or committing while using the `transaction` method:
163 |
164 | DB::transaction(function () {
165 | DB::table('users')->update(['votes' => 1]);
166 |
167 | DB::table('posts')->delete();
168 | });
169 |
170 | #### Manually Using Transactions
171 |
172 | If you would like to begin a transaction manually and have complete control over rollbacks and commits, you may use the `beginTransaction` method on the `DB` facade:
173 |
174 | DB::beginTransaction();
175 |
176 | You can rollback the transaction via the `rollBack` method:
177 |
178 | DB::rollBack();
179 |
180 | Lastly, you can commit a transaction via the `commit` method:
181 |
182 | DB::commit();
183 |
184 | > **Note:** Using the `DB` facade's transaction methods also controls transactions for the [query builder](/docs/{{version}}/queries) and [Eloquent ORM](/docs/{{version}}/eloquent).
185 |
186 |
187 | ## Using Multiple Database Connections
188 |
189 | When using multiple connections, you may access each connection via the `connection` method on the `DB` facade. The `name` passed to the `connection` method should correspond to one of the connections listed in your `config/database.php` configuration file:
190 |
191 | $users = DB::connection('foo')->select(...);
192 |
193 | You may also access the raw, underlying PDO instance using the `getPdo` method on a connection instance:
194 |
195 | $pdo = DB::connection()->getPdo();
196 |
--------------------------------------------------------------------------------
/documentation.md:
--------------------------------------------------------------------------------
1 | - 前言
2 | - [发行说明](/docs/{{version}}/releases)
3 | - [升级向导](/docs/{{version}}/upgrade)
4 | - [贡献向导](/docs/{{version}}/contributions)
5 | - 环境配置
6 | - [安装](/docs/{{version}}/installation)
7 | - [Homestead](/docs/{{version}}/homestead)
8 | - 基本功能
9 | - [路由](/docs/{{version}}/routing)
10 | - [中间件](/docs/{{version}}/middleware)
11 | - [控制器](/docs/{{version}}/controllers)
12 | - [请求](/docs/{{version}}/requests)
13 | - [响应](/docs/{{version}}/responses)
14 | - [视图](/docs/{{version}}/views)
15 | - [Blade 模板引擎](/docs/{{version}}/blade)
16 | - 系统架构
17 | - [请求的生命周期](/docs/{{version}}/lifecycle)
18 | - [应用程序结构](/docs/{{version}}/structure)
19 | - [服务提供者](/docs/{{version}}/providers)
20 | - [服务容器](/docs/{{version}}/container)
21 | - [Contracts](/docs/{{version}}/contracts)
22 | - [Facades](/docs/{{version}}/facades)
23 | - 系统服务
24 | - [登录认证](/docs/{{version}}/authentication)
25 | - [Artisan 命令行](/docs/{{version}}/artisan)
26 | - [交易](/docs/{{version}}/billing)
27 | - [缓存](/docs/{{version}}/cache)
28 | - [集合](/docs/{{version}}/collections)
29 | - [Elixir](/docs/{{version}}/elixir)
30 | - [加密](/docs/{{version}}/encryption)
31 | - [错误与日志](/docs/{{version}}/errors)
32 | - [事件](/docs/{{version}}/events)
33 | - [文件系统与云存储](/docs/{{version}}/filesystem)
34 | - [哈希](/docs/{{version}}/hashing)
35 | - [辅助方法](/docs/{{version}}/helpers)
36 | - [本地化](/docs/{{version}}/localization)
37 | - [邮件](/docs/{{version}}/mail)
38 | - [扩展包开发](/docs/{{version}}/packages)
39 | - [分页](/docs/{{version}}/pagination)
40 | - [队列](/docs/{{version}}/queues)
41 | - [Redis](/docs/{{version}}/redis)
42 | - [会话](/docs/{{version}}/session)
43 | - [SSH 任务执行器 (Envoy)](/docs/{{version}}/envoy)
44 | - [计划任务](/docs/{{version}}/scheduling)
45 | - [测试](/docs/{{version}}/testing)
46 | - [表单验证](/docs/{{version}}/validation)
47 | - 数据库
48 | - [基本用法](/docs/{{version}}/database)
49 | - [查询构造器](/docs/{{version}}/queries)
50 | - [表结构迁移](/docs/{{version}}/migrations)
51 | - [数据填充](/docs/{{version}}/seeding)
52 | - Eloquent ORM
53 | - [Eloquent 基础](/docs/{{version}}/eloquent)
54 | - [对象关联](/docs/{{version}}/eloquent-relationships)
55 | - [Eloquent 集合](/docs/{{version}}/eloquent-collections)
56 | - [获取器和修改器](/docs/{{version}}/eloquent-mutators)
57 | - [序列化](/docs/{{version}}/eloquent-serialization)
58 |
--------------------------------------------------------------------------------
/eloquent-collections.md:
--------------------------------------------------------------------------------
1 | # Eloquent: Collections
2 |
3 | - [Introduction](#introduction)
4 | - [Available Methods](#available-methods)
5 | - [Custom Collections](#custom-collections)
6 |
7 |
8 | ## Introduction
9 |
10 | All multi-result sets returned by Eloquent are an instance of the `Illuminate\Database\Eloquent\Collection` object, including results retrieved via the `get` method or accessed via a relationship. The Eloquent collection object extends the Laravel [base collection](/docs/{{version}}/collections), so it naturally inherits dozens of methods used to fluently work with the underlying array of Eloquent models.
11 |
12 | Of course, all collections also serve as iterators, allowing you to loop over them as if they were simple PHP arrays:
13 |
14 | $users = App\User::where('active', 1)->get();
15 |
16 | foreach ($users as $user) {
17 | echo $user->name;
18 | }
19 |
20 | However, collections are much more powerful than arrays and expose a variety of map / reduce operations using an intuitive interface. For example, let's remove all inactive models and gather the first name for each remaining user:
21 |
22 | $users = App\User::where('active', 1)->get();
23 |
24 | $names = $users->reject(function ($user) {
25 | return $user->active === false;
26 | })
27 | ->map(function ($user) {
28 | return $user->name;
29 | });
30 |
31 |
32 | ## Available Methods
33 |
34 | ### The Base Collection
35 |
36 | All Eloquent collections extend the base [Laravel collection](/docs/{{version}}/collections) object; therefore, they inherit all of the powerful methods provided by the base collection class:
37 |
38 |
48 |
49 |
50 | [all](/docs/{{version}}/collections#method-all)
51 | [chunk](/docs/{{version}}/collections#method-chunk)
52 | [collapse](/docs/{{version}}/collections#method-collapse)
53 | [contains](/docs/{{version}}/collections#method-contains)
54 | [count](/docs/{{version}}/collections#method-count)
55 | [diff](/docs/{{version}}/collections#method-diff)
56 | [each](/docs/{{version}}/collections#method-each)
57 | [filter](/docs/{{version}}/collections#method-filter)
58 | [first](/docs/{{version}}/collections#method-first)
59 | [flatten](/docs/{{version}}/collections#method-flatten)
60 | [flip](/docs/{{version}}/collections#method-flip)
61 | [forget](/docs/{{version}}/collections#method-forget)
62 | [forPage](/docs/{{version}}/collections#method-forpage)
63 | [get](/docs/{{version}}/collections#method-get)
64 | [groupBy](/docs/{{version}}/collections#method-groupby)
65 | [has](/docs/{{version}}/collections#method-has)
66 | [implode](/docs/{{version}}/collections#method-implode)
67 | [intersect](/docs/{{version}}/collections#method-intersect)
68 | [isEmpty](/docs/{{version}}/collections#method-isempty)
69 | [keyBy](/docs/{{version}}/collections#method-keyby)
70 | [keys](/docs/{{version}}/collections#method-keys)
71 | [last](/docs/{{version}}/collections#method-last)
72 | [map](/docs/{{version}}/collections#method-map)
73 | [merge](/docs/{{version}}/collections#method-merge)
74 | [pluck](/docs/{{version}}/collections#method-pluck)
75 | [pop](/docs/{{version}}/collections#method-pop)
76 | [prepend](/docs/{{version}}/collections#method-prepend)
77 | [pull](/docs/{{version}}/collections#method-pull)
78 | [push](/docs/{{version}}/collections#method-push)
79 | [put](/docs/{{version}}/collections#method-put)
80 | [random](/docs/{{version}}/collections#method-random)
81 | [reduce](/docs/{{version}}/collections#method-reduce)
82 | [reject](/docs/{{version}}/collections#method-reject)
83 | [reverse](/docs/{{version}}/collections#method-reverse)
84 | [search](/docs/{{version}}/collections#method-search)
85 | [shift](/docs/{{version}}/collections#method-shift)
86 | [shuffle](/docs/{{version}}/collections#method-shuffle)
87 | [slice](/docs/{{version}}/collections#method-slice)
88 | [sort](/docs/{{version}}/collections#method-sort)
89 | [sortBy](/docs/{{version}}/collections#method-sortby)
90 | [sortByDesc](/docs/{{version}}/collections#method-sortbydesc)
91 | [splice](/docs/{{version}}/collections#method-splice)
92 | [sum](/docs/{{version}}/collections#method-sum)
93 | [take](/docs/{{version}}/collections#method-take)
94 | [toArray](/docs/{{version}}/collections#method-toarray)
95 | [toJson](/docs/{{version}}/collections#method-tojson)
96 | [transform](/docs/{{version}}/collections#method-transform)
97 | [unique](/docs/{{version}}/collections#method-unique)
98 | [values](/docs/{{version}}/collections#method-values)
99 | [where](/docs/{{version}}/collections#method-where)
100 | [whereLoose](/docs/{{version}}/collections#method-whereloose)
101 | [zip](/docs/{{version}}/collections#method-zip)
102 |
103 |
104 |
105 | ## Custom Collections
106 |
107 | If you need to use a custom `Collection` object with your own extension methods, you may override the `newCollection` method on your model:
108 |
109 |
9 | ## Introduction
10 |
11 | Accessors and mutators allow you to format Eloquent attributes when retrieving them from a model or setting their value. For example, you may want to use the [Laravel encrypter](/docs/{{version}}/encryption) to encrypt a value while it is stored in the database, and then automatically decrypt the attribute when you access it on an Eloquent model.
12 |
13 | In addition to custom accessors and mutators, Eloquent can also automatically cast date fields to [Carbon](https://github.com/briannesbitt/Carbon) instances or even [cast text fields to JSON](#attribute-casting).
14 |
15 |
16 | ## Accessors & Mutators
17 |
18 | #### Defining An Accessor
19 |
20 | To define an accessor, create a `getFooAttribute` method on your model where `Foo` is the "camel" cased name of the column you wish to access. In this example, we'll defined an accessor for the `first_name` attribute. The accessor will automatically be called by Eloquent when attempting to retrieve the value of `first_name`:
21 |
22 | first_name;
47 |
48 | #### Defining A Mutator
49 |
50 | To define a mutator, define a `setFooAttribute` method on your model where `Foo` is the "camel" cased name of the column you wish to access. So, again, let's define a mutator for the `first_name` attribute. This mutator will be automatically called when we attempt to set the value of the `first_name` attribute on the model:
51 |
52 | attributes['first_name'] = strtolower($value);
69 | }
70 | }
71 |
72 | The mutator will receive the value that is being set on the attribute, allowing you to manipulate the value and set the manipulated value on the Eloquent model's internal `$attributes` property. So, for example, if we attempt to set the `first_name` attribute to `Sally`:
73 |
74 | $user = App\User::find(1);
75 |
76 | $user->first_name = 'Sally';
77 |
78 | In this example, the `setFirstNameAttribute` function will be called with the value `Sally`. The mutator will then apply the `strtolower` function to the name and set its value in the internal `$attributes` array.
79 |
80 |
81 | ## Date Mutators
82 |
83 | By default, Eloquent will convert the `created_at` and `updated_at` columns to instances of [Carbon](https://github.com/briannesbitt/Carbon), which provides an assortment of helpful methods, and extends the native PHP `DateTime` class.
84 |
85 | You may customize which fields are automatically mutated, and even completely disable this mutation, by overriding the `$dates` property of your model:
86 |
87 | disabled_at = Carbon::now();
108 |
109 | $user->save();
110 |
111 | As noted above, when retrieving attributes that are listed in your `$dates` property, they will automatically be cast to [Carbon](https://github.com/briannesbitt/Carbon) instances, allowing you to use any of Carbon's methods on your attributes:
112 |
113 | $user = App\User::find(1);
114 |
115 | return $user->disabled_at->getTimestamp();
116 |
117 | If you need to customize the format of your timestamps, set the `$dateFormat` property on your model. This property determines how date attributes are stored in the database, as well as their format when the model is serialized to an array or JSON:
118 |
119 |
136 | ## Attribute Casting
137 |
138 | The `$casts` property on your model provides a convenient method of converting attributes to common data types. The `$casts` property should be an array where the key is the name of the attribute being cast, while the value is the type you wish to cast to the column to. The supported cast types are: `integer`, `real`, `float`, `double`, `string`, `boolean`, `object` and `array`.
139 |
140 | For example, let's cast the `is_admin` attribute, which is stored in our database as an integer (`0` or `1`) to a boolean value:
141 |
142 | 'boolean',
157 | ];
158 | }
159 |
160 | Now the `is_admin` attribute will always be cast to a boolean when you access it, even if the underlying value is stored in the database as an integer:
161 |
162 | $user = App\User::find(1);
163 |
164 | if ($user->is_admin) {
165 | //
166 | }
167 |
168 | #### Array Casting
169 |
170 | The `array` cast type is particularly useful when working with columns that are stored as serialized JSON. For example, if your database has a `TEXT` field type that contains serialized JSON, adding the `array` cast to that attribute will automatically deserialize the attribute to a PHP array when you access it on your Eloquent model:
171 |
172 | 'array',
187 | ];
188 | }
189 |
190 | Once the cast is defined, you may access the `options` attribute and it will automatically be deserialized from JSON into a PHP array. When you set the value of the `options` attribute, the given array will automatically be serialized back into JSON for storage:
191 |
192 | $user = App\User::find(1);
193 |
194 | $options = $user->options;
195 |
196 | $options['key'] = 'value';
197 |
198 | $user->options = $options;
199 |
200 | $user->save();
201 |
--------------------------------------------------------------------------------
/eloquent-serialization.md:
--------------------------------------------------------------------------------
1 | # Eloquent: Serialization
2 |
3 | - [Introduction](#introduction)
4 | - [Basic Usage](#basic-usage)
5 | - [Hiding Attributes From JSON](#hiding-attributes-from-json)
6 | - [Appending Values To JSON](#appending-values-to-json)
7 |
8 |
9 | ## Introduction
10 |
11 | When building JSON APIs, you will often need to convert your models and relationships to arrays or JSON. Eloquent includes convenient methods for making these conversions, as well as controlling which attributes are included in your serializations.
12 |
13 |
14 | ## Basic Usage
15 |
16 | #### Converting A Model To An Array
17 |
18 | To convert a model and its loaded [relationships](/docs/{{version}}/eloquent-relationships) to an array, you may use the `toArray` method. This method is recursive, so all attributes and all relations (including the relations of relations) will be converted to arrays:
19 |
20 | $user = App\User::with('roles')->first();
21 |
22 | return $user->toArray();
23 |
24 | You may also convert [collections](/docs/{{version}}/eloquent-collections) to arrays:
25 |
26 | $users = App\User::all();
27 |
28 | return $users->toArray();
29 |
30 | #### Converting A Model To JSON
31 |
32 | To convert a model to JSON, you may use the `toJson` method. Like `toArray`, the `toJson` method is recursive, so all attributes and relations will be converted to JSON:
33 |
34 | $user = App\User::find(1);
35 |
36 | return $user->toJson();
37 |
38 | Alternatively, you may cast a model or collection to a string, which will automatically call the `toJson` method:
39 |
40 | $user = App\User::find(1);
41 |
42 | return (string) $user;
43 |
44 | Since models and collections are converted to JSON when cast to a string, you can return Eloquent objects directly from your application's routes or controllers:
45 |
46 | Route::get('users', function () {
47 | return App\User::all();
48 | });
49 |
50 |
51 | ## Hiding Attributes From JSON
52 |
53 | Sometimes you may wish to limit the attributes, such as passwords, that are included in your model's array or JSON representation. To do so, add a `$hidden` property definition to your model:
54 |
55 | **Note:** When hiding relationships, use the relationship's **method** name, not its dynamic property name.
72 |
73 | Alternatively, you may use the `visible` property to define a white-list of attributes that should be included in your model's array and JSON representation:
74 |
75 |
92 | ## Appending Values To JSON
93 |
94 | Occasionally, you may need to add array attributes that do not have a corresponding column in your database. To do so, first define an [accessor](/docs/{{version}}/eloquent-mutators) for the value:
95 |
96 | attributes['admin'] == 'yes';
112 | }
113 | }
114 |
115 | Once you have created the accessor, add the attribute name to the `appends` property on the model:
116 |
117 |
7 | ## Configuration
8 |
9 | Before using Laravel's encrypter, you should set the `key` option of your `config/app.php` configuration file to a 32 character, random string. If this value is not properly set, all values encrypted by Laravel will be insecure.
10 |
11 |
12 | ## Basic Usage
13 |
14 | #### Encrypting A Value
15 |
16 | You may encrypt a value using the `Crypt` [facade](/docs/{{version}}/facades). All encrypted values are encrypted using OpenSSL and the `AES-256-CBC` cipher. Furthermore, all encrypted values are signed with a message authentication code (MAC) to detect any modifications to the encrypted string.
17 |
18 | For example, we may use the `encrypt` method to encrypt a secret and store it on an [Eloquent model](/docs/{{version}}/eloquent):
19 |
20 | fill([
43 | 'secret' => Crypt::encrypt($request->secret)
44 | ])->save();
45 | }
46 | }
47 |
48 | #### Decrypting A Value
49 |
50 | Of course, you may decrypt values using the `decrypt` method on the `Crypt` facade. If the value can not be properly decrypted, such as when the MAC is invalid, an `Illuminate\Contracts\Encryption\DecryptException` will be thrown:
51 |
52 | use Illuminate\Contracts\Encryption\DecryptException;
53 |
54 | try {
55 | $decrypted = Crypt::decrypt($encryptedValue);
56 | } catch (DecryptException $e) {
57 | //
58 | }
59 |
--------------------------------------------------------------------------------
/envoy.md:
--------------------------------------------------------------------------------
1 | # Envoy Task Runner
2 |
3 | - [Introduction](#introduction)
4 | - [Writing Tasks](#writing-tasks)
5 | - [Task Variables](#task-variables)
6 | - [Multiple Servers](#envoy-multiple-servers)
7 | - [Task Macros](#envoy-task-macros)
8 | - [Running Tasks](#envoy-running-tasks)
9 | - [Notifications](#envoy-notifications)
10 | - [HipChat](#hipchat)
11 | - [Slack](#slack)
12 |
13 |
14 | ## Introduction
15 |
16 | [Laravel Envoy](https://github.com/laravel/envoy) provides a clean, minimal syntax for defining common tasks you run on your remote servers. Using a Blade style syntax, you can easily setup tasks for deployment, Artisan commands, and more. Currently, Envoy only supports the Mac and Linux operating systems.
17 |
18 |
19 | ### Installation
20 |
21 | First, install Envoy using the Composer `global` command:
22 |
23 | composer global require "laravel/envoy=~1.0"
24 |
25 | Make sure to place the `~/.composer/vendor/bin` directory in your PATH so the `envoy` executable is found when you run the `envoy` command in your terminal.
26 |
27 | #### Updating Envoy
28 |
29 | You may also use Composer to keep your Envoy installation up to date:
30 |
31 | composer global update
32 |
33 |
34 | ## Writing Tasks
35 |
36 | All of your Envoy tasks should be defined in an `Envoy.blade.php` file in the root of your project. Here's an example to get you started:
37 |
38 | @servers(['web' => 'user@192.168.1.1'])
39 |
40 | @task('foo', ['on' => 'web'])
41 | ls -la
42 | @endtask
43 |
44 | As you can see, an array of `@servers` is defined at the top of the file, allowing you to reference these servers in the `on` option of your task declarations. Within your `@task` declarations, you should place the Bash code that will be run on your server when the task is executed.
45 |
46 | #### Bootstrapping
47 |
48 | Sometimes, you may need to execute some PHP code before evaluating your Envoy tasks. You may use the ```@setup``` directive to declare variables and do general PHP work inside the Envoy file:
49 |
50 | @setup
51 | $now = new DateTime();
52 |
53 | $environment = isset($env) ? $env : "testing";
54 | @endsetup
55 |
56 | You may also use ```@include``` to include any outside PHP files:
57 |
58 | @include('vendor/autoload.php');
59 |
60 | #### Confirming Tasks
61 |
62 | If you would like to be prompted for confirmation before running a given task on your servers, you may add the `confirm` directive to your task declaration:
63 |
64 | @task('deploy', ['on' => 'web', 'confirm' => true])
65 | cd site
66 | git pull origin {{ $branch }}
67 | php artisan migrate
68 | @endtask
69 |
70 |
71 | ### Task Variables
72 |
73 | If needed, you may pass variables into the Envoy file using command line switches, allowing you to customize your tasks:
74 |
75 | envoy run deploy --branch=master
76 |
77 | You may use the options in your tasks via Blade's "echo" syntax:
78 |
79 | @servers(['web' => '192.168.1.1'])
80 |
81 | @task('deploy', ['on' => 'web'])
82 | cd site
83 | git pull origin {{ $branch }}
84 | php artisan migrate
85 | @endtask
86 |
87 |
88 | ### Multiple Servers
89 |
90 | You may easily run a task across multiple servers. First, add additional servers to your `@servers` declaration. Each server should be assigned a unique name. Once you have defined your additional servers, simply list the servers in the task declaration's `on` array:
91 |
92 | @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])
93 |
94 | @task('deploy', ['on' => ['web-1', 'web-2']])
95 | cd site
96 | git pull origin {{ $branch }}
97 | php artisan migrate
98 | @endtask
99 |
100 | By default, the task will be executed on each server serially. Meaning, the task will finish running on the first server before proceeding to execute on the next server.
101 |
102 | #### Parallel Execution
103 |
104 | If you would like to run a task across multiple servers in parallel, add the `parallel` option to your task declaration:
105 |
106 | @servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])
107 |
108 | @task('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true])
109 | cd site
110 | git pull origin {{ $branch }}
111 | php artisan migrate
112 | @endtask
113 |
114 |
115 | ### Task Macros
116 |
117 | Macros allow you to define a set of tasks to be run in sequence using a single command. For instance, a `deploy` macro may run the `git` and `composer` tasks:
118 |
119 | @servers(['web' => '192.168.1.1'])
120 |
121 | @macro('deploy')
122 | git
123 | composer
124 | @endmacro
125 |
126 | @task('git')
127 | git pull origin master
128 | @endtask
129 |
130 | @task('composer')
131 | composer install
132 | @endtask
133 |
134 | Once the macro has been defined, you may run it via single, simple command:
135 |
136 | envoy run deploy
137 |
138 |
139 | ## Running Tasks
140 |
141 | To run a task from your `Envoy.blade.php` file, execute Envoy's `run` command, passing the command the name of the task or macro you would like to execute. Envoy will run the task and display the output from the servers as the task is running:
142 |
143 | envoy run task
144 |
145 |
146 |
147 | ## Notifications
148 |
149 |
150 | ### HipChat
151 |
152 | After running a task, you may send a notification to your team's HipChat room using Envoy's `@hipchat` directive. The directive accepts an API token, the name of the room, and the username to be displayed as the sender of the message:
153 |
154 | @servers(['web' => '192.168.1.1'])
155 |
156 | @task('foo', ['on' => 'web'])
157 | ls -la
158 | @endtask
159 |
160 | @after
161 | @hipchat('token', 'room', 'Envoy')
162 | @endafter
163 |
164 | If you wish, you may also pass a custom message to send to the HipChat room. Any variables available to your Envoy tasks will also be available when constructing the message:
165 |
166 | @after
167 | @hipchat('token', 'room', 'Envoy', "{$task} ran in the {$env} environment.")
168 | @endafter
169 |
170 |
171 | ### Slack
172 |
173 | In addition to HipChat, Envoy also supports sending notifications to [Slack](https://slack.com). The `@slack` directive accepts a Slack hook URL, a channel name, and the message you wish to send to the channel:
174 |
175 | @after
176 | @slack('hook', 'channel', 'message')
177 | @endafter
178 |
179 | You may retrieve your webhook URL by creating an `Incoming WebHooks` integration on Slack's website. The `hook` argument should be the entire webhook URL provided by the Incoming Webhooks Slack Integration. For example:
180 |
181 | https://hooks.slack.com/services/ZZZZZZZZZ/YYYYYYYYY/XXXXXXXXXXXXXXX
182 |
183 | You may provide one of the following as the channel argument:
184 |
185 | - To send the notification to a channel: `#channel`
186 | - To send the notification to a user: `@user`
187 |
188 |
--------------------------------------------------------------------------------
/errors.md:
--------------------------------------------------------------------------------
1 | # Errors & Logging
2 |
3 | - [Introduction](#introduction)
4 | - [Configuration](#configuration)
5 | - [The Exception Handler](#the-exception-handler)
6 | - [Report Method](#report-method)
7 | - [Render Method](#render-method)
8 | - [HTTP Exceptions](#http-exceptions)
9 | - [Custom HTTP Error Pages](#custom-http-error-pages)
10 | - [Logging](#logging)
11 |
12 |
13 | ## Introduction
14 |
15 | When you start a new Laravel project, error and exception handling is already configured for you. In addition, Laravel is integrated with the [Monolog](https://github.com/Seldaek/monolog) logging library, which provides support for a variety of powerful log handlers.
16 |
17 |
18 | ## Configuration
19 |
20 | #### Error Detail
21 |
22 | The amount of error detail your application displays through the browser is controlled by the `debug` configuration option in your `config/app.php` configuration file. By default, this configuration option is set to respect the `APP_DEBUG` environment variable, which is stored in your `.env` file.
23 |
24 | For local development, you should set the `APP_DEBUG` environment variable to `true`. In your production environment, this value should always be `false`.
25 |
26 | #### Log Modes
27 |
28 | Out of the box, Laravel supports `single`, `daily`, `syslog` and `errorlog` logging modes. For example, if you wish to use daily log files instead of a single file, you should simply set the `log` value in your `config/app.php` configuration file:
29 |
30 | 'log' => 'daily'
31 |
32 | #### Custom Monolog Configuration
33 |
34 | If you would like to have complete control over how Monolog is configured for your application, you may use the application's `configureMonologUsing` method. You should place a call to this method in your `bootstrap/app.php` file right before the `$app` variable is returned by the file:
35 |
36 | $app->configureMonologUsing(function($monolog) {
37 | $monolog->pushHandler(...);
38 | });
39 |
40 | return $app;
41 |
42 |
43 | ## The Exception Handler
44 |
45 | All exceptions are handled by the `App\Exceptions\Handler` class. This class contains two methods: `report` and `render`. We'll examine each of these methods in detail.
46 |
47 |
48 | ### The Report Method
49 |
50 | The `report` method is used to log exceptions or send them to an external service like [BugSnag](https://bugsnag.com). By default, the `report` method simply passes the exception to the base class where the exception is logged. However, you are free to log exceptions however you wish.
51 |
52 | For example, if you need to report different types of exceptions in different ways, you may use the PHP `instanceof` comparison operator:
53 |
54 | /**
55 | * Report or log an exception.
56 | *
57 | * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
58 | *
59 | * @param \Exception $e
60 | * @return void
61 | */
62 | public function report(Exception $e)
63 | {
64 | if ($e instanceof CustomException) {
65 | //
66 | }
67 |
68 | return parent::report($e);
69 | }
70 |
71 | #### Ignoring Exceptions By Type
72 |
73 | The `$dontReport` property of the exception handler contains an array of exception types that will not be logged. By default, exceptions resulting from 404 errors are not written to your log files. You may add other exception types to this array as needed.
74 |
75 |
76 | ### The Render Method
77 |
78 | The `render` method is responsible for converting a given exception into an HTTP response that should be sent back to the browser. By default, the exception is passed to the base class which generates a response for you. However, you are free to check the exception type or return your own custom response:
79 |
80 | /**
81 | * Render an exception into an HTTP response.
82 | *
83 | * @param \Illuminate\Http\Request $request
84 | * @param \Exception $e
85 | * @return \Illuminate\Http\Response
86 | */
87 | public function render($request, Exception $e)
88 | {
89 | if ($e instanceof CustomException) {
90 | return response()->view('errors.custom', [], 500);
91 | }
92 |
93 | return parent::render($request, $e);
94 | }
95 |
96 |
97 | ## HTTP Exceptions
98 |
99 | Some exceptions describe HTTP error codes from the server. For example, this may be a "page not found" error (404), an "unauthorized error" (401) or even a developer generated 500 error. In order to generate such a response from anywhere in your application, use the following:
100 |
101 | abort(404);
102 |
103 | The `abort` method will immediately raise an exception which will be rendered by the exception handler. Optionally, you may provide the response text:
104 |
105 | abort(403, 'Unauthorized action.');
106 |
107 | This method may be used at any time during the request's lifecycle.
108 |
109 |
110 | ### Custom HTTP Error Pages
111 |
112 | Laravel makes it easy to return custom error pages for various HTTP status codes. For example, if you wish to customize the error page for 404 HTTP status codes, create a `resources/views/errors/404.blade.php`. This file will be served on all 404 errors generated by your application.
113 |
114 | The views within this directory should be named to match the HTTP status code they correspond to.
115 |
116 |
117 | ## Logging
118 |
119 | The Laravel logging facilities provide a simple layer on top of the powerful [Monolog](http://github.com/seldaek/monolog) library. By default, Laravel is configured to create daily log files for your application which are stored in the `storage/logs` directory. You may write information to the logs using the `Log` [facade](/docs/{{version}}/facades):
120 |
121 | User::findOrFail($id)]);
142 | }
143 | }
144 |
145 | The logger provides the eight logging levels defined in [RFC 5424](http://tools.ietf.org/html/rfc5424): **emergency**, **alert**, **critical**, **error**, **warning**, **notice**, **info** and **debug**.
146 |
147 | Log::emergency($error);
148 | Log::alert($error);
149 | Log::critical($error);
150 | Log::error($error);
151 | Log::warning($error);
152 | Log::notice($error);
153 | Log::info($error);
154 | Log::debug($error);
155 |
156 | #### Contextual Information
157 |
158 | An array of contextual data may also be passed to the log methods. This contextual data will be formatted and displayed with the log message:
159 |
160 | Log::info('User failed to login.', ['id' => $user->id]);
161 |
162 | #### Accessing The Underlying Monolog Instance
163 |
164 | Monolog has a variety of additional handlers you may use for logging. If needed, you may access the underlying Monolog instance being used by Laravel:
165 |
166 | $monolog = Log::getMonolog();
167 |
--------------------------------------------------------------------------------
/facades.md:
--------------------------------------------------------------------------------
1 | # Facades
2 |
3 | - [Introduction](#introduction)
4 | - [Using Facades](#using-facades)
5 | - [Facade Class Reference](#facade-class-reference)
6 |
7 |
8 | ## Introduction
9 |
10 | Facades provide a "static" interface to classes that are available in the application's [service container](/docs/{{version}}/container). Laravel ships with many facades, and you have probably been using them without even knowing it! Laravel "facades" serve as "static proxies" to underlying classes in the service container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.
11 |
12 |
13 | ## Using Facades
14 |
15 | In the context of a Laravel application, a facade is a class that provides access to an object from the container. The machinery that makes this work is in the `Facade` class. Laravel's facades, and any custom facades you create, will extend the base `Illuminate\Support\Facades\Facade` class.
16 |
17 | A facade class only needs to implement a single method: `getFacadeAccessor`. It's the `getFacadeAccessor` method's job to define what to resolve from the container. The `Facade` base class makes use of the `__callStatic()` magic-method to defer calls from your facade to the resolved object.
18 |
19 | In the example below, a call is made to the Laravel cache system. By glancing at this code, one might assume that the static method `get` is being called on the `Cache` class:
20 |
21 | $user]);
41 | }
42 | }
43 |
44 | Notice that near the top of the file we are "importing" the `Cache` facade. This facade serves as a proxy to accessing the underlying implementation of the `Illuminate\Contracts\Cache\Factory` interface. Any calls we make using the facade will be passed to the underlying instance of Laravel's cache service.
45 |
46 | If we look at that `Illuminate\Support\Facades\Cache` class, you'll see that there is no static method `get`:
47 |
48 | class Cache extends Facade
49 | {
50 | /**
51 | * Get the registered name of the component.
52 | *
53 | * @return string
54 | */
55 | protected static function getFacadeAccessor() { return 'cache'; }
56 | }
57 |
58 | Instead, the `Cache` facade extends the base `Facade` class and defines the method `getFacadeAccessor()`. Remember, this method's job is to return the name of a service container binding. When a user references any static method on the `Cache` facade, Laravel resolves the `cache` binding from the [service container](/docs/{{version}}/container) and runs the requested method (in this case, `get`) against that object.
59 |
60 |
61 | ## Facade Class Reference
62 |
63 | Below you will find every facade and its underlying class. This is a useful tool for quickly digging into the API documentation for a given facade root. The [service container binding](/docs/{{version}}/container) key is also included where applicable.
64 |
65 | Facade | Class | Service Container Binding
66 | ------------- | ------------- | -------------
67 | App | [Illuminate\Foundation\Application](http://laravel.com/api/{{version}}/Illuminate/Foundation/Application.html) | `app`
68 | Artisan | [Illuminate\Console\Application](http://laravel.com/api/{{version}}/Illuminate/Console/Application.html) | `artisan`
69 | Auth | [Illuminate\Auth\AuthManager](http://laravel.com/api/{{version}}/Illuminate/Auth/AuthManager.html) | `auth`
70 | Auth (Instance) | [Illuminate\Auth\Guard](http://laravel.com/api/{{version}}/Illuminate/Auth/Guard.html) |
71 | Blade | [Illuminate\View\Compilers\BladeCompiler](http://laravel.com/api/{{version}}/Illuminate/View/Compilers/BladeCompiler.html) | `blade.compiler`
72 | Bus | [Illuminate\Contracts\Bus\Dispatcher](http://laravel.com/api/{{version}}/Illuminate/Contracts/Bus/Dispatcher.html) |
73 | Cache | [Illuminate\Cache\Repository](http://laravel.com/api/{{version}}/Illuminate/Cache/Repository.html) | `cache`
74 | Config | [Illuminate\Config\Repository](http://laravel.com/api/{{version}}/Illuminate/Config/Repository.html) | `config`
75 | Cookie | [Illuminate\Cookie\CookieJar](http://laravel.com/api/{{version}}/Illuminate/Cookie/CookieJar.html) | `cookie`
76 | Crypt | [Illuminate\Encryption\Encrypter](http://laravel.com/api/{{version}}/Illuminate/Encryption/Encrypter.html) | `encrypter`
77 | DB | [Illuminate\Database\DatabaseManager](http://laravel.com/api/{{version}}/Illuminate/Database/DatabaseManager.html) | `db`
78 | DB (Instance) | [Illuminate\Database\Connection](http://laravel.com/api/{{version}}/Illuminate/Database/Connection.html) |
79 | Event | [Illuminate\Events\Dispatcher](http://laravel.com/api/{{version}}/Illuminate/Events/Dispatcher.html) | `events`
80 | File | [Illuminate\Filesystem\Filesystem](http://laravel.com/api/{{version}}/Illuminate/Filesystem/Filesystem.html) | `files`
81 | Hash | [Illuminate\Contracts\Hashing\Hasher](http://laravel.com/api/{{version}}/Illuminate/Contracts/Hashing/Hasher.html) | `hash`
82 | Input | [Illuminate\Http\Request](http://laravel.com/api/{{version}}/Illuminate/Http/Request.html) | `request`
83 | Lang | [Illuminate\Translation\Translator](http://laravel.com/api/{{version}}/Illuminate/Translation/Translator.html) | `translator`
84 | Log | [Illuminate\Log\Writer](http://laravel.com/api/{{version}}/Illuminate/Log/Writer.html) | `log`
85 | Mail | [Illuminate\Mail\Mailer](http://laravel.com/api/{{version}}/Illuminate/Mail/Mailer.html) | `mailer`
86 | Password | [Illuminate\Auth\Passwords\PasswordBroker](http://laravel.com/api/{{version}}/Illuminate/Auth/Passwords/PasswordBroker.html) | `auth.password`
87 | Queue | [Illuminate\Queue\QueueManager](http://laravel.com/api/{{version}}/Illuminate/Queue/QueueManager.html) | `queue`
88 | Queue (Instance) | [Illuminate\Queue\QueueInterface](http://laravel.com/api/{{version}}/Illuminate/Queue/QueueInterface.html) |
89 | Queue (Base Class) | [Illuminate\Queue\Queue](http://laravel.com/api/{{version}}/Illuminate/Queue/Queue.html) |
90 | Redirect | [Illuminate\Routing\Redirector](http://laravel.com/api/{{version}}/Illuminate/Routing/Redirector.html) | `redirect`
91 | Redis | [Illuminate\Redis\Database](http://laravel.com/api/{{version}}/Illuminate/Redis/Database.html) | `redis`
92 | Request | [Illuminate\Http\Request](http://laravel.com/api/{{version}}/Illuminate/Http/Request.html) | `request`
93 | Response | [Illuminate\Contracts\Routing\ResponseFactory](http://laravel.com/api/{{version}}/Illuminate/Contracts/Routing/ResponseFactory.html) |
94 | Route | [Illuminate\Routing\Router](http://laravel.com/api/{{version}}/Illuminate/Routing/Router.html) | `router`
95 | Schema | [Illuminate\Database\Schema\Blueprint](http://laravel.com/api/{{version}}/Illuminate/Database/Schema/Blueprint.html) |
96 | Session | [Illuminate\Session\SessionManager](http://laravel.com/api/{{version}}/Illuminate/Session/SessionManager.html) | `session`
97 | Session (Instance) | [Illuminate\Session\Store](http://laravel.com/api/{{version}}/Illuminate/Session/Store.html) |
98 | Storage | [Illuminate\Contracts\Filesystem\Factory](http://laravel.com/api/{{version}}/Illuminate/Contracts/Filesystem/Factory.html) | `filesystem`
99 | URL | [Illuminate\Routing\UrlGenerator](http://laravel.com/api/{{version}}/Illuminate/Routing/UrlGenerator.html) | `url`
100 | Validator | [Illuminate\Validation\Factory](http://laravel.com/api/{{version}}/Illuminate/Validation/Factory.html) | `validator`
101 | Validator (Instance) | [Illuminate\Validation\Validator](http://laravel.com/api/{{version}}/Illuminate/Validation/Validator.html) |
102 | View | [Illuminate\View\Factory](http://laravel.com/api/{{version}}/Illuminate/View/Factory.html) | `view`
103 | View (Instance) | [Illuminate\View\View](http://laravel.com/api/{{version}}/Illuminate/View/View.html) |
104 |
--------------------------------------------------------------------------------
/filesystem.md:
--------------------------------------------------------------------------------
1 | # Filesystem / Cloud Storage
2 |
3 | - [Introduction](#introduction)
4 | - [Configuration](#configuration)
5 | - [Basic Usage](#basic-usage)
6 | - [Obtaining Disk Instances](#obtaining-disk-instances)
7 | - [Retrieving Files](#retrieving-files)
8 | - [Storing Files](#storing-files)
9 | - [Deleting Files](#deleting-files)
10 | - [Directories](#directories)
11 | - [Custom Filesystems](#custom-filesystems)
12 |
13 |
14 | ## Introduction
15 |
16 | Laravel provides a powerful filesystem abstraction thanks to the wonderful [Flysystem](https://github.com/thephpleague/flysystem) PHP package by Frank de Jonge. The Laravel Flysystem integration provides simple to use drivers for working with local filesystems, Amazon S3, and Rackspace Cloud Storage. Even better, it's amazingly simple to switch between these storage options as the API remains the same for each system.
17 |
18 |
19 | ## Configuration
20 |
21 | The filesystem configuration file is located at `config/filesystems.php`. Within this file you may configure all of your "disks". Each disk represents a particular storage driver and storage location. Example configurations for each supported driver is included in the configuration file. So, simply modify the configuration to reflect your storage preferences and credentials.
22 |
23 | Of course, you may configure as many disks as you like, and may even have multiple disks that use the same driver.
24 |
25 | #### The Local Driver
26 |
27 | When using the `local` driver, note that all file operations are relative to the `root` directory defined in your configuration file. By default, this value is set to the `storage/app` directory. Therefore, the following method would store a file in `storage/app/file.txt`:
28 |
29 | Storage::disk('local')->put('file.txt', 'Contents');
30 |
31 | #### Other Driver Prerequisites
32 |
33 | Before using the S3 or Rackspace drivers, you will need to install the appropriate package via Composer:
34 |
35 | - Amazon S3: `league/flysystem-aws-s3-v3 ~1.0`
36 | - Rackspace: `league/flysystem-rackspace ~1.0`
37 |
38 |
39 | ## Basic Usage
40 |
41 |
42 | ### Obtaining Disk Instances
43 |
44 | The `Storage` facade may be used to interact with any of your configured disks. For example, you may use the `put` method on the facade to store an avatar on the default disk. If you call methods on the `Storage` facade without first calling the `disk` method, the method call will automatically be passed to the default disk:
45 |
46 | id,
69 | file_get_contents($request->file('avatar')->getRealPath())
70 | );
71 | }
72 | }
73 |
74 | When using multiple disks, you may access a particular disk using the `disk` method on the `Storage` facade. Of course, you may continue to chain methods to execute methods on the disk:
75 |
76 | $disk = Storage::disk('s3');
77 |
78 | $contents = Storage::disk('local')->get('file.jpg')
79 |
80 |
81 | ### Retrieving Files
82 |
83 | The `get` method may be used to retrieve the contents of a given file. The raw string contents of the file will be returned by the method:
84 |
85 | $contents = Storage::get('file.jpg');
86 |
87 | The `exists` method may be used to determine if a given file exists on the disk:
88 |
89 | $exists = Storage::disk('s3')->exists('file.jpg');
90 |
91 | #### File Meta Information
92 |
93 | The `size` method may be used to get the size of the file in bytes:
94 |
95 | $size = Storage::size('file1.jpg');
96 |
97 | The `lastModified` method returns the UNIX timestamp of the last time the file was modified:
98 |
99 | $time = Storage::lastModified('file1.jpg');
100 |
101 |
102 | ### Storing Files
103 |
104 | The `put` method may be used to store a file on disk. You may also pass a PHP `resource` to the `put` method, which will use Flysystem's underlying stream support. Using streams is greatly recommended when dealing with large files:
105 |
106 | Storage::put('file.jpg', $contents);
107 |
108 | Storage::put('file.jpg', $resource);
109 |
110 | The `copy` method may be used to copy an existing file to a new location on the disk:
111 |
112 | Storage::copy('old/file1.jpg', 'new/file1.jpg');
113 |
114 | The `move` method may be used to move an existing file to a new location:
115 |
116 | Storage::move('old/file1.jpg', 'new/file1.jpg');
117 |
118 | #### Prepending / Appending To Files
119 |
120 | The `prepend` and `append` methods allow you to easily insert content at the beginning or end of a file:
121 |
122 | Storage::prepend('file.log', 'Prepended Text');
123 |
124 | Storage::append('file.log', 'Appended Text');
125 |
126 |
127 | ### Deleting Files
128 |
129 | The `delete` method accepts a single filename or an array of files to remove from the disk:
130 |
131 | Storage::delete('file.jpg');
132 |
133 | Storage::delete(['file1.jpg', 'file2.jpg']);
134 |
135 |
136 | ### Directories
137 |
138 | #### Get All Files Within A Directory
139 |
140 | The `files` method returns an array of all of the files in a given directory. If you would like to retrieve a list of all files within a given directory including all sub-directories, you may use the `allFiles` method:
141 |
142 | $files = Storage::files($directory);
143 |
144 | $files = Storage::allFiles($directory);
145 |
146 | #### Get All Directories Within A Directory
147 |
148 | The `directories` method returns an array of all the directories within a given directory. Additionally, you may use the `allDirectories` method to get a list of all directories within a given directory and all of its sub-directories:
149 |
150 | $directories = Storage::directories($directory);
151 |
152 | // Recursive...
153 | $directories = Storage::allDirectories($directory);
154 |
155 | #### Create A Directory
156 |
157 | The `makeDirectory` method will create the given directory, including any needed sub-directories:
158 |
159 | Storage::makeDirectory($directory);
160 |
161 | #### Delete A Directory
162 |
163 | Finally, the `deleteDirectory` may be used to remove a directory, including all of its files, from the disk:
164 |
165 | Storage::deleteDirectory($directory);
166 |
167 |
168 | ## Custom Filesystems
169 |
170 | Laravel's Flysystem integration provides drivers for several "drivers" out of the box; however, Flysystem is not limited to these and has adapters for many other storage systems. You can create a custom driver if you want to use one of these additional adapters in your Laravel application.
171 |
172 | In order to set up the custom filesystem you will need to create a [service provider](/docs/{{version}}/providers) such as `DropboxServiceProvider`. In the provider's `boot` method, you may use the `Storage` facade's `extend` method to define the custom driver:
173 |
174 |
7 | ## Introduction
8 |
9 | The Laravel `Hash` [facade](/docs/{{version}}/facades) provides secure Bcrypt hashing for storing user passwords. If you are using the `AuthController` controller that is included with your Laravel application, it will automatically use Bcrypt for registration and authentication.
10 |
11 | Bcrypt is a great choice for hashing passwords because its "work factor" is adjustable, which means that the time it takes to generate a hash can be increased as hardware power increases.
12 |
13 |
14 | ## Basic Usage
15 |
16 | You may hash a password by calling the `make` method on the `Hash` facade:
17 |
18 | fill([
43 | 'password' => Hash::make($request->newPassword)
44 | ])->save();
45 | }
46 | }
47 |
48 | Alternatively, you may also use the global `bcrypt` helper function:
49 |
50 | bcrypt('plain-text');
51 |
52 | #### Verifying A Password Against A Hash
53 |
54 | The `check` method allows you to verify that a given plain-text string corresponds to a given hash. However, if you are using the `AuthController` [included with Laravel](/docs/{{version}}/authentication), you will probably not need to use this directly, as the included authentication controller automatically calls this method:
55 |
56 | if (Hash::check('plain-text', $hashedPassword)) {
57 | // The passwords match...
58 | }
59 |
60 | #### Checking If A Password Needs To Be Rehashed
61 |
62 | The `needsRehash` function allows you to determine if the work factor used by the hasher has changed since the password was hashed:
63 |
64 | if (Hash::needsRehash($hashed)) {
65 | $hashed = Hash::make('plain-text');
66 | }
67 |
--------------------------------------------------------------------------------
/homestead.md:
--------------------------------------------------------------------------------
1 | # Laravel Homestead
2 |
3 | - [简介](#introduction)
4 | - [安装和配置](#installation-and-setup)
5 | - [第一步](#first-steps)
6 | - [配置 Homestead](#configuring-homestead)
7 | - [启动 Vagrant Box 虚拟机](#launching-the-vagrant-box)
8 | - [独立项目每台机器](#per-project-installation)
9 | - [日常使用](#daily-usage)
10 | - [通过 SSH 连接](#connecting-via-ssh)
11 | - [连接数据库](#connecting-to-databases)
12 | - [增加站点](#adding-additional-sites)
13 | - [端口](#ports)
14 | - [Blackfire Profiler](#blackfire-profiler)
15 |
16 |
17 | ## 简介
18 |
19 |
20 | Laravel 致力于让 PHP 开发体验更愉快,也包含你的本地开发环境。[Vagrant](http://vagrantup.com) 提供了一个简单、优雅的方式来管理与供应虚拟机。
21 |
22 | Laravel Homestead 是一个官方预载的 Vagrant「封装包」,提供你一个美好的开发环境,你不需要在你的本机端安装 PHP、HHVM、网页服务器或任何服务器软件。不用担心搞乱你的系统!Vagrant 封装包可以搞定一切。如果有什么地方出现故障,你可以在几分钟内快速的销毁并重建虚拟机。
23 |
24 | Homestead 可以在任何 Windows、Mac 或 Linux 上面运行,里面包含了 Nginx 网页服务器、PHP 5.6、MySQL、Postgres、Redis、Memcached 还有所有你要开发精彩的 Laravel 应用程序所需的软件。
25 |
26 | > **附注:** 如果您是 Windows 的用户,您可能需要启用硬件虚拟化(VT-x)。通常需要通过 BIOS 来启用它。
27 |
28 | Homestead 目前是构建且测试于 Vagrant 1.7 版本。
29 |
30 |
31 | ### Included Software
32 |
33 | - Ubuntu 14.04
34 | - PHP 5.6
35 | - HHVM
36 | - Nginx
37 | - MySQL
38 | - Postgres
39 | - Node (With PM2, Bower, Grunt, and Gulp)
40 | - Redis
41 | - Memcached
42 | - Beanstalkd
43 | - [Laravel Envoy](/docs/{{version}}/envoy)
44 | - [Blackfire Profiler](#blackfire-profiler)
45 |
46 |
47 | ## 安装与配置
48 |
49 |
50 | ### 第一步
51 |
52 | 在启动你的 Homestead 环境之前,你必须先安装 [VirtualBox](https://www.virtualbox.org/wiki/Downloads) 和 [Vagrant](http://www.vagrantup.com/downloads.html). 两套软件在各平台都有提供易用的可视化安装程序。
53 |
54 | 如果使用 VMware 作为 provider, 你需要购买 VMware Fusion / Desktop 以及 [VMware Vagrant plug-in](http://www.vagrantup.com/vmware). VMware 提供了更快、性能更好的共享文件夹。
55 |
56 | #### 安装 Homestead Vagrant Box
57 |
58 | 当 VirtualBox / VMware 和 Vagrant 安装完成后,你可以在终端机以下列命令将 'laravel/homestead' 封装包安装进你的 Vagrant 安装程序中。下载封装包会花你一点时间,时间长短将依据你的网络速度决定:
59 |
60 | vagrant box add laravel/homestead
61 |
62 | 如果这个命令失败了, 你可能安装的是一个老版本的 Vagrant 需要指定一个完整的 URL:
63 |
64 | vagrant box add laravel/homestead https://atlas.hashicorp.com/laravel/boxes/homestead
65 |
66 | #### 克隆 Homestead 代码库
67 |
68 | 你可以简单地通过手动复制资源库的方式来安装 Homestead。将资源库复制至你的 "home" 目录中的 `Homestead` 文件夹,如此一来 Homestead 封装包将能提供主机服务给你所有的 Laravel(及 PHP)应用:
69 |
70 | git clone https://github.com/laravel/homestead.git Homestead
71 |
72 | 一旦你克隆完 Homestead 仓库,从 Homestead 目录中执行 `bash init.sh` 命令来创建 `Homestead.yaml` 配置文件:
73 |
74 | bash init.sh
75 |
76 | 此 `Homestead.yaml` 文件,将会被放置在你的 `~/.homestead` 目录中。
77 |
78 |
79 | ### 配置 Homestead
80 |
81 | #### 配置你的 Provider
82 |
83 |
84 | 在 `Homestead.yaml` 文件中的 `provider` 键表明需要使用的 Vagrant prodiver:`virtualbox` 、 `vmware_fusion` (Mac OS X)、或者 `vmware_workstation` (Windows),你可以根据自己的喜好设定 provider 。
85 |
86 | provider: virtualbox
87 |
88 | #### 配置你的 SSH 密钥
89 |
90 | 然后你需要编辑 `Homestead.yaml`。可以在文件中配置你的 SSH 公开密钥,以及主要机器与 Homestead 虚拟机之间的共享目录。
91 |
92 | 如果没有 SSH 密钥的话, 在 Mac 和 Linux 下,你可以利用下面的命令来创建一个 SSH 密钥组:
93 |
94 | ssh-keygen -t rsa -C "you@homestead"
95 |
96 | 在 Windows 下,你需要安装 [Git](http://git-scm.com/) 并且使用包含在 Git 里的 `Git Bash` 来执行上述的命令。另外你也可以使用 [PuTTY](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) 和 [PuTTYgen](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html)。
97 |
98 | 一旦你创建了一个 SSH 密钥,记得在你的 `Homestead.yaml` 文件中的 `authorize` 属性指明密钥路径。
99 |
100 | #### 配置你的共享文件夹
101 |
102 | `Homestead.yaml` 文件中的 `folders` 属性列出了所有你想在 Homestead 环境共享的文件夹列表。这些文件夹中的文件若有变动,他们将会同步在你的本机与 Homestead 环境里。你可以将你需要的共享文件夹都配置进去。
103 |
104 | folders:
105 | - map: ~/Code
106 | to: /home/vagrant/Code
107 |
108 | 如果要开启 [NFS](http://docs.vagrantup.com/v2/synced-folders/nfs.html),只需要在 `folders` 中加入一个标识:
109 |
110 | folders:
111 | - map: ~/Code
112 | to: /home/vagrant/Code
113 | type: "nfs"
114 |
115 | #### 配置你的 Nginx 站点
116 |
117 | 对 Nginx 不熟悉?没关系。`sites` 属性允许你简单的对应一个 `域名` 到一个 homestead 环境中的目录。一个例子的站点被配置在 `Homestead.yaml` 文件中。同样的,你可以加任何你需要的站点到你的 Homestead 环境中。Homestead 可以为你每个进行中的 Laravel 应用提供方便的虚拟化环境。
118 |
119 | sites:
120 | - map: homestead.app
121 | to: /home/vagrant/Code/Laravel/public
122 |
123 | 你可以通过配置 `hhvm` 属性为 `true` 来让虚拟站点支持 [HHVM](http://hhvm.com):
124 |
125 | sites:
126 | - map: homestead.app
127 | to: /home/vagrant/Code/Laravel/public
128 | hhvm: true
129 |
130 | 默认情况下, 每个站点在主机里面可以通过 HTTP 8000 和 HTTPS 44300.
131 |
132 | #### The Hosts File
133 |
134 | 为了主机可以访问到你的 Nginx 站点,别忘记在你的机器的 `hosts` 文件将「域名」加进去。`hosts` 文件会将你的本地域名的站点请求指向你的 Homestead 环境中。在 Mac 和 Linux,该文件放在 `/etc/hosts`。在 Windows 环境中,它被放置在 `C:\Windows\System32\drivers\etc\hosts`。你要加进去的内容类似如下:
135 |
136 | 192.168.10.10 homestead.app
137 |
138 | 务必确认 IP 地址与你的 `Homestead.yaml` 文件中的相同。一旦你将域名加进你的 `hosts` 文件中,你就可以通过网页浏览器访问到你的站点。
139 |
140 | http://homestead.app
141 |
142 |
143 | ### 运行虚拟机 Vagrant Box
144 |
145 | 当你根据你的喜好编辑完 `Homestead.yaml` 后,在终端机里进入你的 Homestead 文件夹并执行 `vagrant up` 命令。
146 |
147 | Vagrant 会将虚拟机开机,并且自动配置你的共享目录和 Nginx 站点。如果要移除虚拟机,可以使用 `vagrant destroy --force` 命令。
148 |
149 |
150 | ### 独立项目每台机器
151 |
152 | 默认的 Homestead 安装是全局的, 如果你针对单独的项目, 创建独占的虚拟机, 可以使用以下方法.
153 |
154 | 允许项目参与人员直接使用 `vagrant up`, 生成 `Vagrantfile` 目录在你的项目中, 并完成环境的配置.
155 |
156 | 使用下面的命令可以安装 Homestead 到你的项目中:
157 |
158 | composer require laravel/homestead --dev
159 |
160 | 一旦 Homestead 安装成功, 你可以使用 `make` 命令在根目录下生成 `Vagrantfile` 和 `Homestead.yaml` 文件. `make` 命令会自动配置 `sites` 和 `folders` 目录在 `Homestead.yaml` 文件中.
161 |
162 | Mac / Linux:
163 |
164 | php vendor/bin/homestead make
165 |
166 | Windows:
167 |
168 | vendor\bin\homestead make
169 |
170 | 接下里, 在命令行下允许 `vagrant up` 命令, 并浏览器访问 `http://homestead.app`. 需要注意的是, 你需要将 `homestead.app` 在 `hosts` 文件里面配置好.
171 |
172 |
173 | ## 日常使用
174 |
175 |
176 | ### 通过 SSH 连接
177 |
178 | 要通过 SSH 连接上您的 Homestead 环境,在终端机里进入你的 Homestead 目录并执行 `vagrant ssh` 命令。
179 |
180 | 因为你可能会经常需要通过 SSH 进入你的 Homestead 虚拟机,可以考虑在你的主要机器上创建一个"别名" 用来快速 SSH 进入 Homestead 虚拟机:
181 |
182 | alias vm="ssh vagrant@127.0.0.1 -p 2222"
183 |
184 |
185 | ### 连接数据库
186 |
187 | 在 `Homestead` 封装包中,已经预了 MySQL 与 Postgres 两种数据库。为了更简便,Laravel 的 `local` 数据库配置已经默认将其配置完成。
188 |
189 | 如果想要从本机上通过 Navicat 或者 Sequel Pro 连接 MySQL 或者 Postgres 数据库,你可以连接 `127.0.0.1` 的端口 33060 (MySQL) 或 54320 (Postgres)。而帐号密码分别是 `homestead` / `secret`。
190 |
191 | > **附注:** 从本机端你应该只能使用这些非标准的连接端口来连接数据库。因为当 Laravel 运行在虚拟机时,在 Laravel 的数据库配置文件中依然是配置使用默认的 3306 及 5432 连接端口。
192 |
193 |
194 | ### 增加更多的站点
195 |
196 | 在 Homestead 环境上架且运行后,你可能会需要为 Laravel 应用程序增加更多的 Nginx 站点。你可以在单一个 Homestead 环境中运行非常多 Laravel 安装程序。有两种方式可以达成:第一种,在 `Homestead.yaml` 文件中增加站点然后在 Homestead 目录中执行 `vagrant provision`。
197 |
198 |
199 | ### Ports
200 |
201 | 以下的端口将会被转发至 Homestead 环境:
202 |
203 | - **SSH:** 2222 → Forwards To 22
204 | - **HTTP:** 8000 → Forwards To 80
205 | - **HTTPS:** 44300 → Forwards To 443
206 | - **MySQL:** 33060 → Forwards To 3306
207 | - **Postgres:** 54320 → Forwards To 5432
208 |
209 | #### 增加额外端口
210 |
211 | 你也可以自定义转发额外的端口至 Vagrant box,只需要指定协议:
212 |
213 | ports:
214 | - send: 93000
215 | to: 9300
216 | - send: 7777
217 | to: 777
218 | protocol: udp
219 |
220 |
221 | ## Blackfire Profiler
222 |
223 | [Blackfire Profiler](https://blackfire.io) 是由 SensioLabs 创建的一个分析工具,它会自动的收集代码执行期间的相关数据,比如 RAM, CPU time, 和 disk I/O. 如果你使用 Homestead ,那么使用这个分析工具会变得非常简单。
224 |
225 | blackfire 所需的包已经安装在 Homestead box 中,你只需要在 `Homestead.yaml` 文件中设置 **Server** ID 和 token :
226 |
227 | blackfire:
228 | - id: your-server-id
229 | token: your-server-token
230 | client-id: your-client-id
231 | client-token: your-client-token
232 |
233 |
234 | 当你设定完 Blackfire 的凭证信息,使用 `vagrant provision` 令配置生效。当然,你也需要通过阅读[Blackfire 文档](https://blackfire.io/getting-started) 来学习如何在你的浏览器中安装 Blackfire 扩展。
235 |
--------------------------------------------------------------------------------
/installation.md:
--------------------------------------------------------------------------------
1 | # 安装
2 |
3 | - [安装](#installation)
4 | - [配置](#configuration)
5 | - [基本配置](#basic-configuration)
6 | - [环境配置](#environment-configuration)
7 | - [配置缓存](#configuration-caching)
8 | - [获取配置项](#accessing-configuration-values)
9 | - [应用程序命名](#naming-your-application)
10 | - [维护模式](#maintenance-mode)
11 |
12 |
13 | ## 安装
14 |
15 | ### 服务器要求
16 |
17 | Laravel 框架对系统有一些要求. 当然, 如果使用 [Laravel Homestead](/docs/{{version}}/homestead) 虚拟机已经满足这些要求。
18 |
19 |
20 | - PHP >= 5.5.9
21 | - OpenSSL PHP Extension
22 | - PDO PHP Extension
23 | - Mbstring PHP Extension
24 | - Tokenizer PHP Extension
25 |
26 |
27 |
28 | ### 安装 Laravel
29 |
30 | Laravel 使用 [Composer](http://getcomposer.org/) 来管理依赖关系。因此,在使用 Laravel 前,请确认 Composer 已安装在你的计算机上。
31 |
32 | #### 通过 Laravel 安装程序
33 |
34 | 首先, 通过 Composer 下载 Laravel 安装程序:
35 |
36 | composer global require "laravel/installer=~1.1"
37 |
38 | 请确保 `~/.composer/vendor/bin` 目录在你的 `PATH` 中。这样,Laravel 可执行文件才会被系统定位并执行。
39 |
40 | 一但安装后, 你可以使用一个简单的命令 `laravel new` 来创建一个全新的 Laravel 在你指定的目录中。例如,`laravel new blog` 将创建一个名为 `blog` 的目录,并在该目录中创建一个全新安装的 Laravel,并且,所有 Laravel 的依赖已被安装。这个方法比通过 Composer 安装更快:
41 |
42 | laravel new blog
43 |
44 | #### 通过 Composer 创建项目
45 |
46 | 你也可以通过 Composer 的 `create-project` 命令来安装 Laravel:
47 |
48 | composer create-project laravel/laravel --prefer-dist
49 |
50 |
51 | ## 配置
52 |
53 |
54 | ### 基本配置
55 |
56 | 所有配置文件都储存在 Laravel 框架的 `config` 目录中。每个选项都有注释,因此你可以轻松的阅读并且熟悉这些配置项。
57 |
58 | #### 目录权限
59 |
60 | 安装 Laravle 后,你可能需要配置一些权限。目录内的 `storage` 和 `bootstrap/cache` 目录在你的 Web 服务器中应有写权限。如果你使用 [Homestead](/docs/{{version}}/homestead) 虚拟机,那么相关的权限已配置好。
61 |
62 | #### 应用密钥
63 |
64 | 安装完 Laravel 后,你应该设置一个随机字符串作为应用密钥。如果你是通过 Composer 或 Laravel 安装程序进行安装的,这个密钥已通过 `key:generate` 命令被设置。通常,这个字符串长度应该为 32 位。这个密钥被设置在 `.env` 环境配置文件中。如果你还没有将 `.env.example` 重命名为 `.env`,那你现在应该去改名。**如果应用密钥没有被设置,那么你的用户 Session 与其他加密数据将不会是安全的!**
65 |
66 | #### 其他配置
67 |
68 | Laravel 安装后几乎不需要任何配置即可开始使用。你可以立即开始进行开发!然而,你不妨去查看 `config/app.php` 文件与其中的选项说明。它包含了几个选项,例如 `timezone` 和 `locale`。你可以根据你自己的需求来更改它们。
69 |
70 | 你也可能希望更改一些其他 Laravel 组件的配置,例如:
71 |
72 | - [Cache](/docs/{{version}}/cache#configuration)
73 | - [Database](/docs/{{version}}/database#configuration)
74 | - [Session](/docs/{{version}}/session#configuration)
75 |
76 | 一旦 Laravel 被安装,你同样应该配置你的 [环境配置](/docs/{{version}}/installation#environment-configuration)
77 |
78 |
79 | #### 优雅链接
80 |
81 | **Apache**
82 |
83 | 框架自带了 `public/.htaccess` 文件,它将允许 URLs 中省略 `index.php`。如果你的 Laravel 应用运行在 Apache 上,请确认启用了 `mod_rewrite` 模块。
84 |
85 | 如果这个 `.htaccess` 不起作用,你可以尝试如下:
86 |
87 | Options +FollowSymLinks
88 | RewriteEngine On
89 |
90 | RewriteCond %{REQUEST_FILENAME} !-d
91 | RewriteCond %{REQUEST_FILENAME} !-f
92 | RewriteRule ^ index.php [L]
93 |
94 | **Nginx**
95 |
96 | 在 Nginx 中,以下配置将允许你使用优雅链接:
97 |
98 | location / {
99 | try_files $uri $uri/ /index.php?$query_string;
100 | }
101 |
102 | 当然,在使用 [Homestead](/docs/{{version}}/homestead) 时,优雅链接已被自动配置好。
103 |
104 |
105 | ### 环境配置
106 |
107 | 通常应用程序需要根据不同的执行环境有不同的配置选项。例如,你可能希望在你的本机开发环境上与生产服务器环境有不同的缓存驱动,通过环境配置文件,就可以轻松完成。
108 |
109 | 为了使它更轻松,Laravel 使用了 Vance Lucas 写的 [DotEnv](https://github.com/vlucas/phpdotenv) 类库。在全新安装的 Laravel 中,你应用的根目录下会有一个 `.env.example` 文件,如果你是通过 Composer 安装的 Laravel,这个文件已被自动重命名为 `.env`。如果没有,你应该手动重命名。
110 |
111 | 当你的应用程序收到请求,这个文件的所有变量将会被加载到 `$_ENV` PHP 超全局变量中。你可以使用 `env` 辅助函数来取出变量的值。事实上,如果你查看 Laravel 配置的文件,你会发现有几个选项已经使用这个辅助方法了!
112 |
113 | 根据你自己的本地服务器或线上环境需求,你可以轻松地修改你的环境配置,然而,你的 `.env` 文件不应该被提交到应用程序代码的版本控制中,因为每个开发者 / 服务器使用你的应用程序可能需要不同的环境配置。
114 |
115 | 如果你是一个团队的开发者,不妨将 `.env.example` 文件包含到你的应用。通过在配置文件中预留值,团队中的其他开发人员可以很清楚地看到执行你的应用程序所需的环境变量配置。
116 |
117 | #### 获取当前应用环境
118 |
119 | 当前应用环境是通过 `.env` 文件中的 `APP_ENV` 变量决定的。如果你需要访问当前应用环境,可以通过 `App` [facade](/docs/{{version}}/facades):
120 |
121 | $environment = App::environment();
122 |
123 | 你也可以传递参数给 `environment` 来确认当前环境是否符合一个指定的值,你也可以传递多个值:
124 |
125 | if (App::environment('local')) {
126 | // The environment is local
127 | }
128 |
129 | if (App::environment('local', 'staging')) {
130 | // The environment is either local OR staging...
131 | }
132 |
133 | 一个应用实例也可以被通过 `app` 辅助函数访问到:
134 |
135 | $environment = app()->environment();
136 |
137 |
138 | ### 配置缓存
139 |
140 | 为了提升你的应用速度,你应该使用 `config:cache` Artisan 命令缓存你所有的配置文件到一个单一文件中。这将合并你应用中的所有配置选项到单一文件中,以便被框架更快的加载。
141 |
142 | 通常你应该将 `config:cache` 命令作为应用部署时的一个步骤。这个命令在开发环境下不推荐使用,因为在开发流程中配置项会经常的变更。
143 |
144 |
145 | ### 获取配置项
146 |
147 | 你可以使用 `config` 全局辅助函数很容易地访问你的配置项。这个配置的值可以使用 "点" 语法来访问,其中包括你要访问的配置名,与该配置项所在的文件名。如果配置项不存在,你也可以指定一个默认值来返回:
148 |
149 | $value = config('app.timezone');
150 |
151 | 要在程序运行时设置一个配置项,需传递一个数组到 `config` 辅助函数:
152 |
153 | config(['app.timezone' => 'America/Chicago']);
154 |
155 |
156 | ### 应用程序命名
157 |
158 | 在安装 Laravel 后,你可能希望重命名你的应用。默认情况下,`app` 目录下的命名空间为 `App`,且 Compsoer 已经使用 [PSR-4 自动载入标准](http://www.php-fig.org/psr/psr-4/) 来自动加载。然而,你可能会希望将命名空间改成与你应用程序相匹配的名字。你可以很容易地通过 `app:name` Artisan 命令来更改。
159 |
160 | 例如,如果你的应用被命名为 "Horsefly",你可以在框架根目录下执行以下命令:
161 |
162 | php artisan app:name Horsefly
163 |
164 | 重命名你的应用不是必须的。你完全可以保留默认的命名空间 `App`。
165 |
166 |
167 | ## 维护模式
168 |
169 | 如果你的应用处于维护模式,当有请求传入时,将显示一个自定义的视图。当你的应用在更新或者维护时,可以方便的做到 "关闭" 站点。默认的中间件中包含了维护模式的检查。如果当前应用处于维护模式,一个 带有 503 状态码 的 `HttpException` 异常将被抛出。
170 |
171 | 要开启维护模式,你可以简单地使用 `down` Artisan 命令:
172 |
173 | php artisan down
174 |
175 | 要关闭维护模式,你可以简单地使用 `up` Artisan 命令:
176 |
177 | php artisan up
178 |
179 | ### 维护模式响应模板
180 |
181 | 默认的维护模式模板文件位于: `resources/views/errors/503.blade.php`
182 |
183 | ### 维护模式和队列
184 |
185 | 当你的应用处于维护模式,将不会有 [队列 Jobs](/docs/{{version}}/queues) 被处理。这些 Jobs 将在应用关闭维护模式后继续正常处理。
186 |
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright © Taylor Otwell
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/lifecycle.md:
--------------------------------------------------------------------------------
1 | # Request Lifecycle
2 |
3 | - [Introduction](#introduction)
4 | - [Lifecycle Overview](#lifecycle-overview)
5 | - [Focus On Service Providers](#focus-on-service-providers)
6 |
7 |
8 | ## Introduction
9 |
10 | When using any tool in the "real world", you feel more confident if you understand how that tool works. Application development is no different. When you understand how your development tools function, you feel more comfortable and confident using them.
11 |
12 | The goal of this document is to give you a good, high-level overview of how the Laravel framework "works". By getting to know the overall framework better, everything feels less "magical" and you will be more confident building your applications.
13 |
14 | If you don't understand all of the terms right away, don't lose heart! Just try to get a basic grasp of what is going on, and your knowledge will grow as you explore other sections of the documentation.
15 |
16 |
17 | ## Lifecycle Overview
18 |
19 | ### First Things
20 |
21 | The entry point for all requests to a Laravel application is the `public/index.php` file. All requests are directed to this file by your web server (Apache / Nginx) configuration. The `index.php` file doesn't contain much code. Rather, it is simply a starting point for loading the rest of the framework.
22 |
23 | The `index.php` file loads the Composer generated autoloader definition, and then retrieves an instance of the Laravel application from `bootstrap/app.php` script. The first action taken by Laravel itself is to create an instance of the application / [service container](/docs/{{version}}/container).
24 |
25 | ### HTTP / Console Kernels
26 |
27 | Next, the incoming request is sent to either the HTTP kernel or the console kernel, depending on the type of request that is entering the application. These two kernels serve as the central location that all requests flow through. For now, let's just focus on the HTTP kernel, which is located in `app/Http/Kernel.php`.
28 |
29 | The HTTP kernel extends the `Illuminate\Foundation\Http\Kernel` class, which defines an array of `bootstrappers` that will be run before the request is executed. These bootstrappers configure error handling, configure logging, [detect the application environment](/docs/{{version}}/installation#environment-configuration), and perform other tasks that need to be done before the request is actually handled.
30 |
31 | The HTTP kernel also defines a list of HTTP [middleware](/docs/{{version}}/middleware) that all requests must pass through before being handled by the application. These middleware handle reading and writing the [HTTP session](/docs/{{version}}/session), determine if the application is in maintenance mode, [verifying the CSRF token](/docs/{{version}}/routing#csrf-protection), and more.
32 |
33 | The method signature for the HTTP kernel's `handle` method is quite simple: receive a `Request` and return a `Response`. Think of the Kernel as being a big black box that represents your entire application. Feed it HTTP requests and it will return HTTP responses.
34 |
35 | #### Service Providers
36 |
37 | One of the most important Kernel bootstrapping actions is loading the [service providers](/docs/{{version}}/providers) for your application. All of the service providers for the application are configured in the `config/app.php` configuration file's `providers` array. First, the `register` method will be called on all providers, then, once all providers have been registered, the `boot` method will be called.
38 |
39 | Service providers are responsible for bootstrapping all of the framework's various components, such as the database, queue, validation, and routing components. Since they bootstrap and configure every feature offered by the framework, service providers are the most important aspect of the entire Laravel bootstrap process.
40 |
41 | #### Dispatch Request
42 |
43 | Once the application has been bootstrapped and all service providers have been registered, the `Request` will be handed off to the router for dispatching. The router will dispatch the request to a route or controller, as well as run any route specific middleware.
44 |
45 |
46 | ## Focus On Service Providers
47 |
48 | Service providers are truly the key to bootstrapping a Laravel application. The application instance is created, the service providers are registered, and the request is handed to the bootstrapped application. It's really that simple!
49 |
50 | Having a firm grasp of how a Laravel application is built and bootstrapped via service providers is very valuable. Of course, your application's default service providers are stored in the `app/Providers` directory.
51 |
52 | By default, the `AppServiceProvider` is fairly empty. This provider is a great place to add your application's own bootstrapping and service container bindings. Of course, for large applications, you may wish to create several service providers, each with a more granular type of bootstrapping.
53 |
--------------------------------------------------------------------------------
/localization.md:
--------------------------------------------------------------------------------
1 | # 本地化
2 |
3 | - [介绍](#introduction)
4 | - [基本用法](#basic-usage)
5 | - [复数形式](#pluralization)
6 | - [覆写扩展包的语言文件](#overriding-vendor-language-files)
7 |
8 |
9 | ## 介绍
10 |
11 | Laravel的本地化功能提供了一种便利的获取多种语言字串的方法,让你轻松地在应用中支持多语言。
12 |
13 | 语言字串保存在目录 `resources/lang` 下的文件中。应用支持的每种语言都对应该目录下的一个子目录:
14 |
15 | /resources
16 | /lang
17 | /en
18 | messages.php
19 | /es
20 | messages.php
21 |
22 | 所有语言文件都简单返回一个带有键值的数组。例如:
23 |
24 | 'Welcome to our application'
28 | ];
29 |
30 | #### 配置语言环境
31 |
32 | 你的应用的默认语言保存在 `config/app.php` 配置文件中。当然,你可以根据需要修改该值。你也可以使用 `App` facade 的 `setLocale` 方法在运行时修改当前语言。
33 |
34 | Route::get('welcome/{locale}', function ($locale) {
35 | App::setLocale($locale);
36 |
37 | //
38 | });
39 |
40 | 你也可以配置一个 "备用语言", 它会在当前语言不含有给定的语句时被使用。 和默认语言一样,备用语言也在 `config/app.php` 中设置:
41 |
42 | 'fallback_locale' => 'en',
43 |
44 |
45 | ## 基本用法
46 |
47 | 你可以通过 `trans` 方法从语言文件中获取各行字串。`trans` 方法接受文件名和键值作为第一个参数。比如获取 `resources/lang/messages.php` 文件中键值为 `welcome` 的字串:
48 |
49 | echo trans('messages.welcome');
50 |
51 | 如果你在使用 [Blade templating engine](/docs/{{version}}/blade) 模版引擎,你可以使用 `{{ }}` 语法输出行字串:
52 |
53 | {{ trans('messages.welcome') }}
54 |
55 | 如果该指定的行字串不存在,`trans` 函数只简单返回该行字串的键值。所以在上面的例子中,`trans` 将返回 `messages.welcome`如果不存在该行字串。
56 |
57 | #### 在语言文件中替换参数
58 |
59 | 你还可以给语言文件中的各行定义占位符。所有的占位符都以 `:` 为前缀。比如你可以定义一个带有占位符 name 的欢迎信息:
60 |
61 | 'welcome' => 'Welcome, :name',
62 |
63 | 要替换占位符,只需要将一个数组作为第二个参数传入 `trans` 函数:
64 |
65 | echo trans('messages.welcome', ['name' => 'Dayle']);
66 |
67 |
68 | ### 复数形式
69 |
70 | 复数是个复杂的问题,不同语言对复数有各自不同的规则。通过使用 “|” 标记,你可以区分一个字符串的单数和复数形式:
71 |
72 | 'apples' => 'There is one apple|There are many apples',
73 |
74 | 接下来你可以使用 `trans_choice` 方法来根据给定的”个数“取得字串。在下面的例子中,因为个数大于1,所以返回该行的复数形式的字串:
75 |
76 | echo trans_choice('messages.apples', 10);
77 |
78 | 因为 Laravel 的翻译器由 Symfony 翻译组件提供,你可以创建更加复杂的复数规则:
79 |
80 | 'apples' => '{0} There are none|[1,19] There are some|[20,Inf] There are many',
81 |
82 |
83 | ## 覆写扩展包的语言文件
84 |
85 | 有些扩展包自带语言文件。你可以将语言文件放置在 `resources/lang/vendor/{package}/{locale}` 目录来覆写它们,而不是去修改扩展包的核心文件。
86 |
87 | 所以,如果你需要覆写 `skyrim/hearthfire` 扩展包的 `messages.php` 中的英文语句,你可以将一个语言文件放置在 `resources/lang/vendor/hearthfire/en/messages.php`。在该文件中只定义需要覆写的语句,没有被覆写的语句将依然从扩展包的语言文件中加载。
88 |
--------------------------------------------------------------------------------
/middleware.md:
--------------------------------------------------------------------------------
1 | # HTTP Middleware
2 |
3 | - [Introduction](#introduction)
4 | - [Defining Middleware](#defining-middleware)
5 | - [Registering Middleware](#registering-middleware)
6 | - [Middleware Parameters](#middleware-parameters)
7 | - [Terminable Middleware](#terminable-middleware)
8 |
9 |
10 | ## Introduction
11 |
12 | HTTP middleware provide a convenient mechanism for filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to the login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.
13 |
14 | Of course, additional middleware can be written to perform a variety of tasks besides authentication. A CORS middleware might be responsible for adding the proper headers to all responses leaving your application. A logging middleware might log all incoming requests to your application.
15 |
16 | There are several middleware included in the Laravel framework, including middleware for maintenance, authentication, CSRF protection, and more. All of these middleware are located in the `app/Http/Middleware` directory.
17 |
18 |
19 | ## Defining Middleware
20 |
21 | To create a new middleware, use the `make:middleware` Artisan command:
22 |
23 | php artisan make:middleware OldMiddleware
24 |
25 | This command will place a new `OldMiddleware` class within your `app/Http/Middleware` directory. In this middleware, we will only allow access to the route if the supplied `age` is greater than 200. Otherwise, we will redirect the users back to the "home" URI.
26 |
27 | input('age') <= 200) {
45 | return redirect('home');
46 | }
47 |
48 | return $next($request);
49 | }
50 |
51 | }
52 |
53 | As you can see, if the given `age` is less than or equal to `200`, the middleware will return an HTTP redirect to the client; otherwise, the request will be passed further into the application. To pass the request deeper into the application (allowing the middleware to "pass"), simply call the `$next` callback with the `$request`.
54 |
55 | It's best to envision middleware as a series of "layers" HTTP requests must pass through before they hit your application. Each layer can examine the request and even reject it entirely.
56 |
57 | ### *Before* / *After* Middleware
58 |
59 | Whether a middleware runs before or after a request depends on the middleware itself. For example, the following middleware would perform some task **before** the request is handled by the application:
60 |
61 |
98 | ## Registering Middleware
99 |
100 | ### Global Middleware
101 |
102 | If you want a middleware to be run during every HTTP request to your application, simply list the middleware class in the `$middleware` property of your `app/Http/Kernel.php` class.
103 |
104 | ### Assigning Middleware To Routes
105 |
106 | If you would like to assign middleware to specific routes, you should first assign the middleware a short-hand key in your `app/Http/Kernel.php` file. By default, the `$routeMiddleware` property of this class contains entries for the middleware included with Laravel. To add your own, simply append it to this list and assign it a key of your choosing. For example:
107 |
108 | // Within App\Http\Kernel Class...
109 |
110 | protected $routeMiddleware = [
111 | 'auth' => \App\Http\Middleware\Authenticate::class,
112 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
113 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
114 | ];
115 |
116 | Once the middleware has been defined in the HTTP kernel, you may use the `middleware` key in the route options array:
117 |
118 | Route::get('admin/profile', ['middleware' => 'auth', function () {
119 | //
120 | }]);
121 |
122 |
123 | ## Middleware Parameters
124 |
125 | Middleware can also receive additional custom parameters. For example, if your application needs to verify that the authenticated user has a given "role" before performing a given action, you could create a `RoleMiddleware` that receives a role name as an additional argument.
126 |
127 | Additional middleware parameters will be passed to the middleware after the `$next` argument:
128 |
129 | user()->hasRole($role)) {
148 | // Redirect...
149 | }
150 |
151 | return $next($request);
152 | }
153 |
154 | }
155 |
156 | Middleware parameters may be specified when defining the route by separating the middleware name and parameters with a `:`. Multiple parameters should be delimited by commas:
157 |
158 | Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) {
159 | //
160 | }]);
161 |
162 |
163 | ## Terminable Middleware
164 |
165 | Sometimes a middleware may need to do some work after the HTTP response has already been sent to the browser. For example, the "session" middleware included with Laravel writes the session data to storage _after_ the response has been sent to the browser. To accomplish this, define the middleware as "terminable" by adding a `terminate` method to the middleware:
166 |
167 |
19 | ## 介绍
20 |
21 | 迁移就像是数据库的版本控制,可以方便团队的修改和共享数据库结构.迁移通常会和[结构生成器](/docs/{{version}}/schema)一起使用,可以很简单的为你的应用创建数据库结构.
22 |
23 | Laravel `Schema` [facade](/docs/{{version}}/facades)提供一个与数据库无关的数据表创建和操作方法,它可以很好的处理 Laravel 支持的各种数据库类型,并且在不同系统间提供一致性的 API 操作。
24 |
25 |
26 | ## 创建迁移
27 |
28 | 使用 [Artisan CLI](/docs/{{version}}/artisan) 的 `make:migrate` 命令建立迁移文件:
29 |
30 | php artisan make:migration create_users_table
31 |
32 | 迁移文件会建立在 database/migrations 目录下,文件名会包含时间戳记,在执行迁移时用来确定顺序。
33 |
34 | `--table` 和 `--create` 参数可以用来指定数据表名称,以及迁移文件是否要建立新的数据表。这些选项可以简单预填充到为指定的表生成的迁移存根文件:
35 |
36 | php artisan make:migration add_votes_to_users_table --table=users
37 |
38 | php artisan make:migration create_users_table --create=users
39 |
40 | 如果你想指定生成迁移文件的自定义导出路径,可以在执行`make:migration`命令使用`--path`参数,提供的路径应该是相对于应用程序的基本路径.
41 |
42 |
43 | ## 迁移结构
44 |
45 | 一个迁移类应包含两个方法:`up`和`down`,`up`方法用于为数据库添加新的表,列或索引,而`down`方法应简单的反转有`up`方法执行的操作.
46 | 在这两种方法内,你可以使用Laravel的结构生成器意味深长的创建和修改数据表.要了解结构生成器所有的可用方法,[点击这里](#creating-tables).
47 | For example, let's look at a sample migration that creates a `flights` table:
48 | 下面我们举一个简单的例子,创建`flights`表迁移:
49 |
50 | increments('id');
66 | $table->string('name');
67 | $table->string('airline');
68 | $table->timestamps();
69 | });
70 | }
71 |
72 | /**
73 | * Reverse the migrations.
74 | *
75 | * @return void
76 | */
77 | public function down()
78 | {
79 | Schema::drop('flights');
80 | }
81 | }
82 |
83 |
84 |
85 | ## 运行迁移
86 |
87 | 通过Artisan命令`migrate`来运行所有未执行的迁移,如果你用的是[Homestead](/docs/{{version}}/homestead)虚拟机开发环境,你应该在你的VM里运行下面的命令:
88 |
89 | php artisan migrate
90 |
91 | 果运行命令报错`class not found`,可以试试这条命令`composer dump-autoload`,然后再重新执行上面的迁移命令.
92 |
93 | #### 在生产环境中强制迁移
94 |
95 | 有些迁移操作是破坏性的,可能导致你丢失数据,为了保护你的生产数据,当你对生产数据库执行这些命令之前,系统会提示您进行确认,如果不想系统提示确认,可以用参数`--force`:
96 |
97 | php artisan migrate --force
98 |
99 |
100 | ### 回滚迁移
101 |
102 | 用`rollback`命令可以回滚最近的一次迁移操作,注意,执行过的最后一“批”迁移可以包括多个迁移文件:
103 |
104 | php artisan migrate:rollback
105 |
106 | `migrate:reset`命令可以回滚应用的所有迁移:
107 |
108 | php artisan migrate:reset
109 |
110 | #### 回滚/迁移单个命令
111 |
112 | `migrate:refresh`命令会先回滚所有数据库迁移,然后再执行`migrate`命令,该命令会重建你的整个数据库:
113 |
114 | php artisan migrate:refresh
115 |
116 | php artisan migrate:refresh --seed
117 |
118 |
119 | ## 编写迁移
120 |
121 |
122 | ### 创建表
123 |
124 | 用结构生成器(`Schema` facade)的`create`方法可以创建新的数据表.`create`方法有两个参数,第一个参数是表名,第二个参数是`Closure`(闭包函数),它接收一个`Blueprint`(蓝图)对象,用于创建新表:
125 |
126 | Schema::create('users', function ($table) {
127 | $table->increments('id');
128 | });
129 |
130 | 当然,在创建表时,你可以使用结构生成器的任何的[列方法](http://laravel-china.org/docs/5.1/migrations#creating-columns)来定义表的列。
131 |
132 | #### 检查表/列是否存在
133 |
134 | 通过`hasTable`和`hasColumn`方法,你可以很容易的检查表或列是否存在:
135 |
136 | if (Schema::hasTable('users')) {
137 | //
138 | }
139 |
140 | if (Schema::hasColumn('users', 'email')) {
141 | //
142 | }
143 |
144 | #### 连接和存储引擎
145 |
146 | 如果你要进行模式操作的数据库连接不是你的默认连接,可以使用`connection`方法:
147 |
148 | Schema::connection('foo')->create('users', function ($table) {
149 | $table->increments('id');
150 | });
151 |
152 | 通过设置结构生成器的`engine`参数,为一张表设置数据存储引擎:
153 |
154 | Schema::create('users', function ($table) {
155 | $table->engine = 'InnoDB';
156 |
157 | $table->increments('id');
158 | });
159 |
160 |
161 | ### 重命名/删除表
162 |
163 | 用`rename`方法可以重命名一个存在的数据表:
164 |
165 | Schema::rename($from, $to);
166 |
167 | 用`drop`或`dropIfExists`方法可以删除一个存在的数据表:
168 |
169 | Schema::drop('users');
170 |
171 | Schema::dropIfExists('users');
172 |
173 |
174 | ### 创建列
175 |
176 | 我们用结构生成器的`table`方法更新现有的表,和`create`方法类似,`table`方法接受两个参数:表名和一个`Closure`(闭包,它接收一个`Blueprint`(蓝图)实例,用于添加列到数据表):
177 |
178 | Schema::table('users', function ($table) {
179 | $table->string('email');
180 | });
181 |
182 | #### 可用列类型
183 |
184 | 数据表产生器提供多种字段类型可使用,在您建立数据表时也许会用到:
185 |
186 | 命令 | 功能描述
187 | ------------- | -------------
188 | `$table->bigIncrements('id');` | ID 自动增量,使用相当于「big integer」类型
189 | `$table->bigInteger('votes');` | 相当于 BIGINT 类型
190 | `$table->binary('data');` | 相当于 BLOB 类型
191 | `$table->boolean('confirmed');` | 相当于 BOOLEAN 类型
192 | `$table->char('name', 4);` | 相当于 CHAR 类型,并带有长度
193 | `$table->date('created_at');` | 相当于 DATE 类型
194 | `$table->dateTime('created_at');` | 相当于 DATETIME 类型
195 | `$table->decimal('amount', 5, 2);` | 相当于 DECIMAL 类型,并带有精度与基数
196 | `$table->double('column', 15, 8);` | 相当于 DOUBLE 类型,总共有 15 位数,在小数点后面有 8 位数
197 | `$table->enum('choices', array('foo', 'bar'));` | 相当于 ENUM 类型
198 | `$table->float('amount');` | 相当于 FLOAT 类型
199 | `$table->increments('id');` | 相当于 Incrementing 类型 (数据表主键)
200 | `$table->integer('votes');` | 相当于 INTEGER 类型
201 | `$table->json('options');` | 相当于 JSON 类型
202 | `$table->jsonb('options');` | JSONB equivalent to the table
203 | `$table->longText('description');` | 相当于 LONGTEXT 类型
204 | `$table->mediumInteger('numbers');` | 相当于 MEDIUMINT 类型
205 | `$table->mediumText('description');` | 相当于 MEDIUMTEXT 类型
206 | `$table->morphs('taggable');` | 加入整数 `taggable_id` 与字串 `taggable_type`
207 | `$table->nullableTimestamps();` | 与 `timestamps()` 相同,但允许 NULL
208 | `$table->smallInteger('votes');` | 相当于 SMALLINT 类型
209 | `$table->tinyInteger('numbers');` | 相当于 TINYINT 类型
210 | `$table->softDeletes();` | 加入 **deleted\_at** 字段于软删除使用
211 | `$table->string('email');` | 相当于 VARCHAR 类型
212 | `$table->string('name', 100);` | 相当于 VARCHAR 类型,并指定长度
213 | `$table->text('description');` | 相当于 TEXT 类型
214 | `$table->time('sunrise');` | 相当于 TIME 类型
215 | `$table->timestamp('added_on');` | 相当于 TIMESTAMP 类型
216 | `$table->timestamps();` | 加入 **created\_at** 和 **updated\_at** 字段
217 | `$table->rememberToken();` | 加入 `remember_token` 使用 VARCHAR(100) NULL
218 |
219 | #### 列修饰符
220 |
221 | 除了以上列出的列类型,还有几个列修饰符,可以在加入列的同时使用,例如,让某列"可以为空",你可能会用到`nullable`方法:
222 |
223 | Schema::table('users', function ($table) {
224 | $table->string('email')->nullable();
225 | });
226 |
227 | 下面是所有可用列修饰符列表,这个列表并不被包含在[索引修饰符](#creating-indexes)里:
228 |
229 | 修饰符 | 描述
230 | ------------- | -------------
231 | ->first() | 将列调整为表的第一列 (MySQL Only)
232 | ->after('column') | 将列调整到'column'列的后面 (MySQL Only)
233 | ->nullable() | 该列允许列插入空值
234 | ->default($value) | 指定该列的默认值为$value
235 | ->unsigned() | 指定 `integer(整型)` 列为 `UNSIGNED(无符号)`列
236 |
237 |
238 |
239 | ### 修改列
240 |
241 | #### 先决条件(Prerequisites)
242 |
243 | 修改列之前,请务必确定你的`composer.json`文件已添加依赖项`doctrine/dbal`,Doctrine DBAL库用于确定列的当前状态,并创建指定调整到列的SQL查询。
244 |
245 | #### 修改列属性
246 |
247 | `change`能让你修改一个已经存在的列的类型或属性.例如:你像增加一个string类型列的字段长度,让我们看看`change`方法的行动力,假设我们想要将字段 `name` 的长度从 25 增加到 50:
248 |
249 | Schema::table('users', function ($table) {
250 | $table->string('name', 50)->change();
251 | });
252 |
253 | 我们还可以设定,让这个字段可以为空:
254 |
255 | Schema::table('users', function ($table) {
256 | $table->string('name', 50)->nullable()->change();
257 | });
258 |
259 |
260 | #### 修改列名称
261 |
262 | 要修改列名称,你可能会在结构生成器中用到`renameColumn`方法,请确认在修改前 `composer.json` 文件内已经加入 `doctrine/dbal`.:
263 |
264 | Schema::table('users', function ($table) {
265 | $table->renameColumn('from', 'to');
266 | });
267 |
268 | > **注意:** `enum`字段类型不支持字段名称修改
269 |
270 |
271 | ### 移除列
272 |
273 | 要移除列,可在结构生成器内使用 `dropColumn` 方法.:
274 |
275 | Schema::table('users', function ($table) {
276 | $table->dropColumn('votes');
277 | });
278 |
279 | 如果你给`dropcolumn`方法传递包含多个列名的数组,则可以移除多个列:
280 |
281 | Schema::table('users', function ($table) {
282 | $table->dropColumn(['votes', 'avatar', 'location']);
283 | });
284 |
285 | > **注意:** 从SQLite数据库删除列前,你需要将`composer.json` 文件内已经加入 `doctrine/dbal`,并在终端运行`composer update`来安装库.
286 |
287 |
288 | ### 创建索引
289 |
290 | 结构生成器支持多种索引类型.首先,让我们来看一个例子,它指定列的值应该是唯一的。要创建索引,我们可以在定义列的时候,用`unique`方法链上去:
291 |
292 | $table->string('email')->unique();
293 |
294 | 或者,您可以先定义列,之后再创建索引,例如:
295 |
296 | $table->unique('email');
297 |
298 | 你甚至可以将一个数组传递给一个索引方法来创建一个复合索引:
299 |
300 | $table->index(['account_id', 'created_at']);
301 |
302 | #### 可用的索引类型
303 |
304 | 命令 | 功能描述
305 | ------------- | -------------
306 | $table->primary('id'); | 添加主键 (primary key)
307 | $table->primary(['first', 'last']); | 添加组合键(composite keys)
308 | $table->unique('email'); | 添加唯一索引 (unique index)
309 | $table->index('state'); | 添加基本索引 (index)
310 |
311 |
312 | ### 移除索引
313 |
314 | 要移除索引就必须指定索引名称,默认情况下,Laravel默认有脉络可循的索引名称.简单地链接这些数据表与索引的字段名称和类型.举例如下:
315 |
316 | 命令 | 功能描述
317 | ------------- | -------------
318 | `$table->dropPrimary('users_id_primary');` | 从「users」数据表移除主键
319 | `$table->dropUnique('users_email_unique');` | 从「users」数据表移除唯一索引
320 | `$table->dropIndex('geo_state_index');` | 从「geo」数据表移除基本索引
321 |
322 |
323 | ### 外键约束
324 |
325 | Laravel 也支持数据表的外键约束,这是用来在数据库级别强制引用完整性,例如:我们在`posts`表定义的`user_id`列是引用了`user`表的`id`列:
326 |
327 | Schema::table('posts', function ($table) {
328 | $table->integer('user_id')->unsigned();
329 |
330 | $table->foreign('user_id')->references('id')->on('users');
331 | });
332 |
333 | 您也可以指定在「on delete」和「on update」进行约束动作:
334 |
335 | $table->foreign('user_id')
336 | ->references('id')->on('users')
337 | ->onDelete('cascade');
338 |
339 | 要移除外键,可使用 `dropForeign` 方法。外键的命名约定雷同其他索引,因此,我们可以连接约束中的表名和列,后缀为`_foreign`:
340 |
341 | $table->dropForeign('posts_user_id_foreign');
342 |
343 |
344 |
--------------------------------------------------------------------------------
/packages.md:
--------------------------------------------------------------------------------
1 | # Package Development
2 |
3 | - [Introduction](#introduction)
4 | - [Service Providers](#service-providers)
5 | - [Routing](#routing)
6 | - [Resources](#resources)
7 | - [Views](#views)
8 | - [Translations](#translations)
9 | - [Configuration](#configuration)
10 | - [Public Assets](#public-assets)
11 | - [Publishing File Groups](#publishing-file-groups)
12 |
13 |
14 | ## Introduction
15 |
16 | Packages are the primary way of adding functionality to Laravel. Packages might be anything from a great way to work with dates like [Carbon](https://github.com/briannesbitt/Carbon), or an entire BDD testing framework like [Behat](https://github.com/Behat/Behat).
17 |
18 | Of course, there are different types of packages. Some packages are stand-alone, meaning they work with any framework, not just Laravel. Both Carbon and Behat are examples of stand-alone packages. Any of these packages may be used with Laravel by simply requesting them in your `composer.json` file.
19 |
20 | On the other hand, other packages are specifically intended for use with Laravel. These packages may have routes, controllers, views, and configuration specifically intended to enhance a Laravel application. This guide primarily covers the development of those packages that are Laravel specific.
21 |
22 |
23 | ## Service Providers
24 |
25 | [Service providers](/docs/{{version}}/providers) are the connection points between your package and Laravel. A service provider is responsible for binding things into Laravel's [service container](/docs/{{version}}/container) and informing Laravel where to load package resources such as views, configuration, and localization files.
26 |
27 | A service provider extends the `Illuminate\Support\ServiceProvider` class and contains two methods: `register` and `boot`. The base `ServiceProvider` class is located in the `illuminate/support` Composer package, which you should add to your own package's dependencies.
28 |
29 | To learn more about the structure and purpose of service providers, check out [their documentation](/docs/{{version}}/providers).
30 |
31 |
32 | ## Routing
33 |
34 | To define routes for your package, simply `require` the routes file from within your package service provider's `boot` method. From within your routes file, you may use the `Route` facade to [register routes](/docs/{{version}}/routing) just as you would within a typical Laravel application:
35 |
36 | /**
37 | * Perform post-registration booting of services.
38 | *
39 | * @return void
40 | */
41 | public function boot()
42 | {
43 | if (! $this->app->routesAreCached()) {
44 | require __DIR__.'/../../routes.php';
45 | }
46 | }
47 |
48 |
49 | ## Resources
50 |
51 |
52 | ### Views
53 |
54 | To register your package's [views](/docs/{{version}}/views) with Laravel, you need to tell Laravel where the views are located. You may do this using the service provider's `loadViewsFrom` method. The `loadViewsFrom` method accepts two arguments: the path to your view templates and your package's name. For example, if your package name is "courier", add the following to your service provider's `boot` method:
55 |
56 | /**
57 | * Perform post-registration booting of services.
58 | *
59 | * @return void
60 | */
61 | public function boot()
62 | {
63 | $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
64 | }
65 |
66 | Package views are referenced using a double-colon `package::view` syntax. So, you may load the `admin` view from the `courier` package like so:
67 |
68 | Route::get('admin', function () {
69 | return view('courier::admin');
70 | });
71 |
72 | #### Overriding Package Views
73 |
74 | When you use the `loadViewsFrom` method, Laravel actually registers **two** locations for your views: one in the application's `resources/views/vendor` directory and one in the directory you specify. So, using our `courier` example: when requesting a package view, Laravel will first check if a custom version of the view has been provided by the developer in `resources/views/vendor/courier`. Then, if the view has not been customized, Laravel will search the package view directory you specified in your call to `loadViewsFrom`. This makes it easy for end-users to customize / override your package's views.
75 |
76 | #### Publishing Views
77 |
78 | If you would like to make your views available for publishing to the application's `resources/views/vendor` directory, you may use the service provider's `publishes` method. The `publishes` method accepts an array of package view paths and their corresponding publish locations.
79 |
80 | /**
81 | * Perform post-registration booting of services.
82 | *
83 | * @return void
84 | */
85 | public function boot()
86 | {
87 | $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
88 |
89 | $this->publishes([
90 | __DIR__.'/path/to/views' => base_path('resources/views/vendor/courier'),
91 | ]);
92 | }
93 |
94 | Now, when users of your package execute Laravel's `vendor:publish` Artisan command, your views package's will be copied to the specified location.
95 |
96 |
97 | ### Translations
98 |
99 | If your package contains [translation files](/docs/{{version}}/localization), you may use the `loadTranslationsFrom` method to inform Laravel how to load them. For example, if your package is named "courier", you should add the following to your service provider's `boot` method:
100 |
101 | /**
102 | * Perform post-registration booting of services.
103 | *
104 | * @return void
105 | */
106 | public function boot()
107 | {
108 | $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
109 | }
110 |
111 | Package translations are referenced using a double-colon `package::file.line` syntax. So, you may load the `courier` package's `welcome` line from the `messages` file like so:
112 |
113 | echo trans('courier::messages.welcome');
114 |
115 |
116 | ### Configuration
117 |
118 | Typically, you will want to publish your package's configuration file to the application's own `config` directory. This will allow users of your package to easily override your default configuration options. To publish a configuration file, just use the `publishes` method from the `boot` method of your service provider:
119 |
120 | /**
121 | * Perform post-registration booting of services.
122 | *
123 | * @return void
124 | */
125 | public function boot()
126 | {
127 | $this->publishes([
128 | __DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
129 | ]);
130 | }
131 |
132 | Now, when users of your package execute Laravel's `vendor:publish` command, your file will be copied to the specified location. Of course, once your configuration has been published, it can be accessed like any other configuration file:
133 |
134 | $value = config('courier.option');
135 |
136 | #### Default Package Configuration
137 |
138 | You may also choose to merge your own package configuration file with the application's copy. This allows your users to include only the options they actually want to override in the published copy of the configuration. To merge the configurations, use the `mergeConfigFrom` method within your service provider's `register` method:
139 |
140 | /**
141 | * Register bindings in the container.
142 | *
143 | * @return void
144 | */
145 | public function register()
146 | {
147 | $this->mergeConfigFrom(
148 | __DIR__.'/path/to/config/courier.php', 'courier'
149 | );
150 | }
151 |
152 |
153 | ## Public Assets
154 |
155 | Your packages may have assets such as JavaScript, CSS, and images. To publish these assets to the application's `public` directory, use the service provider's `publishes` method. In this example, we will also add a `public` asset group tag, which may be used to publish groups of related assets:
156 |
157 | /**
158 | * Perform post-registration booting of services.
159 | *
160 | * @return void
161 | */
162 | public function boot()
163 | {
164 | $this->publishes([
165 | __DIR__.'/path/to/assets' => public_path('vendor/courier'),
166 | ], 'public');
167 | }
168 |
169 | Now, when your package's users execute the `vendor:publish` command, your assets will be copied to the specified location. Since you typically will need to overwrite the assets every time the package is updated, you may use the `--force` flag:
170 |
171 | php artisan vendor:publish --tag=public --force
172 |
173 | If you would like to make sure your public assets are always up-to-date, you can add this command to the `post-update-cmd` list in your `composer.json` file.
174 |
175 |
176 | ## Publishing File Groups
177 |
178 | You may want to publish groups of package assets and resources separately. For instance, you might want your users to be able to publish your package's configuration files without being forced to publish your package's assets at the same time. You may do this by "tagging" them when calling the `publishes` method. For example, let's define two publish groups in the `boot` method of a package service provider:
179 |
180 | /**
181 | * Perform post-registration booting of services.
182 | *
183 | * @return void
184 | */
185 | public function boot()
186 | {
187 | $this->publishes([
188 | __DIR__.'/../config/package.php' => config_path('package.php')
189 | ], 'config');
190 |
191 | $this->publishes([
192 | __DIR__.'/../database/migrations/' => database_path('migrations')
193 | ], 'migrations');
194 | }
195 |
196 | Now your users may publish these groups separately by referencing their tag name when using the `vendor:publish` Artisan command:
197 |
198 | php artisan vendor:publish --provider="Vendor\Providers\PackageServiceProvider" --tag="config"
199 |
--------------------------------------------------------------------------------
/pagination.md:
--------------------------------------------------------------------------------
1 | # Pagination
2 |
3 | - [Introduction](#introduction)
4 | - [Basic Usage](#basic-usage)
5 | - [Paginating Query Builder Results](#paginating-query-builder-results)
6 | - [Paginating Eloquent Results](#paginating-eloquent-results)
7 | - [Manually Creating A Paginator](#manually-creating-a-paginator)
8 | - [Displaying Results In A View](#displaying-results-in-a-view)
9 | - [Converting Results To JSON](#converting-results-to-json)
10 |
11 |
12 | ## Introduction
13 |
14 | In other frameworks, pagination can be very painful. Laravel makes it a breeze. Laravel can quickly generate an intelligent "range" of links based on the current page, and the generated HTML is compatible with the [Bootstrap CSS framework](http://getbootstrap.com/).
15 |
16 |
17 | ## Basic Usage
18 |
19 |
20 | ### Paginating Query Builder Results
21 |
22 | There are several ways to paginate items. The simplest is by using the `paginate` method on the [query builder](/docs/{{version}}/queries) or an [Eloquent query](/docs/{{version}}/eloquent). The `paginate` method provided by Laravel automatically takes care of setting the proper limit and offset based on the current page being viewed by the user. By default, the current page is detected by the value of the `?page` query string argument on the HTTP request. Of course, this value is automatically detected by Laravel, and is also automatically inserted into links generated by the paginator.
23 |
24 | First, let's take a look at calling the `paginate` method on a query. In this example, the only argument passed to `paginate` is the number of items you would like displayed "per page". In this case, let's specify that we would like to display `15` items per page:
25 |
26 | paginate(15);
43 |
44 | return view('user.index', ['users' => $users]);
45 | }
46 | }
47 |
48 | > **Note:** Currently, pagination operations that use a `groupBy` statement cannot be executed efficiently by Laravel. If you need to use a `groupBy` with a paginated result set, it is recommended that you query the database and create a paginator manually.
49 |
50 | #### "Simple Pagination"
51 |
52 | If you only need to display simple "Next" and "Previous" links in your pagination view, you have the option of using the `simplePaginate` method to perform a more efficient query. This is very useful for large datasets if you do not need to display a link for each page number when rendering your view:
53 |
54 | $users = DB::table('users')->simplePaginate(15);
55 |
56 |
57 | ### Paginating Eloquent Results
58 |
59 | You may also paginate [Eloquent](/docs/{{version}}/eloquent) queries. In this example, we will paginate the `User` model with `15` items per page. As you can see, the syntax is nearly identical to paginating query builder results:
60 |
61 | $users = App\User::paginate(15);
62 |
63 | Of course, you may call `paginate` after setting other constraints on the query, such as `where` clauses:
64 |
65 | $users = User::where('votes', '>', 100)->paginate(15);
66 |
67 | You may also use the `simplePaginate` method when paginating Eloquent models:
68 |
69 | $users = User::where('votes', '>', 100)->simplePaginate(15);
70 |
71 |
72 | ### Manually Creating A Paginator
73 |
74 | Sometimes you may wish to create a pagination instance manually, passing it an array of items. You may do so by creating either an `Illuminate\Pagination\Paginator` or `Illuminate\Pagination\LengthAwarePaginator` instance, depending on your needs.
75 |
76 | The `Paginator` class does not need to know the total number of items in the result set; however, because of this, the class does not have methods for retrieve the index of the last page. The `LengthAwarePaginator` accepts almost the same arguments as the `Paginator`; however, it does require a count of the total number of items in the result set.
77 |
78 | In other words, the `Paginator` corresponds to the `simplePaginate` method on the query builder and Eloquent, while the `LengthAwarePaginator` corresponds to the `paginate` method.
79 |
80 | When manually creating a paginator instance, you should manually "slice" the array of results you pass to the paginator. If you're unsure how to do this, check out the [array_slice](http://php.net/manual/en/function.array-slice.php) PHP function.
81 |
82 |
83 | ## Displaying Results In A View
84 |
85 | When you call the `paginate` or `simplePaginate` methods on a query builder or Eloquent query, you will receive a paginator instance. When calling the `paginate` method, you will receive an instance of `Illuminate\Pagination\LengthAwarePaginator`. When calling the `simplePaginate` method, you will receive an instance of `Illuminate\Pagination\Paginator`. These objects provide several methods that describe the result set. In addition to these helpers methods, the paginator instances are iterators and may be looped as an array.
86 |
87 | So, once you have retrieved the results, you may display the results and render the page links using [Blade](/docs/{{version}}/blade):
88 |
89 |
90 | @foreach ($users as $user)
91 | {{ $user->name }}
92 | @endforeach
93 |
94 |
95 | {!! $users->render() !!}
96 |
97 | The `render` method will render the links to the rest of the pages in the result set. Each of these links will already contain the proper `?page` query string variable. Remember, the HTML generated by the `render` method is compatible with the [Bootstrap CSS framework](https://getbootstrap.com).
98 |
99 | > **Note:** When calling the `render` method from a Blade template, be sure to use the `{!! !!}` echo syntax so the HTML links will not be escaped.
100 |
101 | #### Customizing The Paginator URI
102 |
103 | The `setPath` method allows you to customize the URI used by the paginator when generating links. For example, if you want the paginator to generate links like `http://example.com/custom/url?page=N`, you should pass `custom/url` to the `setPath` method:
104 |
105 | Route::get('users', function () {
106 | $users = App\User::paginate(15);
107 |
108 | $users->setPath('custom/url');
109 |
110 | //
111 | });
112 |
113 | #### Appending To Pagination Links
114 |
115 | You may add to the query string of pagination links using the `appends` method. For example, to append `&sort=votes` to each pagination link, you should make the following call to `appends`:
116 |
117 | {!! $users->appends(['sort' => 'votes'])->render() !!}
118 |
119 | If you wish to append a "hash fragment" to the paginator's URLs, you may use the `fragment` method. For example, to append `#foo` to the end of each pagination link, make the following call to the `fragment` method:
120 |
121 | {!! $users->fragment('foo')->render() !!}
122 |
123 | #### Additional Helper Methods
124 |
125 | You may also access additional pagination information via the following methods on paginator instances:
126 |
127 | - `$results->count()`
128 | - `$results->currentPage()`
129 | - `$results->hasMorePages()`
130 | - `$results->lastPage() (Not available when using simplePaginate)`
131 | - `$results->nextPageUrl()`
132 | - `$results->perPage()`
133 | - `$results->total() (Not available when using simplePaginate)`
134 | - `$results->url($page)`
135 |
136 |
137 | ## Converting Results To JSON
138 |
139 | The Laravel paginator result classes implement the `Illuminate\Contracts\Support\JsonableInterface` contract and expose the `toJson` method, so it's very easy to convert your pagination results to JSON.
140 |
141 | You may also convert a paginator instance to JSON by simply returning it from a route or controller action:
142 |
143 | Route::get('users', function () {
144 | return App\User::paginate();
145 | });
146 |
147 | The JSON from the paginator will include meta information such as `total`, `current_page`, `last_page`, and more. The actual result objects will be available via the `data` key in the JSON array. Here is an example of the JSON created by returning a paginator instance from a route:
148 |
149 | #### Example Paginator JSON
150 |
151 | {
152 | "total": 50,
153 | "per_page": 15,
154 | "current_page": 1,
155 | "last_page": 4,
156 | "next_page_url": "http://laravel.app?page=2",
157 | "prev_page_url": null,
158 | "from": 1,
159 | "to": 15,
160 | "data":[
161 | {
162 | // Result Object
163 | },
164 | {
165 | // Result Object
166 | }
167 | ]
168 | }
169 |
--------------------------------------------------------------------------------
/providers.md:
--------------------------------------------------------------------------------
1 | # Service Providers
2 |
3 | - [Introduction](#introduction)
4 | - [Writing Service Providers](#writing-service-providers)
5 | - [The Register Method](#the-register-method)
6 | - [The Boot Method](#the-boot-method)
7 | - [Registering Providers](#registering-providers)
8 | - [Deferred Providers](#deferred-providers)
9 |
10 |
11 | ## Introduction
12 |
13 | Service providers are the central place of all Laravel application bootstrapping. Your own application, as well as all of Laravel's core services are bootstrapped via service providers.
14 |
15 | But, what do we mean by "bootstrapped"? In general, we mean **registering** things, including registering service container bindings, event listeners, middleware, and even routes. Service providers are the central place to configure your application.
16 |
17 | If you open the `config/app.php` file included with Laravel, you will see a `providers` array. These are all of the service provider classes that will be loaded for your application. Of course, many of them are "deferred" providers, meaning they will not be loaded on every request, but only when the services they provide are actually needed.
18 |
19 | In this overview you will learn how to write your own service providers and register them with your Laravel application.
20 |
21 |
22 | ## Writing Service Providers
23 |
24 | All service providers extend the `Illuminate\Support\ServiceProvider` class. This abstract class requires that you define at least one method on your provider: `register`. Within the `register` method, you should **only bind things into the [service container](/docs/{{version}}/container)**. You should never attempt to register any event listeners, routes, or any other piece of functionality within the `register` method.
25 |
26 | The Artisan CLI can easily generate a new provider via the `make:provider` command:
27 |
28 | php artisan make:provider RiakServiceProvider
29 |
30 |
31 | ### The Register Method
32 |
33 | As mentioned previously, within the `register` method, you should only bind things into the [service container](/docs/{{version}}/container). You should never attempt to register any event listeners, routes, or any other piece of functionality within the `register` method. Otherwise, you may accidently use a service that is provided by a service provider which has not loaded yet.
34 |
35 | Now, let's take a look at a basic service provider:
36 |
37 | app->singleton('Riak\Contracts\Connection', function ($app) {
54 | return new Connection(config('riak'));
55 | });
56 | }
57 | }
58 |
59 | This service provider only defines a `register` method, and uses that method to define an implementation of `Riak\Contracts\Connection` in the service container. If you don't understand how the service container works, check out [its documentation](/docs/{{version}}/container).
60 |
61 |
62 | ### The Boot Method
63 |
64 | So, what if we need to register a view composer within our service provider? This should be done within the `boot` method. **This method is called after all other service providers have been registered**, meaning you have access to all other services that have been registered by the framework:
65 |
66 | composer('view', function () {
82 | //
83 | });
84 | }
85 |
86 | /**
87 | * Register bindings in the container.
88 | *
89 | * @return void
90 | */
91 | public function register()
92 | {
93 | //
94 | }
95 | }
96 |
97 | #### Boot Method Dependency Injection
98 |
99 | We are able to type-hint dependencies for our `boot` method. The [service container](/docs/{{version}}/container) will automatically inject any dependencies you need:
100 |
101 | use Illuminate\Contracts\Routing\ResponseFactory;
102 |
103 | public function boot(ResponseFactory $factory)
104 | {
105 | $factory->macro('caps', function ($value) {
106 | //
107 | });
108 | }
109 |
110 |
111 | ## Registering Providers
112 |
113 | All service providers are registered in the `config/app.php` configuration file. This file contains a `providers` array where you can list the names of your service providers. By default, a set of Laravel core service providers are listed in this array. These providers bootstrap the core Laravel components, such as the mailer, queue, cache, and others.
114 |
115 | To register your provider, simply add it to the array:
116 |
117 | 'providers' => [
118 | // Other Service Providers
119 |
120 | 'App\Providers\AppServiceProvider',
121 | ],
122 |
123 |
124 | ## Deferred Providers
125 |
126 | If your provider is **only** registering bindings in the [service container](/docs/{{version}}/container), you may choose to defer its registration until one of the registered bindings is actually needed. Deferring the loading of such a provider will improve the performance of your application, since it is not loaded from the filesystem on every request.
127 |
128 | To defer the loading of a provider, set the `defer` property to `true` and define a `provides` method. The `provides` method returns the service container bindings that the provider registers:
129 |
130 | app->singleton('Riak\Contracts\Connection', function ($app) {
154 | return new Connection($app['config']['riak']);
155 | });
156 | }
157 |
158 | /**
159 | * Get the services provided by the provider.
160 | *
161 | * @return array
162 | */
163 | public function provides()
164 | {
165 | return ['Riak\Contracts\Connection'];
166 | }
167 |
168 | }
169 |
170 | Laravel compiles and stores a list of all of the services supplied by deferred service providers, along with the name of its service provider class. Then, only when you attempt to resolve one of these services does Laravel load the service provider.
171 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | #Laravel 5.1 中文文档
2 |
3 | ##概述
4 | 这是 Laravel 5.1 文档的中文仓库,由 `laravel-china` 发起并维护这个项目。
5 | 您可在 [laravel-china.org](http://laravel-china.org) 查看在线文档。
6 |
7 | 如果您在阅读的过程中发现问题,欢迎提交 issue 或 pull request。
8 |
9 | ##推广
10 | 您可以在您的朋友圈中推广 [laravel-china.org](http://laravel-china.org) 和 [PHPHub](https://phphub.org)(一个积极向上的 PHP & Laravel 开发者社区) 来支持我们。
--------------------------------------------------------------------------------
/redis.md:
--------------------------------------------------------------------------------
1 | # Redis
2 |
3 | - [Introduction](#introduction)
4 | - [Basic Usage](#basic-usage)
5 | - [Pipelining Commands](#pipelining-commands)
6 | - [Pub / Sub](#pubsub)
7 |
8 |
9 | ## Introduction
10 |
11 | [Redis](http://redis.io) is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain [strings](http://redis.io/topics/data-types#strings), [hashes](http://redis.io/topics/data-types#hashes), [lists](http://redis.io/topics/data-types#lists), [sets](http://redis.io/topics/data-types#sets), and [sorted sets](http://redis.io/topics/data-types#sorted-sets). Before using Redis with Laravel, you will need to install the `predis/predis` package (~1.0) via Composer.
12 |
13 |
14 | ### Configuration
15 |
16 | The Redis configuration for your application is located in the `config/database.php` configuration file. Within this file, you will see a `redis` array containing the Redis servers used by your application:
17 |
18 | 'redis' => [
19 |
20 | 'cluster' => false,
21 |
22 | 'default' => [
23 | 'host' => '127.0.0.1',
24 | 'port' => 6379,
25 | 'database' => 0,
26 | ],
27 |
28 | ],
29 |
30 | The default server configuration should suffice for development. However, you are free to modify this array based on your environment. Simply give each Redis server a name, and specify the host and port used by the server.
31 |
32 | The `cluster` option will tell the Laravel Redis client to perform client-side sharding across your Redis nodes, allowing you to pool nodes and create a large amount of available RAM. However, note that client-side sharding does not handle failover; therefore, is primarily suited for cached data that is available from another primary data store.
33 |
34 | Additionally, you may define an `options` array value in your Redis connection definition, allowing you to specify a set of Predis [client options](https://github.com/nrk/predis/wiki/Client-Options).
35 |
36 | If your Redis server requires authentication, you may supply a password by adding a `password` configuration item to your Redis server configuration array.
37 |
38 | > **Note:** If you have the Redis PHP extension installed via PECL, you will need to rename the alias for Redis in your `config/app.php` file.
39 |
40 |
41 | ## Basic Usage
42 |
43 | You may interact with Redis by calling various methods on the `Redis` [facade](/docs/{{version}}/facades). The `Redis` facade supports dynamic methods, meaning you may call any [Redis command](http://redis.io/commands) on the facade and the command will be passed directly to Redis. In this example, we will call the `GET` command on Redis by calling the `get` method on the `Redis` facade:
44 |
45 | $user]);
65 | }
66 | }
67 |
68 | Of course, as mentioned above, you may call any of the Redis commands on the `Redis` facade. Laravel uses magic methods to pass the commands to the Redis server, so simply pass the arguments the Redis command expects:
69 |
70 | Redis::set('name', 'Taylor');
71 |
72 | $values = Redis::lrange('names', 5, 10);
73 |
74 | Alternatively, you may also pass commands to the server using the `command` method, which accepts the name of the command as its first argument, and an array of values as its second argument:
75 |
76 | $values = Redis::command('lrange', [5, 10]);
77 |
78 | #### Using Multiple Redis Connections
79 |
80 | You may get a Redis instance by calling the `Redis::connection` method:
81 |
82 | $redis = Redis::connection();
83 |
84 | This will give you an instance of the default Redis server. If you are not using server clustering, you may pass the server name to the `connection` method to get a specific server as defined in your Redis configuration:
85 |
86 | $redis = Redis::connection('other');
87 |
88 |
89 | ### Pipelining Commands
90 |
91 | Pipelining should be used when you need to send many commands to the server in one operation. The `pipeline` method accepts one argument: a `Closure` that receives a Redis instance. You may issue all of your commands to this Redis instance and they will all be executed within a single operation:
92 |
93 | Redis::pipeline(function ($pipe) {
94 | for ($i = 0; $i < 1000; $i++) {
95 | $pipe->set("key:$i", $i);
96 | }
97 | });
98 |
99 |
100 | ## Pub / Sub
101 |
102 | Laravel also provides a convenient interface to the Redis `publish` and `subscribe` commands. These Redis commands allow you to listen for messages on a given "channel". You may publish messages to the channel from another application, or even using another programming language, allowing easy communication between applications / processes.
103 |
104 | First, let's setup a listener on a channel via Redis using the `subscribe` method. We will place this method call within an [Artisan command](/docs/{{version}}/artisan) since calling the `subscribe` method begins a long-running process:
105 |
106 | 'bar']));
148 | });
149 |
150 | #### Wildcard Subscriptions
151 |
152 | Using the `psubscribe` method, you may subscribe to a wildcard channel, which is useful for catching all messages on all channels. The `$channel` name will be passed as the second argument to the provided callback `Closure`:
153 |
154 | Redis::psubscribe(['*'], function($message, $channel) {
155 | echo $message;
156 | });
157 |
158 | Redis::psubscribe(['users.*'], function($message, $channel) {
159 | echo $message;
160 | });
161 |
--------------------------------------------------------------------------------
/requests.md:
--------------------------------------------------------------------------------
1 | # HTTP Requests
2 |
3 | - [Accessing The Request](#accessing-the-request)
4 | - [Basic Request Information](#basic-request-information)
5 | - [PSR-7 Requests](#psr7-requests)
6 | - [Retrieving Input](#retrieving-input)
7 | - [Old Input](#old-input)
8 | - [Cookies](#cookies)
9 | - [Files](#files)
10 |
11 |
12 | ## Accessing The Request
13 |
14 | To obtain an instance of the current HTTP request via dependency injection, you should type-hint the `Illuminate\Http\Request` class on your controller constructor or method. The current request instance will automatically be injected by the [service container](/docs/{{version}}/container):
15 |
16 | input('name');
34 |
35 | //
36 | }
37 | }
38 |
39 | If your controller method is also expecting input from a route parameter, simply list your route arguments after your other dependencies. For example, if your route is defined like so:
40 |
41 | Route::put('user/{id}', 'UserController@update');
42 |
43 | You may still type-hint the `Illuminate\Http\Request` and access your route parameter `id` by defining your controller method like the following:
44 |
45 |
68 | ### Basic Request Information
69 |
70 | The `Illuminate\Http\Request` instance provides a variety of methods for examining the HTTP request for your application. The Laravel `Illuminate\Http\Request` extends the `Symfony\Component\HttpFoundation\Request` class. Here are a few more of the useful methods available on this class:
71 |
72 | #### Retrieving The Request URI
73 |
74 | The `path` method returns the request's URI. So, if the incoming request is targeted at `http://domain.com/foo/bar`, the `path` method will return `foo/bar`:
75 |
76 | $uri = $request->path();
77 |
78 | The `is` method allows you to verify that the incoming request URI matches a given pattern. You may use the `*` character as a wildcard when utilizing this method:
79 |
80 | if ($request->is('admin/*')) {
81 | //
82 | }
83 |
84 | To get the full URL, not just the path info, you may use the `url` method on the request instance:
85 |
86 | $url = $request->url();
87 |
88 | #### Retrieving The Request Method
89 |
90 | The `method` method will return the HTTP verb for the request. You may also use the `isMethod` method to verify that the HTTP verb matches a given string:
91 |
92 | $method = $request->method();
93 |
94 | if ($request->isMethod('post')) {
95 | //
96 | }
97 |
98 |
99 | ### PSR-7 Requests
100 |
101 | The PSR-7 standard specifies interfaces for HTTP messages, including requests and responses. If you would like to obtain an instance of a PSR-7 request, you will first need to install a few libraries. Laravel uses the Symfony HTTP Message Bridge component to convert typical Laravel requests and responses into PSR-7 compatible implementations:
102 |
103 | composer require symfony/psr-http-message-bridge
104 |
105 | composer require zendframework/zend-diactoros
106 |
107 | Once you have installed these libraries, you may obtain a PSR-7 request by simply type-hinting the request type on your route or controller:
108 |
109 | use Psr\Http\Message\ServerRequestInterface;
110 |
111 | Route::get('/', function (ServerRequestInterface $request) {
112 | //
113 | });
114 |
115 | If you return a PSR-7 response instance from a route or controller, it will automatically be converted back to a Laravel response instance and be displayed by the framework.
116 |
117 |
118 | ## Retrieving Input
119 |
120 | #### Retrieving An Input Value
121 |
122 | Using a few simple methods, you may access all user input from your `Illuminate\Http\Request` instance. You do not need to worry about the HTTP verb used for the request, as input is accessed in the same way for all verbs.
123 |
124 | $name = $request->input('name');
125 |
126 | You may pass a default value as the second argument to the `input` method. This value will be returned if the requested input value is not present on the request:
127 |
128 | $name = $request->input('name', 'Sally');
129 |
130 | When working on forms with array inputs, you may use "dot" notation to access the arrays:
131 |
132 | $input = $request->input('products.0.name');
133 |
134 | #### Determining If An Input Value Is Present
135 |
136 | To determine if a value is present on the request, you may use the `has` method. The `has` method returns `true` if the value is present **and** is not an empty string:
137 |
138 | if ($request->has('name')) {
139 | //
140 | }
141 |
142 | #### Retrieving All Input Data
143 |
144 | You may also retrieve all of the input data as an `array` using the `all` method:
145 |
146 | $input = $request->all();
147 |
148 | #### Retrieving A Portion Of The Input Data
149 |
150 | If you need to retrieve a sub-set of the input data, you may use the `only` and `except` methods. Both of these methods accept a single `array` as their only argument:
151 |
152 | $input = $request->only('username', 'password');
153 |
154 | $input = $request->except('credit_card');
155 |
156 |
157 | ### Old Input
158 |
159 | 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 services](/docs/{{version}}/validation), it is unlikely you will need to manually use these methods, as some of Laravel's built-in validation facilities will call them automatically.
160 |
161 | #### Flashing Input To The Session
162 |
163 | The `flash` method on the `Illuminate\Http\Request` instance will flash the current input to the [session](/docs/{{version}}/session) so that it is available during the user's next request to the application:
164 |
165 | $request->flash();
166 |
167 | You may also use the `flashOnly` and `flashExcept` methods to flash a sub-set of the request data into the session:
168 |
169 | $request->flashOnly('username', 'email');
170 |
171 | $request->flashExcept('password');
172 |
173 | #### Flash Input Into Session Then Redirect
174 |
175 | Since you often will want to flash input in association with a redirect to the previous page, you may easily chain input flashing onto a redirect using the `withInput` method:
176 |
177 | return redirect('form')->withInput();
178 |
179 | return redirect('form')->withInput($request->except('password'));
180 |
181 | #### Retrieving Old Data
182 |
183 | To retrieve flashed input from the previous request, use the `old` method on the `Request` instance. The `old` method provides a convenient helper for pulling the flashed input data out of the [session](/docs/{{version}}/session):
184 |
185 | $username = $request->old('username');
186 |
187 | Laravel also provides a global `old` helper function. If you are displaying old input within a [Blade template](/docs/{{version}}/blade), it is more convenient to use the `old` helper:
188 |
189 | {{ old('username') }}
190 |
191 |
192 | ### Cookies
193 |
194 | #### Retrieving Cookies From The Request
195 |
196 | 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, you may use the `cookie` method on the `Illuminate\Http\Request` instance:
197 |
198 | $value = $request->cookie('name');
199 |
200 | #### Attaching A New Cookie To A Response
201 |
202 | Laravel provides a global `cookie` helper function which serves as a simple factory for generating new `Symfony\Component\HttpFoundation\Cookie` instances. The cookies may be attached to a `Illuminate\Http\Response` instance using the `withCookie` method:
203 |
204 | $response = new Illuminate\Http\Response('Hello World');
205 |
206 | $response->withCookie(cookie('name', 'value', $minutes));
207 |
208 | return $response;
209 |
210 | To create a long-lived cookie, which lasts for five years, you may use the `forever` method on the cookie factory by first calling the `cookie` helper with no arguments, and then chaining the `forever` method onto the returned cookie factory:
211 |
212 | $response->withCookie(cookie()->forever('name', 'value'));
213 |
214 |
215 | ### Files
216 |
217 | #### Retrieving Uploaded Files
218 |
219 | You may access uploaded files that are included with the `Illuminate\Http\Request` instance using the `file` method. The object returned by the `file` method is an instance of the `Symfony\Component\HttpFoundation\File\UploadedFile` class, which extends the PHP `SplFileInfo` class and provides a variety of methods for interacting with the file:
220 |
221 | $file = $request->file('photo');
222 |
223 | #### Verifying File Presence
224 |
225 | You may also determine if a file is present on the request using the `hasFile` method:
226 |
227 | if ($request->hasFile('photo')) {
228 | //
229 | }
230 |
231 | #### Validating Successful Uploads
232 |
233 | In addition to checking if the file is present, you may verify that there were no problems uploading the file via the `isValid` method:
234 |
235 | if ($request->file('photo')->isValid())
236 | {
237 | //
238 | }
239 |
240 | #### Moving Uploaded Files
241 |
242 | To move the uploaded file to a new location, you should use the `move` method. This method will move the file from its temporary upload location (as determined by your PHP configuration) to a more permanent destination of your choosing:
243 |
244 | $request->file('photo')->move($destinationPath);
245 |
246 | $request->file('photo')->move($destinationPath, $fileName);
247 |
248 | #### Other File Methods
249 |
250 | There are a variety of other methods available on `UploadedFile` instances. Check out the [API documentation for the class](http://api.symfony.com/2.7/Symfony/Component/HttpFoundation/File/UploadedFile.html) for more information regarding these methods.
251 |
--------------------------------------------------------------------------------
/scheduling.md:
--------------------------------------------------------------------------------
1 | # Task Scheduling
2 |
3 | - [Introduction](#introduction)
4 | - [Defining Schedules](#defining-schedules)
5 | - [Schedule Frequency Options](#schedule-frequency-options)
6 | - [Preventing Task Overlaps](#preventing-task-overlaps)
7 | - [Task Output](#task-output)
8 | - [Task Hooks](#task-hooks)
9 |
10 |
11 | ## Introduction
12 |
13 | In the past, developers have generated a Cron entry for each task they need to schedule. However, this is a headache. Your task schedule is no longer in source control, and you must SSH into your server to add the Cron entries. The Laravel command scheduler allows you to fluently and expressively define your command schedule within Laravel itself, and only a single Cron entry is needed on your server.
14 |
15 | Your task schedule is defined in the `app/Console/Kernel.php` file's `schedule` method. To help you get started, a simple example is included with the method. You are free to add as many scheduled tasks as you wish to the `Schedule` object.
16 |
17 | ### Starting The Scheduler
18 |
19 | Here is the only Cron entry you need to add to your server:
20 |
21 | * * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1
22 |
23 | This Cron will call the Laravel command scheduler every minute. Then, Laravel evaluates your scheduled tasks and runs the tasks that are due.
24 |
25 |
26 | ## Defining Schedules
27 |
28 | You may define all of your scheduled tasks in the `schedule` method of the `App\Console\Kernel` class. To get started, let's look at an example of scheduling a task. In this example, we will schedule a `Closure` to be called every day at midnight. Within the `Closure` we will execute a database query to clear a table:
29 |
30 | call(function () {
58 | DB::table('recent_users')->delete();
59 | })->daily();
60 | }
61 | }
62 |
63 | In addition to scheduling `Closure` calls, you may also schedule [Artisan commands](/docs/{{version}}/artisan) and operating system commands. For example, you may use the `command` method to schedule an Artisan command:
64 |
65 | $schedule->command('emails:send --force')->daily();
66 |
67 | The `exec` command may be used to issue a command to the operating system:
68 |
69 | $schedule->exec('node /home/forge/script.js')->daily();
70 |
71 |
72 | ### Schedule Frequency Options
73 |
74 | Of course, there are a variety of schedules you may assign to your task:
75 |
76 | Method | Description
77 | ------------- | -------------
78 | `->cron('* * * * *');` | Run the task on a custom Cron schedule
79 | `->everyMinute();` | Run the task every minute
80 | `->everyFiveMinutes();` | Run the task every five minutes
81 | `->everyTenMinutes();` | Run the task every ten minutes
82 | `->everyThirtyMinutes();` | Run the task every thirty minutes
83 | `->hourly();` | Run the task every hour
84 | `->daily();` | Run the task every day at midnight
85 | `->dailyAt('13:00');` | Run the task every day at 13:00
86 | `->twiceDaily();` | Run the task daily at 1:00 & 13:00
87 | `->weekly();` | Run the task every week
88 | `->monthly();` | Run the task every month
89 |
90 | These methods may be combined with additional constraints to create even more finely tuned schedules that only run on certain days of the week. For example, to schedule a command to run weekly on Monday:
91 |
92 | $schedule->call(function () {
93 | // Runs once a week on Monday at 13:00...
94 | })->weekly()->mondays()->at('13:00');
95 |
96 | Below is a list of the additional schedule constraints:
97 |
98 | Method | Description
99 | ------------- | -------------
100 | `->weekdays();` | Limit the task to weekdays
101 | `->sundays();` | Limit the task to Sunday
102 | `->mondays();` | Limit the task to Monday
103 | `->tuesdays();` | Limit the task to Tuesday
104 | `->wednesdays();` | Limit the task to Wednesday
105 | `->thursdays();` | Limit the task to Thursday
106 | `->fridays();` | Limit the task to Friday
107 | `->saturdays();` | Limit the task to Saturday
108 | `->when(Closure);` | Limit the task based on a truth test
109 |
110 | #### Truth Test Constraints
111 |
112 | The `when` method may be used to limit the execution of a task based on the result of a given truth test. In other words, if the given `Closure` return `true`, the task will execute as long as no other constraining conditions prevent the task from running:
113 |
114 | $schedule->command('emails:send')->daily()->when(function () {
115 | return true;
116 | });
117 |
118 |
119 | ### Preventing Task Overlaps
120 |
121 | By default, scheduled tasks will be run even if the previous instance of the task is still running. To prevent this, you may use the `withoutOverlapping` method:
122 |
123 | $schedule->command('emails:send')->withoutOverlapping();
124 |
125 | In this example, the `emails:send` [Artisan command](/docs/{{version}}/artisan) will be run every minute if it is not already running. The `withoutOverlapping` method is especially useful if you have tasks that vary drastically in their execution time, preventing you from predicting exactly how long a given task will take.
126 |
127 |
128 | ## Task Output
129 |
130 | The Laravel scheduler provides several convenient methods for working with the output generated by scheduled tasks. First, using the `sendOutputTo` method, you may send the output to a file for later inspection:
131 |
132 | $schedule->command('emails:send')
133 | ->daily()
134 | ->sendOutputTo($filePath);
135 |
136 | Using the `emailOutputTo` method, you may e-mail the output to an e-mail address of your choice. Note that the output must first be sent to a file using the `sendOutputTo` method. Also, before e-mailing the output of a task, you should configure Laravel's [e-mail services](/docs/{{version}}/mail):
137 |
138 | $schedule->command('foo')
139 | ->daily()
140 | ->sendOutputTo($filePath)
141 | ->emailOutputTo('foo@example.com');
142 |
143 | > **Note:** The `emailOutputTo` and `sendOutputTo` methods are exclusive to the `command` method and are not supported for `call`.
144 |
145 |
146 | ## Task Hooks
147 |
148 | Using the `before` and `after` methods, you may specify code to be executed before and after the scheduled task is complete:
149 |
150 | $schedule->command('emails:send')
151 | ->daily()
152 | ->before(function () {
153 | // Task is about to start...
154 | })
155 | ->after(function () {
156 | // Task is complete...
157 | });
158 |
159 | #### Pinging URLs
160 |
161 | Using the `pingBefore` and `thenPing` methods, the scheduler can automatically ping a given URL before or after a task is complete. This method is useful for notifying an external service, such as [Laravel Envoyer](https://envoyer.io), that your scheduled task is commencing or complete:
162 |
163 | $schedule->command('emails:send')
164 | ->daily()
165 | ->pingBefore($url)
166 | ->thenPing($url);
167 |
168 | Using either the `pingBefore($url)` or `thenPing($url)` feature requires the Guzzle HTTP library. You can add Guzzle to your project by adding the following line to your `composer.json` file:
169 |
170 | "guzzlehttp/guzzle": "~5.3|~6.0"
171 |
--------------------------------------------------------------------------------
/seeding.md:
--------------------------------------------------------------------------------
1 | # 数据填充(Database: Seeding)
2 |
3 | - [介绍](#introduction)
4 | - [编写填充](#writing-seeders)
5 | - [使用模型工厂](#using-model-factories)
6 | - [调用附加填充](#calling-additional-seeders)
7 | - [执行填充](#running-seeders)
8 |
9 |
10 | ## 介绍(Introduction)
11 |
12 | Laravel 可以简单的使用 seed 类,填充测试数据到数据库。所有的`seed`类存放在`database/seeds`目录下,可以使用任何你想要的类名称,但是应该遵守某些大小写规范,如 `UserTableSeeder` 等等。默认已经有一个 DatabaseSeeder 类。在这个类里,使用 call 方法执行其他的 seed 类,让你控制填充的顺序。
13 |
14 |
15 | ## 编写填充(Writing Seeders)
16 |
17 | 想要创建一个 seeder,你得能在 Laravel 根目录下运行[Artisan 命令](/docs/{{version}}/artisan)才可以。所有的 seeder 被框架成功创建后会放在 `database/seeders` 目录下:
18 |
19 | php artisan make:seeder UserTableSeeder
20 |
21 | 默认的,一个 seeder 类只能包含一个方法:`run`,当你成功运行`db:seed` [Artisan 命令](/docs/{{version}}/artisan)时,这个方法就会被调用了。在 `run` 方法里,你可以插入任何你像要插入的数据到你的数据库
22 | 你可以用[query builder](/docs/{{version}}/queries)或[Eloquent model factories](/docs/{{version}}/testing#model-factories)手动的插入数据。
23 | 例如,我们修改一个安装 Laravel 时默认会在 `database/seeds/` 目录下包含的`DatabaseSeeder`类,我们来为 `run` 方法添加一个数据库插入声明:
24 |
25 | insert([
41 | 'name' => str_random(10),
42 | 'email' => str_random(10).'@gmail.com',
43 | 'password' => bcrypt('secret'),
44 | ]);
45 | }
46 | }
47 |
48 |
49 | ### 使用模型工厂(Using Model Factories)
50 |
51 | 当然,手动指定每一个模型的 seed 的属性是很累的,更好的办法是用[模型工厂](/docs/{{version}}/testing#model-factories)来生成大量的数据库记录。
52 | 首先,回顾下[模型工厂文档](/docs/{{version}}/testing#model-factories)来学会怎么去定义你自己的工厂。一旦你定义好了你的工厂,你可以利用`factory`帮助函数插入数据到你的数据库。
53 | 例如,我们创建50个用户并为每个用户添加一个关系:
54 | For example, let's create 50 users and attach a relationship to each user:
55 |
56 | /**
57 | * Run the database seeds.
58 | *
59 | * @return void
60 | */
61 | public function run()
62 | {
63 | factory('App\User', 50)->create()->each(function($u) {
64 | $u->posts()->save(factory('App\Post')->make());
65 | });
66 | }
67 |
68 |
69 | ### 调用附加填充(Calling Additional Seeders)
70 |
71 | 在 `DatabaseSeeder` 类里面,你可以通过`call` 方法来执行附加的 seed 类。`call`方法允许你将数据库填充 seeder 分开写在不同的文件中,这样就不会出现一个 seeder 文件类文件变的特别大,可以简单的通过 seeder 名称,只运行你想运行的 seeder:
72 |
73 | /**
74 | * Run the database seeds.
75 | *
76 | * @return void
77 | */
78 | public function run()
79 | {
80 | Model::unguard();
81 |
82 | $this->call(UserTableSeeder::class);
83 | $this->call(PostsTableSeeder::class);
84 | $this->call(CommentsTableSeeder::class);
85 | }
86 |
87 |
88 | ## 执行填充(Running Seeders)
89 |
90 | 当你写好你的填充类(seeder),你可以通过Artisan命令 `db:seed` 来填充数据到数据库。默认情况下,`db:seed` 命令会执行 `DatabaseSeeder`,可以使用它来调用其他 seed 类,不过,也可以使用 `--class` 参数指定要单独执行的类:
91 |
92 | php artisan db:seed
93 |
94 | php artisan db:seed --class=UserTableSeeder
95 |
96 | 你也可以使用 `migrate:refresh` 命令填充数据,它会回滚并且再次执行所有迁移,这个命令往往在你彻底重数据库的时候用:
97 |
98 | php artisan migrate:refresh --seed
99 |
--------------------------------------------------------------------------------
/session.md:
--------------------------------------------------------------------------------
1 | # Session
2 |
3 | - [Introduction](#introduction)
4 | - [Basic Usage](#basic-usage)
5 | - [Flash Data](#flash-data)
6 | - [Adding Custom Session Drivers](#adding-custom-session-drivers)
7 |
8 |
9 | ## Introduction
10 |
11 | Since HTTP driven applications are stateless, sessions provide a way to store information about the user across requests. Laravel ships with a variety of session back-ends available for use through a clean, unified API. Support for popular back-ends such as [Memcached](http://memcached.org), [Redis](http://redis.io), and databases is included out of the box.
12 |
13 | ### Configuration
14 |
15 | The session configuration file is stored at `config/session.php`. Be sure to review the well documented options available to you in this file. By default, Laravel is configured to use the `file` session driver, which will work well for many applications. In production applications, you may consider using the `memcached` or `redis` drivers for even faster session performance.
16 |
17 | The session `driver` defines where session data will be stored for each request. Laravel ships with several great drivers out of the box:
18 |
19 |
20 | - `file` - sessions are stored in `storage/framework/sessions`.
21 | - `cookie` - sessions are stored in secure, encrypted cookies.
22 | - `database` - sessions are stored in a database used by your application.
23 | - `memcached` / `redis` - sessions are stored in one of these fast, cached based stores.
24 | - `array` - sessions are stored in a simple PHP array and will not be persisted across requests.
25 |
26 |
27 | > **Note:** The array driver is typically used for running [tests](/docs/{{version}}/testing) to prevent session data from persisting.
28 |
29 | ### Driver Prerequisites
30 |
31 | #### Database
32 |
33 | When using the `database` session driver, you will need to setup a table to contain the session items. Below is an example `Schema` declaration for the table:
34 |
35 | Schema::create('sessions', function ($table) {
36 | $table->string('id')->unique();
37 | $table->text('payload');
38 | $table->integer('last_activity');
39 | });
40 |
41 | You may use the `session:table` Artisan command to generate this migration for you!
42 |
43 | php artisan session:table
44 |
45 | composer dump-autoload
46 |
47 | php artisan migrate
48 |
49 | #### Redis
50 |
51 | Before using Redis sessions with Laravel, you will need to install the `predis/predis` package (~1.0) via Composer.
52 |
53 | ### Other Session Considerations
54 |
55 | The Laravel framework uses the `flash` session key internally, so you should not add an item to the session by that name.
56 |
57 | If you need all stored session data to be encrypted, set the `encrypt` configuration option to `true`.
58 |
59 |
60 | ## Basic Usage
61 |
62 | #### Accessing The Session
63 |
64 | First, let's access the session. We can access the session instance via the HTTP request, which can be type-hinted on a controller method. Remember, controller method dependencies are injected via the Laravel [service container](/docs/{{version}}/container):
65 |
66 | session()->get('key');
85 |
86 | //
87 | }
88 | }
89 |
90 | When you retrieve a value from the session, you may also pass a default value as the second argument to the `get` method. This default value will be returned if the specified key does not exist in the session. If you pass a `Closure` as the default value to the `get` method, the `Closure` will be executed and its result returned:
91 |
92 | $value = $request->session()->get('key', 'default');
93 |
94 | $value = $request->session()->get('key', function() {
95 | return 'default';
96 | });
97 |
98 | If you would like to retrieve all data from the session, you may use the `all` method:
99 |
100 | $data = $request->session()->all();
101 |
102 | You may also use the global `session` PHP function to retrieve and store data in the session:
103 |
104 | Route::get('home', function () {
105 | // Retrieve a piece of data from the session...
106 | $value = session('key');
107 |
108 | // Store a piece of data in the session...
109 | session(['key' => 'value']);
110 | });
111 |
112 | #### Determining If An Item Exists In The Session
113 |
114 | The `has` method may be used to check if an item exists in the session. This method will return `true` if the item exists:
115 |
116 | if ($request->session()->has('users')) {
117 | //
118 | }
119 |
120 | #### Storing Data In The Session
121 |
122 | Once you have access to the session instance, you may call a variety of functions to interact with the underlying data. For example, the `put` method stores a new piece of data in the session:
123 |
124 | $request->session()->put('key', 'value');
125 |
126 | #### Pushing To Array Session Values
127 |
128 | The `push` method may be used to push a new value onto a session value that is an array. For example, if the `user.teams` key contains an array of team names, you may push a new value onto the array like so:
129 |
130 | $request->session()->push('user.teams', 'developers');
131 |
132 | #### Retrieving And Deleting An Item
133 |
134 | The `pull` method will retrieve and delete an item from the session:
135 |
136 | $value = $request->session()->pull('key', 'default');
137 |
138 | #### Deleting Items From The Session
139 |
140 | The `forget` method will remove a piece of data from the session. If you would like to remove all data from the session, you may use the `flush` method:
141 |
142 | $request->session()->forget('key');
143 |
144 | $request->session()->flush();
145 |
146 | #### Regenerating The Session ID
147 |
148 | If you need to regenerate the session ID, you may use the `regenerate` method:
149 |
150 | $request->session()->regenerate();
151 |
152 |
153 | ### Flash Data
154 |
155 | Sometimes you may wish to store items in the session only for the next request. You may do so using the `flash` method. Method stored in the session using this method will only be available during the subsequent HTTP request, and then will be deleted. Flash data is primarily useful for short-lived status messages:
156 |
157 | $request->session()->flash('status', 'Task was successful!');
158 |
159 | If you need to keep your flash data around for even more requests, you may use the `reflash` method, which will keep all of the flash data around for an additional request. If you only need to keep specific flash data around, you may use the `keep` method:
160 |
161 | $request->session()->reflash();
162 |
163 | $request->session()->keep(['username', 'email']);
164 |
165 |
166 | ## Adding Custom Session Drivers
167 |
168 | To add additional drivers to Laravel's session back-end, you may use the `extend` method on the `Session` [facade](/docs/{{version}}/facades). You can call the `extend` method from the `boot` method of a [service provider](/docs/{{version}}/providers):
169 |
170 |
223 | - The `open` method would typically be used in file based session store systems. Since Laravel ships with a `file` session driver, you will almost never need to put anything in this method. You can leave it as an empty stub. It is simply a fact of poor interface design (which we'll discuss later) that PHP requires us to implement this method.
224 | - The `close` method, like the `open` method, can also usually be disregarded. For most drivers, it is not needed.
225 | - The `read` method should return the string version of the session data associated with the given `$sessionId`. There is no need to do any serialization or other encoding when retrieving or storing session data in your driver, as Laravel will perform the serialization for you.
226 | - The `write` method should write the given `$data` string associated with the `$sessionId` to some persistent storage system, such as MongoDB, Dynamo, etc.
227 | - The `destroy` method should remove the data associated with the `$sessionId` from persistent storage.
228 | - The `gc` method should destroy all session data that is older than the given `$lifetime`, which is a UNIX timestamp. For self-expiring systems like Memcached and Redis, this method may be left empty.
229 |
230 |
231 | Once the session driver has been registered, you may use the `mongo` driver in your `config/session.php` configuration file.
232 |
--------------------------------------------------------------------------------
/structure.md:
--------------------------------------------------------------------------------
1 | # Application Structure
2 |
3 | - [Introduction](#introduction)
4 | - [The Root Directory](#the-root-directory)
5 | - [The App Directory](#the-app-directory)
6 | - [Namespacing Your Application](#namespacing-your-application)
7 |
8 |
9 | ## Introduction
10 |
11 | The default Laravel application structure is intended to provide a great starting point for both large and small applications. Of course, you are free to organize your application however you like. Laravel imposes almost no restrictions on where any given class is located - as long as Composer can autoload the class.
12 |
13 |
14 | ## The Root Directory
15 |
16 | The root directory of a fresh Laravel installation contains a variety of folders:
17 |
18 | The `app` directory, as you might expect, contains the core code of your application. We'll explore this folder in more detail soon.
19 |
20 | The `bootstrap` folder contains a few files that bootstrap the framework and configure autoloading, as well as a `cache` folder that contains a few framework generated files for bootstrap performance optimization.
21 |
22 | The `config` directory, as the name implies, contains all of your application's configuration files.
23 |
24 | The `database` folder contains your database migration and seeds. If you wish, you may also use this folder to hold an SQLite database.
25 |
26 | The `public` directory contains the front controller and your assets (images, JavaScript, CSS, etc.).
27 |
28 | The `resources` directory contains your views, raw assets (LESS, SASS, CoffeeScript), and localization files.
29 |
30 | The `storage` directory contains compiled Blade templates, file based sessions, file caches, and other files generated by the framework. This folder is segregated into `app`, `framework`, and `logs` directories. The `app` directory may be used to store any files utilized by your application. The `framework` directory is used to store framework generated files and caches. Finally, the `logs` directory contains your application's log files.
31 |
32 | The `tests` directory contains your automated tests. An example [PHPUnit](https://phpunit.de/) is provided out of the box.
33 |
34 | The `vendor` directory contains your [Composer](https://getcomposer.org) dependencies.
35 |
36 |
37 | ## The App Directory
38 |
39 | The "meat" of your application lives in the `app` directory. By default, this directory is namespaced under `App` and is autoloaded by Composer using the [PSR-4 autoloading standard](http://www.php-fig.org/psr/psr-4/). **You may change this namespace using the `app:name` Artisan command**.
40 |
41 | The `app` directory ships with a variety of additional directories such as `Console`, `Http`, and `Providers`. Think of the `Console` and `Http` directories as providing an API into the "core" of your application. The HTTP protocol and CLI are both mechanisms to interact with your application, but do not actually contain application logic. In other words, they are simply two ways of issuing commands to your application. The `Console` directory contains all of your Artisan commands, while the `Http` directory contains your controllers, filters, and requests.
42 |
43 | The `Jobs` directory, of course, houses the [queueable jobs](/docs/{{version}}/queues) for your application. Jobs may be queued by your application, as well as be run synchronously within the current request lifecycle.
44 |
45 | The `Events` directory, as you might expect, houses [event classes](/docs/{{version}}/events). Events may be used to alert other parts of your application that a given action has occurred, providing a great deal of flexibility and decoupling.
46 |
47 | The `Listeners` directory contains the handler classes for your events. Handlers receive an event and perform logic in response to the event being fired. For example, a `UserRegistered` event might be handled by a `SendWelcomeEmail` listener.
48 |
49 | The `Exceptions` directory contains your application's exception handler and is also a good place to stick any exceptions thrown by your application.
50 |
51 | > **Note:** Many of the classes in the `app` directory can be generated by Artisan via commands. To review the available commands, run the `php artisan list make` command in your terminal.
52 |
53 |
54 | ## Namespacing Your Application
55 |
56 | As discussed above, the default application namespace is `App`; however, you may change this namespace to match the name of your application, which is easily done via the `app:name` Artisan command. For example, if your application is named "SocialNet", you would run the following command:
57 |
58 | php artisan app:name SocialNet
59 |
60 | Of course, you are free to simply use the `App` namespace.
61 |
--------------------------------------------------------------------------------
/views.md:
--------------------------------------------------------------------------------
1 | # Views
2 |
3 | - [Basic Usage](#basic-usage)
4 | - [Passing Data To Views](#passing-data-to-views)
5 | - [Sharing Data With All Views](#sharing-data-with-all-views)
6 | - [View Composers](#view-composers)
7 |
8 |
9 | ## Basic Usage
10 |
11 | Views contain the HTML served by your application and separate your controller / application logic from your presentation logic. Views are stored in the `resources/views` directory.
12 |
13 | A simple view might look something like this:
14 |
15 |
16 |
17 |
18 |
19 | Hello,
20 |
21 |
22 |
23 | Since this view is stored at `resources/views/greeting.php`, we may return it using the global `view` helper function like so:
24 |
25 | Route::get('/', function () {
26 | return view('greeting', ['name' => 'James']);
27 | });
28 |
29 | As you can see, the first argument passed to the `view` helper corresponds to the name of the view file in the `resources/views` directory. The second argument passed to helper is an array of data that should be made available to the view. In this case, we are passing the `name` variable, which is displayed in the view by simply executing `echo` on the variable.
30 |
31 | Of course, views may also be nested within sub-directories of the `resources/views` directory. "Dot" notation may be used to reference nested views. For example, if your view is stored at `resources/views/admin/profile.php`, you may reference it like so:
32 |
33 | return view('admin.profile', $data);
34 |
35 | #### Determining If A View Exists
36 |
37 | If you need to determine if a view exists, you may use the `exists` method after calling the `view` helper with no arguments. This method will return `true` if the view exists on disk:
38 |
39 | if (view()->exists('emails.customer')) {
40 | //
41 | }
42 |
43 | When the `view` helper is called without arguments, an instance of `Illuminate\Contracts\View\Factory` is returned, giving you access to any of the factory's methods.
44 |
45 |
46 | ### View Data
47 |
48 |
49 | #### Passing Data To Views
50 |
51 | As you saw in the previous examples, you may easily pass an array of data to views:
52 |
53 | return view('greetings', ['name' => 'Victoria']);
54 |
55 | When passing information in this manner, `$data` should be an array with key/value pairs. Inside your view, you can then access each value using it's corresponding key, such as ``. As an alternative to passing a complete array of data to the `view` helper function, you may use the `with` method to add individual pieces of data to the view:
56 |
57 | $view = view('greeting')->with('name', 'Victoria');
58 |
59 |
60 | #### Sharing Data With All Views
61 |
62 | Occasionally, you may need to share a piece of data with all views that are rendered by your application. You may do so using the view factory's `share` method. Typically, you would place calls to `share` within a service provider's `boot` method. You are free to add them to the `AppServiceProvider` or generate a separate service provider to house them:
63 |
64 | share('key', 'value');
78 | }
79 |
80 | /**
81 | * Register the service provider.
82 | *
83 | * @return void
84 | */
85 | public function register()
86 | {
87 | //
88 | }
89 | }
90 |
91 |
92 | ## View Composers
93 |
94 | View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location.
95 |
96 | Let's register our view composers within a [service provider](/docs/{{version}}/providers). We'll use the `view` helper to access the underlying `Illuminate\Contracts\View\Factory` contract implementation. Remember, Laravel does not include a default directory for view composers. You are free to organize them however you wish. For example, you could create an `App\Http\ViewComposers` directory:
97 |
98 | composer(
115 | 'profile', 'App\Http\ViewComposers\ProfileComposer'
116 | );
117 |
118 | // Using Closure based composers...
119 | view()->composer('dashboard', function ($view) {
120 |
121 | });
122 | }
123 |
124 | /**
125 | * Register the service provider.
126 | *
127 | * @return void
128 | */
129 | public function register()
130 | {
131 | //
132 | }
133 | }
134 |
135 | Remember, if you create a new service provider to contain your view composer registrations, you will need to add the service provider to the `providers` array in the `config/app.php` configuration file.
136 |
137 | Now that we have registered the composer, the `ProfileComposer@compose` method will be executed each time the `profile` view is being rendered. So, let's define the composer class:
138 |
139 | users = $users;
165 | }
166 |
167 | /**
168 | * Bind data to the view.
169 | *
170 | * @param View $view
171 | * @return void
172 | */
173 | public function compose(View $view)
174 | {
175 | $view->with('count', $this->users->count());
176 | }
177 | }
178 |
179 | Just before the view is rendered, the composer's `compose` method is called with the `Illuminate\Contracts\View\View` instance. You may use the `with` method to bind data to the view.
180 |
181 | > **Note:** All view composers are resolved via the [service container](/docs/{{version}}/container), so you may type-hint any dependencies you need within a composer's constructor.
182 |
183 | #### Attaching A Composer To Multiple Views
184 |
185 | You may attach a view composer to multiple views at once by passing an array of views as the first argument to the `composer` method:
186 |
187 | view()->composer(
188 | ['profile', 'dashboard'],
189 | 'App\Http\ViewComposers\MyViewComposer'
190 | );
191 |
192 | The `composer` method accepts the `*` character as a wildcard, allowing you to attach a composer to all views:
193 |
194 | view()->composer('*', function ($view) {
195 | //
196 | });
197 |
198 | ### View Creators
199 |
200 | View **creators** are very similar to view composers; however, they are fired immediately when the view is instantiated instead of waiting until the view is about to render. To register a view creator, use the `creator` method:
201 |
202 | view()->creator('profile', 'App\Http\ViewCreators\ProfileCreator');
203 |
--------------------------------------------------------------------------------