<?php namespace Illuminate\Foundation;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Container\Container;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\ServiceProvider;
use Illuminate\Events\EventServiceProvider;
use Illuminate\Routing\RoutingServiceProvider;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
class Application extends Container implements ApplicationContract, HttpKernelInterface {
/**
* The Laravel framework version.
*
* @var string
*/
const VERSION = '5.0.33';
/**
* The base path for the Laravel installation.
* 安装 Laravel 的基础路径(根目录)。
*
* @var string
*/
protected $basePath;
/**
* Indicates if the application has been bootstrapped before.
* 指示应用程序在此前是否已经被引导。
*
* @var bool
*/
protected $hasBeenBootstrapped = false;
/**
* Indicates if the application has "booted".
* 应用程序启动标记。
*
* @var bool
*/
protected $booted = false;
/**
* The array of booting callbacks.
* 存储 booting 回调的数组。
*
* @var array
*/
protected $bootingCallbacks = array();
/**
* The array of booted callbacks.
* 存储 booted 回调的数组。
*
* @var array
*/
protected $bootedCallbacks = array();
/**
* The array of terminating callbacks.
* 存储 terminating 回调的数组。
*
* @var array
*/
protected $terminatingCallbacks = array();
/**
* All of the registered service providers.
* 所有已注册的服务提供者。
*
* @var array
*/
protected $serviceProviders = array();
/**
* The names of the loaded service providers.
* 所有已加载的服务提供者。
*
* @var array
*/
protected $loadedProviders = array();
/**
* The deferred services and their providers.
* 需要延迟加载的服务和它的提供者。
*
* @var array
*/
protected $deferredServices = array();
/**
* The custom database path defined by the developer.
*
* @var string
*/
protected $databasePath;
/**
* The custom storage path defined by the developer.
*
* @var string
*/
protected $storagePath;
/**
* Indicates if the storage directory should be used for optimizations.
* 标明 storage 目录是否可用于优化。
*
* @var bool
*/
protected $useStoragePathForOptimizations = false;
/**
* The environment file to load during bootstrapping.
* 在引导时需要加载的环境文件。
*
* @var string
*/
protected $environmentFile = '.env';
/**
* Create a new Illuminate application instance.
* 创建一个新的 Illuminate 应用程序实例。
*
* @param string|null $basePath 应用程序基础路径(根目录)
* @return void
*/
public function __construct($basePath = null)
{
// 注册基础绑定
$this->registerBaseBindings();
// 注册所有的基础服务提供者
// 事件 Illuminate\Events\EventServiceProvider@register
// 路由 Illuminate\Routing\RoutingServiceProvider@register
$this->registerBaseServiceProviders();
// 注册核心类别名
$this->registerCoreContainerAliases();
// 设置基础路径
if ($basePath) $this->setBasePath($basePath);
}
/**
* Get the version number of the application.
*
* @return string
*/
public function version()
{
return static::VERSION;
}
/**
* Register the basic bindings into the container.
* 在容器中注册基础绑定
*
* @return void
*/
protected function registerBaseBindings()
{
static::setInstance($this); // 将当前容器设置为共享实例
# $this->instance(抽象类, 实例) 在容器中注册共享实例
$this->instance('app', $this);
$this->instance('Illuminate\Container\Container', $this);
}
/**
* Register all of the base service providers.
* 注册所有的基础服务提供者
*
* @return void
*/
protected function registerBaseServiceProviders()
{
// 统一调用服务提供者父类的 __construct() 方法创建服务提供者实例。
// 使用 $this->register(服务提供者实例) 方法进行注册。
// 事件 Illuminate\Events\EventServiceProvider@register
// 注册 events 单例为 Illuminate\Events\Dispatcher 实例
// 且设置队列解析器为 Illuminate\Contracts\Queue\Queue
$this->register(new EventServiceProvider($this));
// 路由 Illuminate\Routing\RoutingServiceProvider@register
// Illuminate\Routing\Router 注册路由实例
// Illuminate\Routing\UrlGenerator 注册 Url 生成器实例
// Illuminate\Routing\Redirector 注册 Redirector(跳转)实例
// Illuminate\Routing\ResponseFactory 注册 Response(响应)实例
$this->register(new RoutingServiceProvider($this));
}
/**
* Run the given array of bootstrap classes.
* 运行给定数组中的引导类。
*
* @param array $bootstrappers
* @return void
*/
public function bootstrapWith(array $bootstrappers)
{
// 标记应用程序为“已引导”
$this->hasBeenBootstrapped = true;
foreach ($bootstrappers as $bootstrapper)
{
// 触发“bootstrapping: Xxx”事件
$this['events']->fire('bootstrapping: '.$bootstrapper, [$this]);
// 实例化引导类,调用其 bootstrap 方法
$this->make($bootstrapper)->bootstrap($this);
// 触发“bootstrapped: Xxx”事件
$this['events']->fire('bootstrapped: '.$bootstrapper, [$this]);
}
}
/**
* Register a callback to run after loading the environment.
*
* @param \Closure $callback
* @return void
*/
public function afterLoadingEnvironment(Closure $callback)
{
return $this->afterBootstrapping(
'Illuminate\Foundation\Bootstrap\DetectEnvironment', $callback
);
}
/**
* Register a callback to run before a bootstrapper.
*
* @param string $bootstrapper
* @param Closure $callback
* @return void
*/
public function beforeBootstrapping($bootstrapper, Closure $callback)
{
$this['events']->listen('bootstrapping: '.$bootstrapper, $callback);
}
/**
* Register a callback to run after a bootstrapper.
*
* @param string $bootstrapper
* @param Closure $callback
* @return void
*/
public function afterBootstrapping($bootstrapper, Closure $callback)
{
$this['events']->listen('bootstrapped: '.$bootstrapper, $callback);
}
/**
* Determine if the application has been bootstrapped before.
* 判断应用程序在此前是否已经被引导。
*
* @return bool
*/
public function hasBeenBootstrapped()
{
return $this->hasBeenBootstrapped;
}
/**
* Set the base path for the application.
* 设置应用程序的基础路径。
*
* @param string $basePath 基础路径
* @return $this
*/
public function setBasePath($basePath)
{
$this->basePath = $basePath;
$this->bindPathsInContainer();
return $this;
}
/**
* Bind all of the application paths in the container.
* 在容器中绑定所有应用程序路径。
*
* @return void
*/
protected function bindPathsInContainer()
{
$this->instance('path', $this->path());
foreach (['base', 'config', 'database', 'lang', 'public', 'storage'] as $path)
{
$this->instance('path.'.$path, $this->{$path.'Path'}());
}
}
/**
* Get the path to the application "app" directory.
* 获取应用程序的“app”目录的路径。
*
* @return string
*/
public function path()
{
return $this->basePath.DIRECTORY_SEPARATOR.'app';
}
/**
* Get the base path of the Laravel installation.
* 获取安装 Laravel 的基础路径(根目录)。
*
* @return string
*/
public function basePath()
{
return $this->basePath;
}
/**
* Get the path to the application configuration files.
* 获取应用程序配置文件路径。
*
* @return string
*/
public function configPath()
{
return $this->basePath.DIRECTORY_SEPARATOR.'config';
}
/**
* Get the path to the database directory.
* 获取到数据库文件目录的路径。
*
* @return string
*/
public function databasePath()
{
return $this->databasePath ?: $this->basePath.DIRECTORY_SEPARATOR.'database';
}
/**
* Set the database directory.
* 设置数据库文件目录。
*
* @param string $path
* @return $this
*/
public function useDatabasePath($path)
{
$this->databasePath = $path;
$this->instance('path.database', $path);
return $this;
}
/**
* Get the path to the language files.
* 获取语言文件路径。
*
* @return string
*/
public function langPath()
{
return $this->basePath.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'lang';
}
/**
* Get the path to the public / web directory.
* 获取网站 public 目录的路径。
*
* @return string
*/
public function publicPath()
{
return $this->basePath.DIRECTORY_SEPARATOR.'public';
}
/**
* Get the path to the storage directory.
* 获取缓存目录路径。
*
* @return string
*/
public function storagePath()
{
return $this->storagePath ?: $this->basePath.DIRECTORY_SEPARATOR.'storage';
}
/**
* Set the storage directory.
* 设置缓存目录。
*
* @param string $path
* @return $this
*/
public function useStoragePath($path)
{
$this->storagePath = $path;
$this->instance('path.storage', $path);
return $this;
}
/**
* Set the environment file to be loaded during bootstrapping.
* 设置引导时需要加载的环境文件。
*
* @param string $file
* @return $this
*/
public function loadEnvironmentFrom($file)
{
$this->environmentFile = $file;
return $this;
}
/**
* Get the environment file the application is using.
* 获取应用程序当前所使用的环境文件。
*
* @return string
*/
public function environmentFile()
{
return $this->environmentFile ?: '.env';
}
/**
* Get or check the current application environment.
* 获取或检测当前应用程序的运行环境。
*
* @param mixed
* @return string
*/
public function environment()
{
if (func_num_args() > 0)
{
$patterns = is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args();
foreach ($patterns as $pattern)
{
if (str_is($pattern, $this['env']))
{
return true;
}
}
return false;
}
return $this['env'];
}
/**
* Determine if application is in local environment.
*
* @return bool
*/
public function isLocal()
{
return $this['env'] == 'local';
}
/**
* Detect the application's current environment.
* 检测应用程序的当前环境。
*
* @param \Closure $callback
* @return string
*/
public function detectEnvironment(Closure $callback)
{
$args = isset($_SERVER['argv']) ? $_SERVER['argv'] : null;
return $this['env'] = (new EnvironmentDetector())->detect($callback, $args);
}
/**
* Determine if we are running in the console.
*
* @return bool
*/
public function runningInConsole()
{
return php_sapi_name() == 'cli';
}
/**
* Determine if we are running unit tests.
*
* @return bool
*/
public function runningUnitTests()
{
return $this['env'] == 'testing';
}
/**
* Register all of the configured providers.
* 注册 providers 配置项中的所有服务提供者。
*
* @return void
*/
public function registerConfiguredProviders()
{
$manifestPath = $this->getCachedServicesPath();
(new ProviderRepository($this, new Filesystem, $manifestPath))
->load($this->config['app.providers']);
}
/**
* Register a service provider with the application.
* 在应用程序中注册一个服务提供者
*
* @param \Illuminate\Support\ServiceProvider|string $provider
* @param array $options
* @param bool $force
* @return \Illuminate\Support\ServiceProvider
*/
public function register($provider, $options = array(), $force = false)
{
// 若存在,则获取已注册的服务提供者实例
if ($registered = $this->getProvider($provider) && ! $force)
{
return $registered;
}
// If the given "provider" is a string, we will resolve it, passing in the
// application instance automatically for the developer. This is simply
// a more convenient way of specifying your service provider classes.
if (is_string($provider))
{
// 解析类名,获得服务提供者实例
$provider = $this->resolveProviderClass($provider);
}
// 调用各服务提供者类的 register 方法
$provider->register();
// Once we have registered the service we will iterate through the options
// and set each of them on the application so they will be available on
// the actual loading of the service objects and for developer usage.
foreach ($options as $key => $value)
{
$this[$key] = $value;
}
// 标记给定的服务提供者实例为“已注册”。
$this->markAsRegistered($provider);
// If the application has already booted, we will call this boot method on
// the provider class so it has an opportunity to do its boot logic and
// will be ready for any usage by the developer's application logics.
// 若应用程序已启动
if ($this->booted)
{
// 启动给定的服务提供者
// 调用各服务提供者类的 boot 方法
$this->bootProvider($provider);
}
return $provider;
}
/**
* Get the registered service provider instance if it exists.
* 若存在,则获取已注册的服务提供者实例。
*
* @param \Illuminate\Support\ServiceProvider|string $provider
* @return \Illuminate\Support\ServiceProvider|null
*/
public function getProvider($provider)
{
$name = is_string($provider) ? $provider : get_class($provider);
return array_first($this->serviceProviders, function($key, $value) use ($name)
{
return $value instanceof $name;
});
}
/**
* Resolve a service provider instance from the class name.
* 解析一个类名,获得服务提供者实例。
*
* @param string $provider
* @return \Illuminate\Support\ServiceProvider
*/
public function resolveProviderClass($provider)
{
return new $provider($this);
}
/**
* Mark the given provider as registered.
* 标记给定的服务提供者实例为“已注册”。
*
* @param \Illuminate\Support\ServiceProvider
* @return void
*/
protected function markAsRegistered($provider)
{
$this['events']->fire($class = get_class($provider), array($provider));
$this->serviceProviders[] = $provider;
$this->loadedProviders[$class] = true;
}
/**
* Load and boot all of the remaining deferred providers.
*
* @return void
*/
public function loadDeferredProviders()
{
// We will simply spin through each of the deferred providers and register each
// one and boot them if the application has booted. This should make each of
// the remaining services available to this application for immediate use.
foreach ($this->deferredServices as $service => $provider)
{
$this->loadDeferredProvider($service);
}
$this->deferredServices = array();
}
/**
* Load the provider for a deferred service.
*
* @param string $service
* @return void
*/
public function loadDeferredProvider($service)
{
if ( ! isset($this->deferredServices[$service]))
{
return;
}
$provider = $this->deferredServices[$service];
// If the service provider has not already been loaded and registered we can
// register it with the application and remove the service from this list
// of deferred services, since it will already be loaded on subsequent.
if ( ! isset($this->loadedProviders[$provider]))
{
$this->registerDeferredProvider($provider, $service);
}
}
/**
* Register a deferred provider and service.
*
* @param string $provider
* @param string $service
* @return void
*/
public function registerDeferredProvider($provider, $service = null)
{
// Once the provider that provides the deferred service has been registered we
// will remove it from our local list of the deferred services with related
// providers so that this container does not try to resolve it out again.
if ($service) unset($this->deferredServices[$service]);
$this->register($instance = new $provider($this));
if ( ! $this->booted)
{
$this->booting(function() use ($instance)
{
$this->bootProvider($instance);
});
}
}
/**
* Resolve the given type from the container.
* 从容器中解析给定类。
*
* (Overriding Container::make)
*
* @param string $abstract 抽象类
* @param array $parameters 参数数组
* @return mixed
*/
public function make($abstract, $parameters = array())
{
// 获取抽象的别名
$abstract = $this->getAlias($abstract);
// 若需延迟加载
if (isset($this->deferredServices[$abstract]))
{
// 调用延迟加载方法
$this->loadDeferredProvider($abstract);
}
// 调用父类 make 方法
return parent::make($abstract, $parameters);
}
/**
* Determine if the given abstract type has been bound.
* 判断给定类型是否已被绑定。
*
* (Overriding Container::bound)
*
* @param string $abstract
* @return bool
*/
public function bound($abstract)
{
// 判断是否为“延迟启动的服务”,或调用父类 bound 方法,判断该抽象类是否为已被绑定
return isset($this->deferredServices[$abstract]) || parent::bound($abstract);
}
/**
* Determine if the application has booted.
*
* @return bool
*/
public function isBooted()
{
return $this->booted;
}
/**
* Boot the application's service providers.
* 启动应用程序的服务提供者。
*
* @return void
*/
public function boot()
{
// 防止重复启动
if ($this->booted) return;
// Once the application has booted we will also fire some "booted" callbacks
// for any listeners that need to do work after this initial booting gets
// finished. This is useful when ordering the boot-up processes we run.
// 触发已绑定的 booting 回调
$this->fireAppCallbacks($this->bootingCallbacks);
array_walk($this->serviceProviders, function($p) {
// 循环调用各服务提供者的 bootProvider 方法
$this->bootProvider($p);
});
// 标记为已启动
$this->booted = true;
// 触发已绑定的 booted 回调
$this->fireAppCallbacks($this->bootedCallbacks);
}
/**
* Boot the given service provider.
* 启动给定的服务提供者。
*
* @param \Illuminate\Support\ServiceProvider $provider
* @return void
*/
protected function bootProvider(ServiceProvider $provider)
{
// 若存在 boot 方法
if (method_exists($provider, 'boot'))
{
// 调用对应的 boot 方法
return $this->call([$provider, 'boot']);
}
}
/**
* Register a new boot listener.
*
* @param mixed $callback
* @return void
*/
public function booting($callback)
{
$this->bootingCallbacks[] = $callback;
}
/**
* Register a new "booted" listener.
*
* @param mixed $callback
* @return void
*/
public function booted($callback)
{
$this->bootedCallbacks[] = $callback;
if ($this->isBooted()) $this->fireAppCallbacks(array($callback));
}
/**
* {@inheritdoc}
*/
public function handle(SymfonyRequest $request, $type = self::MASTER_REQUEST, $catch = true)
{
return $this['Illuminate\Contracts\Http\Kernel']->handle(Request::createFromBase($request));
}
/**
* Determine if the application configuration is cached.
*
* @return bool
*/
public function configurationIsCached()
{
return $this['files']->exists($this->getCachedConfigPath());
}
/**
* Get the path to the configuration cache file.
* 获取配置文件的缓存路径。
*
* @return string
*/
public function getCachedConfigPath()
{
if ($this->vendorIsWritableForOptimizations())
{
return $this->basePath().'/vendor/config.php';
}
else
{
return $this['path.storage'].'/framework/config.php';
}
}
/**
* Determine if the application routes are cached.
*
* @return bool
*/
public function routesAreCached()
{
return $this['files']->exists($this->getCachedRoutesPath());
}
/**
* Get the path to the routes cache file.
*
* @return string
*/
public function getCachedRoutesPath()
{
if ($this->vendorIsWritableForOptimizations())
{
return $this->basePath().'/vendor/routes.php';
}
else
{
return $this['path.storage'].'/framework/routes.php';
}
}
/**
* Get the path to the cached "compiled.php" file.
*
* @return string
*/
public function getCachedCompilePath()
{
if ($this->vendorIsWritableForOptimizations())
{
return $this->basePath().'/vendor/compiled.php';
}
else
{
return $this->storagePath().'/framework/compiled.php';
}
}
/**
* Get the path to the cached services.json file.
*
* @return string
*/
public function getCachedServicesPath()
{
if ($this->vendorIsWritableForOptimizations())
{
return $this->basePath().'/vendor/services.json';
}
else
{
return $this->storagePath().'/framework/services.json';
}
}
/**
* Determine if vendor path is writable.
* 判断 vendor 目录是否可写。
*
* @return bool
*/
public function vendorIsWritableForOptimizations()
{
if ($this->useStoragePathForOptimizations) return false;
return is_writable($this->basePath().'/vendor');
}
/**
* Determines if storage directory should be used for optimizations.
* 确定是否为优化使用 storage 目录。
*
* @param bool $value
* @return $this
*/
public function useStoragePathForOptimizations($value = true)
{
$this->useStoragePathForOptimizations = $value;
return $this;
}
/**
* Call the booting callbacks for the application.
* 触发应用程序的 booting 回调。
*
* @param array $callbacks
* @return void
*/
protected function fireAppCallbacks(array $callbacks)
{
foreach ($callbacks as $callback)
{
call_user_func($callback, $this);
}
}
/**
* Determine if the application is currently down for maintenance.
*
* @return bool
*/
public function isDownForMaintenance()
{
return file_exists($this->storagePath().DIRECTORY_SEPARATOR.'framework'.DIRECTORY_SEPARATOR.'down');
}
/**
* Register a maintenance mode event listener.
*
* @param \Closure $callback
* @return void
*/
public function down(Closure $callback)
{
$this['events']->listen('illuminate.app.down', $callback);
}
/**
* Throw an HttpException with the given data.
*
* @param int $code
* @param string $message
* @param array $headers
* @return void
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*/
public function abort($code, $message = '', array $headers = array())
{
if ($code == 404)
{
throw new NotFoundHttpException($message);
}
throw new HttpException($code, $message, null, $headers);
}
/**
* Register a terminating callback with the application.
*
* @param \Closure $callback
* @return $this
*/
public function terminating(Closure $callback)
{
$this->terminatingCallbacks[] = $callback;
return $this;
}
/**
* Terminate the application.
*
* @return void
*/
public function terminate()
{
foreach ($this->terminatingCallbacks as $terminating)
{
$this->call($terminating);
}
}
/**
* Get the service providers that have been loaded.
*
* @return array
*/
public function getLoadedProviders()
{
return $this->loadedProviders;
}
/**
* Get the application's deferred services.
*
* @return array
*/
public function getDeferredServices()
{
return $this->deferredServices;
}
/**
* Set the application's deferred services.
*
* @param array $services
* @return void
*/
public function setDeferredServices(array $services)
{
$this->deferredServices = $services;
}
/**
* Add an array of services to the application's deferred services.
*
* @param array $services
* @return void
*/
public function addDeferredServices(array $services)
{
$this->deferredServices = array_merge($this->deferredServices, $services);
}
/**
* Determine if the given service is a deferred service.
*
* @param string $service
* @return bool
*/
public function isDeferredService($service)
{
return isset($this->deferredServices[$service]);
}
/**
* Get the current application locale.
*
* @return string
*/
public function getLocale()
{
return $this['config']->get('app.locale');
}
/**
* Set the current application locale.
*
* @param string $locale
* @return void
*/
public function setLocale($locale)
{
$this['config']->set('app.locale', $locale);
$this['translator']->setLocale($locale);
$this['events']->fire('locale.changed', array($locale));
}
/**
* Register the core class aliases in the container.
* 在容器中注册核心类别名
*
* @return void
*/
public function registerCoreContainerAliases()
{
$aliases = array(
'app' => ['Illuminate\Foundation\Application', 'Illuminate\Contracts\Container\Container', 'Illuminate\Contracts\Foundation\Application'],
'artisan' => ['Illuminate\Console\Application', 'Illuminate\Contracts\Console\Application'],
'auth' => 'Illuminate\Auth\AuthManager',
'auth.driver' => ['Illuminate\Auth\Guard', 'Illuminate\Contracts\Auth\Guard'],
'auth.password.tokens' => 'Illuminate\Auth\Passwords\TokenRepositoryInterface',
'blade.compiler' => 'Illuminate\View\Compilers\BladeCompiler',
'cache' => ['Illuminate\Cache\CacheManager', 'Illuminate\Contracts\Cache\Factory'],
'cache.store' => ['Illuminate\Cache\Repository', 'Illuminate\Contracts\Cache\Repository'],
'config' => ['Illuminate\Config\Repository', 'Illuminate\Contracts\Config\Repository'],
'cookie' => ['Illuminate\Cookie\CookieJar', 'Illuminate\Contracts\Cookie\Factory', 'Illuminate\Contracts\Cookie\QueueingFactory'],
'encrypter' => ['Illuminate\Encryption\Encrypter', 'Illuminate\Contracts\Encryption\Encrypter'],
'db' => 'Illuminate\Database\DatabaseManager',
'events' => ['Illuminate\Events\Dispatcher', 'Illuminate\Contracts\Events\Dispatcher'],
'files' => 'Illuminate\Filesystem\Filesystem',
'filesystem' => ['Illuminate\Filesystem\FilesystemManager', 'Illuminate\Contracts\Filesystem\Factory'],
'filesystem.disk' => 'Illuminate\Contracts\Filesystem\Filesystem',
'filesystem.cloud' => 'Illuminate\Contracts\Filesystem\Cloud',
'hash' => 'Illuminate\Contracts\Hashing\Hasher',
'translator' => ['Illuminate\Translation\Translator', 'Symfony\Component\Translation\TranslatorInterface'],
'log' => ['Illuminate\Log\Writer', 'Illuminate\Contracts\Logging\Log', 'Psr\Log\LoggerInterface'],
'mailer' => ['Illuminate\Mail\Mailer', 'Illuminate\Contracts\Mail\Mailer', 'Illuminate\Contracts\Mail\MailQueue'],
'paginator' => 'Illuminate\Pagination\Factory',
'auth.password' => ['Illuminate\Auth\Passwords\PasswordBroker', 'Illuminate\Contracts\Auth\PasswordBroker'],
'queue' => ['Illuminate\Queue\QueueManager', 'Illuminate\Contracts\Queue\Factory', 'Illuminate\Contracts\Queue\Monitor'],
'queue.connection' => 'Illuminate\Contracts\Queue\Queue',
'redirect' => 'Illuminate\Routing\Redirector',
'redis' => ['Illuminate\Redis\Database', 'Illuminate\Contracts\Redis\Database'],
'request' => 'Illuminate\Http\Request',
'router' => ['Illuminate\Routing\Router', 'Illuminate\Contracts\Routing\Registrar'],
'session' => 'Illuminate\Session\SessionManager',
'session.store' => ['Illuminate\Session\Store', 'Symfony\Component\HttpFoundation\Session\SessionInterface'],
'url' => ['Illuminate\Routing\UrlGenerator', 'Illuminate\Contracts\Routing\UrlGenerator'],
'validator' => ['Illuminate\Validation\Factory', 'Illuminate\Contracts\Validation\Factory'],
'view' => ['Illuminate\View\Factory', 'Illuminate\Contracts\View\Factory'],
);
foreach ($aliases as $key => $aliases)
{
foreach ((array) $aliases as $alias)
{
// 在容器的别名数组中存储指定抽象类的别名。
$this->alias($key, $alias);
}
}
}
/**
* Flush the container of all bindings and resolved instances.
*
* @return void
*/
public function flush()
{
parent::flush();
$this->loadedProviders = [];
}
}