PHP安装
https://www.php.net/downloads...
composer安装
安装方式
https://getcomposer.org/downl...
配置composer镜像下载地址
//全局配置
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
//全局取消配置
composer config -g --unset repos.packagist
//当前项目
composer config repo.packagist composer https://mirrors.aliyun.com/composer/
//当前项目取消配置
composer config --unset repos.packagist
laravel安装
环境要求
PHP> = 7.2.0
BCMath PHP扩展
Ctype PHP扩展
JSON PHP扩展
Mbstring PHP扩展
OpenSSL PHP扩展
PDO PHP扩展
Tokenizer PHP扩展
XML PHP扩展
通过laravel安装程序
composer global require laravel/installer
laravel new blog
通过composer创建项目
composer create-project --prefer-dist laravel/laravel blog
启动本地服务器
php artisan serve
目录结构
根目录下的各个目录
app
:应用程序核心目录,几乎项目所有的类都在这里。
bootstrap
:包含框架启动文件 app.php
,和启动时为了优化性能而生成的文件。
config
:包含所有配置文件。最好是读一遍这些文件,了解你可以轻松配置哪些内容。
database
:包含数据库填充、迁移、模型工厂文件。可以用作 SQLite
数据库存放目录。
public
:静态资源目录,并包含了首页文件 index.php
。
resource
:包含了未编译的源文件(模板、语言、资源)。
routes
:包含了所有的路由定义。
storage
:包含了编译好的模板文件,session 文件,缓存文件,日志等文件。
tests
:包含了自动测试文件。运行测试命令 php vendor/bin/phpunit
。
vendor
:composer
依赖目录。
app
目录下的各个目录
app 目录下的很多目录是命令生成的。由 Composer 使用 PSR-4 自动加载标准自动加载。
查看生成命令:php artisan make:list
。
Broadcasting
:包含所有 broadcast channel 类。
Console
:包含自定义的命令和用来注册命令、定义计划任务的内核文件。
Events
:事件目录。
Exceptions
:异常和异常处理目录。
Http
:包含了控制器、中间件和表单请求。几乎所有请求的处理逻辑都被放在这里。
Jobs
:储存队列任务。
Listeners
:存储事件的监听。
Mail
:存储邮件类目录。
Notifications
:存放通知类。laravel 内置了很多驱动: email, Slack, SMS, database。
Policies
:授权策略类目录。
Providers
:包含了所有服务提供者。服务提供者通过在服务容器上绑定服务、注册事件或者执行其他任务来启动你的应用。
Rules
:储存自定义验证规则对象。
routes
目录下的各个目录
web.php
内的路由将应用 web
中间件组(功能:session 状态,CSRF 保护,cookie 加密等)。
api.php
内的路由将应用 api
中间件组(功能:访问速率控制等)。所有的请求将通过 token 认证,无 session 状态。
consoles.php
定义了所有基于控制台命令的闭包。
channels.php
注册了所有的事件广播频道。
WEB服务器配置
apache
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
nginx
location / {
try_files $uri $uri/ /index.php?$query_string;
}
配置
配置目录 config
环境配置
.env
文件内的变量会被系统级别或服务器级别的变量覆盖。
有空格的值请用双引号包含起来 APP_NAME="My Application"
.env
文件内的变量通过env()
函数获取,config
目录下的变量通过config()
函数获取
在运行PHPUnit
测试时或执行以--env=testing
为选项Artisan
命令时,.env.testing
会覆盖 .env
文件中的值。
$environment = App::environment();
if (App::environment('local')) {
// 环境是 local
}
if (App::environment(['local', 'staging'])) {
// 环境是 local 或 staging...
}
隐藏 debug 页面中的环境变量
# config/app.php
return [
// ...
'debug_blacklist' => [
'_ENV' => [
'APP_KEY',
'DB_PASSWORD',
],
'_SERVER' => [
'APP_KEY',
'DB_PASSWORD',
],
'_POST' => [
'password',
],
],
];
设置获取
$value = config('app.timezone'); // 获取
config(['app.timezone' => 'America/Chicago']); // 设置
维护模式
优先加载:resources/views/errors/503.blade.php
php artisan down
php artisan down --message="Upgrading Database" --retry=60
php artisan down --allow=127.0.0.1 --allow=192.168.0.0/16`
//退出应用程序的维护模式
php artisan up
请求生命周期
所有请求必定首先通过 public/index.php
首先加载composer自动加载文件,然后在bootstrap/app.php
实例化一个基础服务容器
框架会将所有的请求传送到HTTP / Console 内核app/Http/Kernel.php
和app/Console/Kernel.php
app/Http/Kernel.php
继承Illuminate\Foundation\Http\Kernel
,在请求被执行之前执行,主要是配置错误处理,日志,检查环境,已经其他请求被处理前需执行的任务,比如:HTTP中间件,会话管理,CSRF令牌等
Illuminate\Foundation\Http\Kernel
获取一个 Request
,返回一个 Response
应用程序所有服务提供程序都在config/app.php
配置文件的 providers
数组中配置。
首先将在所有的提供程序上调用register方法,然后一旦所有提供程序都已经注册号,将调用boot方法。一旦应用程序被引导,Request
将被传递给 router
以进行分派。 router
会将请求分派给路由或控制器,以及运行任何路由特定的中间件。
服务容器
服务容器中的绑定,解析,解析事件
绑定
基础绑定
$this->app->bind('redis.connection', function ($app) {
return $app['redis']->connection();
});
单例绑定
$this->app->singleton('redis', function ($app) { $config = $app->make('config')->get('database.redis', []);
return new RedisManager($app, Arr::pull($config, 'client', 'predis'), $config);
});
实例绑定
$api = new HelpSpot\API(new HttpClient);
$this->app->instance('HelpSpot\API', $api);
给实例初始值
$this->app->when('App\Http\Controllers\UserController')
->needs('$variableName')
->give($value);
接口绑定
$this->app->bind(
'App\Contracts\EventPusher',
'App\Services\RedisEventPusher'
);
根据上下文提供不同的绑定
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\PhotoController;
use App\Http\Controllers\VideoController;
use Illuminate\Contracts\Filesystem\Filesystem;
$this->app->when(PhotoController::class)
->needs(Filesystem::class)
->give(function () {
return Storage::disk('local');
});
$this->app->when([VideoController::class, UploadController::class])
->needs(Filesystem::class)
->give(function () {
return Storage::disk('s3');
});
给绑定设置标签
$this->app->bind('SpeedReport', function () {
//
});
$this->app->bind('MemoryReport', function () {
//
});
$this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');
通过 tagged
方法轻松地解析它们
$this->app->bind('ReportAggregator', function ($app) {
return new ReportAggregator($app->tagged('reports'));
});
扩展绑定
extend
方法可以修改已解析的服务。
$this->app->extend(Service::class, function ($service) {
return new DecoratedService($service);
});
解析实例
基础解析
$api = $this->app->make('HelpSpot\API');
//无法访问$app时,调用resolve函数
$api = resolve('HelpSpot\API');
//解析时候通过关联数组注入依赖
$api = $this->app->makeWith('HelpSpot\API', ['id' => 1]);
容器事件
服务容器每次解析对象会触发一个事件,你可以使用 resolving
方法监听这个事件 :
//容器解析任何对象时调用
$this->app->resolving(function ($object, $app) {
// Called when container resolves object of any type...
});
//容器解析HelpSpot\API时调用
$this->app->resolving(HelpSpot\API::class, function ($api, $app) {
// Called when container resolves objects of type "HelpSpot\API"...
});
服务提供者
加载服务提供者是框架启动的关键步骤之一,它主要负责启动不同的组件(数据库、队列、验证、路由等),服务提供者被配置在config/app.php
中的providers
数组中
所有的服务器都继承Illuminate\Support\ServiceProvider
类,其中该类包含一个register
和boot
方法,其中register
方法中,只需要将服务绑定到服务容器中
制作一个服务提供者
通过artisan
命令行工具make:provider
生成一个新的提供者
php artisan make:provider RiakServiceProvider
服务提供者主要由两个方法:register
和 boot
。register
只负责绑定一些东西到容器。boot
可以使用类型提示解析等来完成任意你想做的事情,这些都归功于容器调用所有服务提供者的register
方法之后才去调用boot
方法。
在config/app.php
的providers
数组中注册服务提供者。
制作一个延迟服务提供者
如果你的服务提供者只在服务容器中注册,可以选着延迟加载该绑定直到注册绑定的服务真的需要时在加载,延迟加载这样的提供者提升应用的性能,因为它不是每次都在请求的时候进入加载
要延迟加载提供者,需要实现 \Illuminate\Contracts\Support\DeferrableProvider
接口并置一个 provides
方法。这个 provides
方法返回该提供者注册的服务容器绑定:
app->singleton(Connection::class, function ($app) {
return new Connection($app['config']['riak']);
});
}
/**
* 获取由提供者提供的服务。
*
* @return array
*/
public function provides()
{
return [Connection::class];
}
}
Facades
Facades原理
在 Laravel 应用中,Facade 就是一个可以从容器访问对象的类。其中核心的部件就是 Facade
类。不管是 Laravel 自带的 Facades,还是自定义的 Facades,都继承自 Illuminate\Support\Facades\Facade
类。Facade
基类使用了__callStatic()
魔术方法,直到对象从容器中被解析出来后,才会进行调用。
use Illuminate\Support\Facades\Cache;
Route::get('/cache', function () {
return Cache::get('key');
});
原生用法 vs 实时用法
# 原生用法
use App\Contracts\Publisher;
public function publish(Publisher $publisher)
{
$this->update(['publishing' => now()]);
$publisher->publish($this);
}
# 实时用法
use Facades\App\Contracts\Publisher;
Publisher::publish($this);
facades 列表
契约
契约和 Facades 均可以用来构建健壮的、充分测试过的 Laravel 应用。
缓存实现的高耦合代码
cache = $cache;
}
/**
* 根据 ID 获取订单
*
* @param int $id
* @return Order
*/
public function find($id)
{
if ($this->cache->has($id)) {
//
}
}
}