🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 实例容器 框架集成了 `Pimple\Container` 容器,并且预注册了部分实例。`app` 方法目前只实现了单例。 使用实例: ```php app('app'); app('redis'); app('logger'); app('event'); ``` app 方法: ```php if (! function_exists('app')) { /** * Get the available container instance. * * @param string $abstract * @param array $parameters * @return mixed|\Mod\Fend\Application */ function app($abstract = null, array $parameters = []) { if (is_null($abstract)) { return Application::getInstance(); } return Application::getInstance()->make($abstract, $parameters); } } ``` 应用实例代码,路径:app/Fend/Application.php ```php <?php namespace App\Fend; use Closure; use Monolog\Logger; use Monolog\Handler\StreamHandler; use InvalidArgumentException; use Pimple\Container as PimpleContainer; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\VarDumper\Cloner\VarCloner; use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\Dumper\ContextProvider\CliContextProvider; use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider; use Symfony\Component\VarDumper\Dumper\HtmlDumper; use Symfony\Component\VarDumper\Dumper\ServerDumper; use Symfony\Component\VarDumper\VarDumper; class Application extends PimpleContainer { /** * The current globally available container (if any). * * @var static */ protected static $instance; /** * The loaded service providers. * * @var array */ protected $loadedProviders = []; /** * Current version * * @var string */ const VERSION = '2.0.0'; /** * Create new container * * @param array $values The parameters or objects. */ public function __construct(array $values = []) { parent::__construct($values); $this->bootstrapContainer(); } /** * Bootstrap the application container. * * @return void */ protected function bootstrapContainer() { static::setInstance($this); $this['app'] = $this; $this[self::class] = $this; //$this->bootDumpServer(); $this->registerEventBindings(); $this->registerRedisBindings(); $this->registerLoggerBindings(); } /** * Set the shared instance of the application. * * @param $container * @return Application */ public static function setInstance($container = null) { return static::$instance = $container; } /** * Set the globally available instance of the application. * * @return static */ public static function getInstance() { if (is_null(static::$instance)) { throw new InvalidArgumentException('Expected a Application'); } return static::$instance; } /** * 绑定 DumpServer */ public function bootDumpServer() { $cloner = new VarCloner(); $fallbackDumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg']) ? new CliDumper() : new HtmlDumper(); $dumper = new ServerDumper('tcp://127.0.0.1:9912', $fallbackDumper, [ 'cli' => new CliContextProvider(), 'source' => new SourceContextProvider(), ]); VarDumper::setHandler(function ($var) use ($cloner, $dumper) { $dumper->dump($cloner->cloneVar($var)); }); } /** * Register container bindings for the application. * * @return void */ protected function registerEventBindings() { $this->bind('events', function(){ return new EventDispatcher(); }); } /** * Register container bindings for the application. * * @return void */ protected function registerRedisBindings() { $this->bind('redis', function(){ return (new \Fend_Cache_Redis())->mc; }); } /** * Register container bindings for the application. * * @return void */ protected function registerLoggerBindings() { $path = date('Ym/'); $backtraceCallable = function($record) { $record['extra'] = array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),3); return $record; }; $this->makeBindLogger('', $path, $backtraceCallable); $this->makeBindLogger('.pay', $path, $backtraceCallable); $this->makeBindLogger('.order', $path, $backtraceCallable); $this->makeBindLogger('.power', $path, $backtraceCallable); $this->makeBindLogger('.goods', $path, $backtraceCallable); $this->makeBindLogger('.packet', $path, $backtraceCallable); $this->makeBindLogger('.notify', $path, $backtraceCallable); $this->makeBindLogger('.studycard', $path, $backtraceCallable); $this->makeBindLogger('.rechargecard', $path, $backtraceCallable); $this->makeBindLogger('.activity', $path, $backtraceCallable); } /** * 创建并绑定日志服务 * * @param $name * @param $path * @param $backtraceCallable */ public function makeBindLogger($name, $path, $backtraceCallable) { $this->bind('logger'.$name, function() use ($name, $path, $backtraceCallable){ $logger = new Logger($name ? substr($name, 1) : 'app'); $logger->pushHandler(new StreamHandler(FD_SYSROOT.'data/logs/'.$path.'app'.$name.'.log', \Monolog\Logger::DEBUG)); $logger->pushProcessor($backtraceCallable); return $logger; }); } /** * Get the version number of the application. * * @return string */ public function version() { return static::VERSION; } /** * Register a service provider with the application. * * @param $provider */ public function registerProvider($provider) { if (! $provider instanceof ServiceProvider) { $provider = new $provider($this); } if (array_key_exists($providerName = get_class($provider), $this->loadedProviders)) { return; } $this->loadedProviders[$providerName] = $provider; if (method_exists($provider, 'register')) { $provider->register(); } if (method_exists($provider, 'boot')) { $provider->boot(); } } /** * Resolve the given type from the container. * * @param string $abstract * @param array $parameters * @return mixed */ public function make($abstract = '', $parameters = []) { if( !$this->has($abstract) ){ $this[$abstract] = function ($container) use ($abstract, $parameters) { $instance = empty($parameters) ? new $abstract : new $abstract(...$parameters); if (method_exists($instance, 'setContainer')) { $instance->setContainer($container); } if (method_exists($instance, 'initialize')) { $instance->initialize(); } return $instance; }; } return $this->get($abstract); } /** * Register a binding with the container. * * @param string $abstract * @param null $concrete * @return $this|void */ public function bind($abstract, $concrete = null) { if ( !$concrete instanceof Closure ) { return; } $this[$abstract] = $concrete; return $this; } /******************************************************************************** * Magic methods for convenience *******************************************************************************/ public function __get($name) { return $this->get($name); } public function __isset($name) { return $this->has($name); } /** * Returns true if the container can return an entry for the given identifier. * Returns false otherwise. * * @param string $id Identifier of the entry to look for. * * @return boolean */ public function has($id) { return $this->offsetExists($id); } /** * Finds an entry of the container by its identifier and returns it. * * @param string $id Identifier of the entry to look for. * * @return mixed */ public function get($id) { if (!$this->offsetExists($id)) { throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); } return $this->offsetGet($id); } } ```