laravel学习笔记

PHP安装php

https://www.php.net/downloads...nginx

composer安装

安装方式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

laravel安装

环境要求数据库

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

vendorcomposer 依赖目录。

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.phpapp/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类,其中该类包含一个registerboot方法,其中register方法中,只须要将服务绑定到服务容器中

制做一个服务提供者

经过artisan命令行工具make:provider生成一个新的提供者

php artisan make:provider RiakServiceProvider

服务提供者主要由两个方法:registerbootregister 只负责绑定一些东西到容器。boot 可使用类型提示解析等来完成任意你想作的事情,这些都归功于容器调用全部服务提供者的register方法以后才去调用boot方法。

config/app.phpproviders数组中注册服务提供者。

制做一个延迟服务提供者

若是你的服务提供者只在服务容器中注册,能够选着延迟加载该绑定直到注册绑定的服务真的须要时在加载,延迟加载这样的提供者提高应用的性能,由于它不是每次都在请求的时候进入加载

要延迟加载提供者,须要实现 \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];
    }
}

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 列表

Facade Class Service Container Binding
App IlluminateFoundationApplication app
Artisan IlluminateContractsConsoleKernel artisan
Auth IlluminateAuthAuthManager auth
Auth (Instance) IlluminateContractsAuthGuard auth.driver
Blade IlluminateViewCompilersBladeCompiler blade.compiler
Broadcast IlluminateContractsBroadcastingFactory  
Broadcast (Instance) IlluminateContractsBroadcastingBroadcaster  
Bus IlluminateContractsBusDispatcher  
Cache IlluminateCacheCacheManager cache
Cache (Instance) IlluminateCacheRepository cache.store
Config IlluminateConfigRepository config
Cookie IlluminateCookieCookieJar cookie
Crypt IlluminateEncryptionEncrypter encrypter
DB IlluminateDatabaseDatabaseManager db
DB (Instance) IlluminateDatabaseConnection db.connection
Event IlluminateEventsDispatcher events
File IlluminateFilesystemFilesystem files
Gate IlluminateContractsAuthAccessGate  
Hash IlluminateContractsHashingHasher hash
Lang IlluminateTranslationTranslator translator
Log IlluminateLogLogManager log
Mail IlluminateMailMailer mailer
Notification IlluminateNotificationsChannelManager  
Password IlluminateAuthPasswordsPasswordBrokerManager auth.password
Password (Instance) IlluminateAuthPasswordsPasswordBroker auth.password.broker
Queue IlluminateQueueQueueManager queue
Queue (Instance) IlluminateContractsQueueQueue queue.connection
Queue (Base Class) IlluminateQueueQueue  
Redirect IlluminateRoutingRedirector redirect
Redis IlluminateRedisRedisManager redis
Redis (Instance) IlluminateRedisConnectionsConnection redis.connection
Request IlluminateHttpRequest request
Response IlluminateContractsRoutingResponseFactory  
Response (Instance) IlluminateHttpResponse  
Route IlluminateRoutingRouter router
Schema IlluminateDatabaseSchemaBuilder  
Session IlluminateSessionSessionManager session
Session (Instance) IlluminateSessionStore session.store
Storage IlluminateFilesystemFilesystemManager filesystem
Storage (Instance) IlluminateContractsFilesystemFilesystem filesystem.disk
URL IlluminateRoutingUrlGenerator url
Validator IlluminateValidationFactory validator
Validator (Instance) IlluminateValidationValidator  
View IlluminateViewFactory view
View (Instance) IlluminateViewView

契约

契约和 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;
});
相关文章
相关标签/搜索