569 lines
16 KiB
PHP
Executable File
569 lines
16 KiB
PHP
Executable File
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
|
// +----------------------------------------------------------------------
|
|
// | Author: liu21st <liu21st@gmail.com>
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace think;
|
|
|
|
use ArrayAccess;
|
|
use ArrayIterator;
|
|
use Closure;
|
|
use Countable;
|
|
use InvalidArgumentException;
|
|
use IteratorAggregate;
|
|
use ReflectionClass;
|
|
use ReflectionException;
|
|
use ReflectionFunction;
|
|
use ReflectionMethod;
|
|
use think\exception\ClassNotFoundException;
|
|
|
|
/**
|
|
* @package think
|
|
* @property Build $build
|
|
* @property Cache $cache
|
|
* @property Config $config
|
|
* @property Cookie $cookie
|
|
* @property Debug $debug
|
|
* @property Env $env
|
|
* @property Hook $hook
|
|
* @property Lang $lang
|
|
* @property Middleware $middleware
|
|
* @property Request $request
|
|
* @property Response $response
|
|
* @property Route $route
|
|
* @property Session $session
|
|
* @property Template $template
|
|
* @property Url $url
|
|
* @property Validate $validate
|
|
* @property View $view
|
|
* @property route\RuleName $rule_name
|
|
* @property Log $log
|
|
*/
|
|
class Container implements ArrayAccess, IteratorAggregate, Countable
|
|
{
|
|
/**
|
|
* 容器对象实例
|
|
* @var Container
|
|
*/
|
|
protected static $instance;
|
|
|
|
/**
|
|
* 容器中的对象实例
|
|
* @var array
|
|
*/
|
|
protected $instances = [];
|
|
|
|
/**
|
|
* 容器绑定标识
|
|
* @var array
|
|
*/
|
|
protected $bind = [
|
|
'app' => App::class,
|
|
'build' => Build::class,
|
|
'cache' => Cache::class,
|
|
'config' => Config::class,
|
|
'cookie' => Cookie::class,
|
|
'debug' => Debug::class,
|
|
'env' => Env::class,
|
|
'hook' => Hook::class,
|
|
'lang' => Lang::class,
|
|
'log' => Log::class,
|
|
'middleware' => Middleware::class,
|
|
'request' => Request::class,
|
|
'response' => Response::class,
|
|
'route' => Route::class,
|
|
'session' => Session::class,
|
|
'template' => Template::class,
|
|
'url' => Url::class,
|
|
'validate' => Validate::class,
|
|
'view' => View::class,
|
|
'rule_name' => route\RuleName::class,
|
|
// 接口依赖注入
|
|
'think\LoggerInterface' => Log::class,
|
|
];
|
|
|
|
/**
|
|
* 容器标识别名
|
|
* @var array
|
|
*/
|
|
protected $name = [];
|
|
|
|
/**
|
|
* 获取当前容器的实例(单例)
|
|
* @access public
|
|
* @return static
|
|
*/
|
|
public static function getInstance()
|
|
{
|
|
if (is_null(static::$instance)) {
|
|
static::$instance = new static;
|
|
}
|
|
|
|
return static::$instance;
|
|
}
|
|
|
|
/**
|
|
* 设置当前容器的实例
|
|
* @access public
|
|
* @param object $instance
|
|
* @return void
|
|
*/
|
|
public static function setInstance($instance)
|
|
{
|
|
static::$instance = $instance;
|
|
}
|
|
|
|
/**
|
|
* 获取容器中的对象实例
|
|
* @access public
|
|
* @param string $abstract 类名或者标识
|
|
* @param array|true $vars 变量
|
|
* @param bool $newInstance 是否每次创建新的实例
|
|
* @return object
|
|
*/
|
|
public static function get($abstract, $vars = [], $newInstance = false)
|
|
{
|
|
return static::getInstance()->make($abstract, $vars, $newInstance);
|
|
}
|
|
|
|
/**
|
|
* 绑定一个类、闭包、实例、接口实现到容器
|
|
* @access public
|
|
* @param string $abstract 类标识、接口
|
|
* @param mixed $concrete 要绑定的类、闭包或者实例
|
|
* @return Container
|
|
*/
|
|
public static function set($abstract, $concrete = null)
|
|
{
|
|
return static::getInstance()->bindTo($abstract, $concrete);
|
|
}
|
|
|
|
/**
|
|
* 移除容器中的对象实例
|
|
* @access public
|
|
* @param string $abstract 类标识、接口
|
|
* @return void
|
|
*/
|
|
public static function remove($abstract)
|
|
{
|
|
return static::getInstance()->delete($abstract);
|
|
}
|
|
|
|
/**
|
|
* 清除容器中的对象实例
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public static function clear()
|
|
{
|
|
return static::getInstance()->flush();
|
|
}
|
|
|
|
/**
|
|
* 绑定一个类、闭包、实例、接口实现到容器
|
|
* @access public
|
|
* @param string|array $abstract 类标识、接口
|
|
* @param mixed $concrete 要绑定的类、闭包或者实例
|
|
* @return $this
|
|
*/
|
|
public function bindTo($abstract, $concrete = null)
|
|
{
|
|
if (is_array($abstract)) {
|
|
$this->bind = array_merge($this->bind, $abstract);
|
|
} elseif ($concrete instanceof Closure) {
|
|
$this->bind[$abstract] = $concrete;
|
|
} elseif (is_object($concrete)) {
|
|
if (isset($this->bind[$abstract])) {
|
|
$abstract = $this->bind[$abstract];
|
|
}
|
|
$this->instances[$abstract] = $concrete;
|
|
} else {
|
|
$this->bind[$abstract] = $concrete;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 绑定一个类实例当容器
|
|
* @access public
|
|
* @param string $abstract 类名或者标识
|
|
* @param object|\Closure $instance 类的实例
|
|
* @return $this
|
|
*/
|
|
public function instance($abstract, $instance)
|
|
{
|
|
if ($instance instanceof \Closure) {
|
|
$this->bind[$abstract] = $instance;
|
|
} else {
|
|
if (isset($this->bind[$abstract])) {
|
|
$abstract = $this->bind[$abstract];
|
|
}
|
|
|
|
$this->instances[$abstract] = $instance;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 判断容器中是否存在类及标识
|
|
* @access public
|
|
* @param string $abstract 类名或者标识
|
|
* @return bool
|
|
*/
|
|
public function bound($abstract)
|
|
{
|
|
return isset($this->bind[$abstract]) || isset($this->instances[$abstract]);
|
|
}
|
|
|
|
/**
|
|
* 判断容器中是否存在对象实例
|
|
* @access public
|
|
* @param string $abstract 类名或者标识
|
|
* @return bool
|
|
*/
|
|
public function exists($abstract)
|
|
{
|
|
if (isset($this->bind[$abstract])) {
|
|