PHP安装php
https://www.php.net/downloads...nginx
安装方式laravel
https://getcomposer.org/downl...web
配置composer镜像下载地址redis
//全局配置 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
环境要求数据库
PHP> = 7.2.0 BCMath PHP扩展 Ctype PHP扩展 JSON PHP扩展 Mbstring PHP扩展 OpenSSL PHP扩展 PDO PHP扩展 Tokenizer PHP扩展 XML PHP扩展
经过laravel安装程序apache
composer global require laravel/installer laravel new blog
经过composer建立项目bootstrap
composer create-project --prefer-dist laravel/laravel blog
启动本地服务器api
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
注册了全部的事件广播频道。
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]
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
方法返回该提供者注册的服务容器绑定:
<?php namespace App\Providers; use Riak\Connection; use Illuminate\Support\ServiceProvider; use Illuminate\Contracts\Support\DeferrableProvider; class RiakServiceProvider extends ServiceProvider implements DeferrableProvider { /** * 注册服务提供者。 * * @return void */ public function register() { $this->app->singleton(Connection::class, function ($app) { return new Connection($app['config']['riak']); }); } /** * 获取由提供者提供的服务。 * * @return array */ public function provides() { return [Connection::class]; } }
在 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'); });
# 原生用法 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 都可以用来构建健壮的、充分测试过的 Laravel 应用。
缓存实现的高耦合代码
<?php namespace App\Orders; class Repository { /** * 缓存实例 */ protected $cache; /** * 建立一个新的仓库实例 * * @param \SomePackage\Cache\Memcached $cache * @return void */ public function __construct(\SomePackage\Cache\Memcached $cache) { $this->cache = $cache; } /** * 根据 ID 获取订单 * * @param int $id * @return Order */ public function find($id) { if ($this->cache->has($id)) { // } } }
全部的路由文件都在routers
目录下,
routes/web.php文件定位web界面的路由,被分配给 web
中间件组提供了会话状态和 CSRF 保护等功能
routes/api.php
中的路由都是无状态的,而且被分配了 api
中间件组
路由经过 RouteServiceProvider
被嵌套到一个路由组里面。
Route::get('/', function () { return view('welcome'); });
Route::get('/user', 'UserController@index');
Route::get($uri, $callback); Route::post($uri, $callback); Route::put($uri, $callback); Route::delete($uri, $callback); Route::options($uri, $callback); Route::any($uri, $callback); Route::patch($methods, $uri, $callback);
Route::redirect('/here', '/there'); Route::redirect('/here', '/there', 301); Route::permanentRedirect('/here', '/there');
Route::view('/welcome', 'welcome'); Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
Route::get('user/{id}', function ($id) { return 'User '.$id; }); Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) { // });
Route::get('user/{name?}', function ($name = null) { return $name; }); Route::get('user/{name?}', function ($name = 'John') { return $name; });
Route::get('user/{name}', function ($name) { // })->where('name', '[A-Za-z]+'); Route::get('user/{id}/{name}', function ($id, $name) { // })->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
全局正则匹配配置方式
\app\Providers\RouteServiceProvider.php
文件boot方法中添加
public function boot() { Route::pattern('id', '[0-9]+'); parent::boot(); }
Route::get('user/profile', function () { // })->name('profile'); //生成完整的url $url = route('profile'); //别名路由重定向 return redirect()->route('profile');
Route::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); });
Route::namespace('Admin')->group(function () { // 在 「App\Http\Controllers\Admin」 命名空间下的控制器 });
Route::domain('{account}.zqw.xyz')->group(function () { Route::get('user/{id}', function ($account, $id) { // }); });
Route::prefix('admin')->group(function () { Route::get('users', function () { // 匹配包含 「/admin/users」 的 URL }); });
Route::name('admin.')->group(function () { Route::get('users', function () { // 指定路由名为 「admin.users」... })->name('users'); });
Route::get('api/users/{user}', function (App\User $user) { return $user->email; });