此文參考PHP容器--Pimple運行流程淺析 和 利用 Composer 一步一步構建本身的 PHP 框架,若有不清楚的,請參考原文。php
Pimple貌似在PHP社區裏很是流行,聽聞是個很是輕量化而且好用的iOC容器。以想着在項目中運用的目的,今天來研究一番。html
先來搭建個簡單的php環境吧,參照着上面提到的用Composer搭建,路由使用macaw,建立了一個BaseController、IndexController、User、UserServiceProvider。其中BaseController繼承了Container容器,在參考的原文裏是在App類中的。下面一個個來說一下。<?phpnamespace App\Controllers;框架
/** * Created by PhpStorm. * User: hackcat * Date: 2017/7/1 * Time: 下午2:11 */ class BaseController extends \Pimple\Container {
//服務提供中,全部提供者都在這裏填寫,demo中只涉及到了UserService,固然還有Route啥的。 protected $providers = [ UserServiceProvider::class ]; public function __construct() { parent::__construct();
//構造函數中調用註冊提供者方法。 $this->registerProviders(); } public function addProvider($provider){ array_push($this->providers,$provider); return $this; } public function setProviders($providers){ $this->providers = []; foreach ($providers as $provider){ $this->addProvider($provider); } } public function getProviders(){ return $this->providers; } public function __get($id) { return $this->offsetGet($id); } public function __set($id, $value) { $this->offsetSet($id,$value); }
//循環迭代以前的服務提供者,在Container的register方法中註冊提供者實例,注意,這裏只是提供者實例,而不是User。 private function registerProviders(){
foreach ($this->providers as $provider){ $this->register(new $provider()); } } }
<?phpide
/**
* User服務提供者,須要實現\Pimple\ServiceProviderInterface接口
* Created by PhpStorm. * User: hackcat * Date: 2017/7/1 * Time: 下午2:27 */
class UserServiceProvider implements \Pimple\ServiceProviderInterface {
//這邊實現register方法 public function register(\Pimple\Container $pimple) {
//注意,此處是返回一個匿名函數,而不是返回User的實例,因此不等於 $pimple['user'] = new User();這個等會咱們會在測試程序中獲得驗證。實現一個按需加載,延遲加載的做用。 $pimple['user'] = function($pimple){ return new User(); }; } }
<?php /**
* User類,主要是幾個測試方法和構造函數,用於等下作測試的。 * Created by PhpStorm. * User: hackcat * Date: 2017/7/1 * Time: 下午2:26 */ class User { public $name; public function __construct() { echo 'new User'; } public function sayHello(){ echo 'Hello my name is '.$this->name; } }
<?php /**
* 測試類。 * Created by PhpStorm. * User: hackcat * Date: 2017/7/1 * Time: 下午1:55 */ class IndexController extends BaseController { public function index(){
$user = $this->user; $user->name = 'hackcat'; $user->sayHello(); $user1 = $this->user; echo $user1 === $user; } }
1. 測試1: 函數
class IndexController extends BaseController { public function index(){ } }
界面上不顯示任何文字,表示User類沒有被實例化。
2. 測試2post
public function index(){ $user = $this->user; $user->name = 'hackcat'; $user->sayHello(); } 顯示new UserHello my name is hackcat。表示已建立User對象,而且容器證實OK。
3. 測試3測試
public function index(){ $user = $this->user; $user->name = 'hackcat'; $user->sayHello(); $user1 = $this->user; echo $user1->name; } 再建立一個user1,沒有在此new User,而且名字也是hackcat,說明$user === $user1,是同一個對象,單例模式OK。