PHP学习心得


IOC容器及Facade 深度解析

<h2>IOC</h2> <ul> <li>英文全称:Inversion of Control,</li> <li>中文名称:控制反转,它还有个名字叫依赖注入(Dependency Injection,简称DI)。</li> </ul> <h2>单例模式</h2> <ul> <li>在一个进程里边,请求一次,不管使用多少次,只实例化一次,</li> <li>解决在全局中创建唯一的一个全局实例</li> <li>getInstance() thinkphp/library/think/Container.php</li> </ul> <h2>工厂模式</h2> <ul> <li>多个对象有同一个方法,再通过一个新的对象调用多个对象中的相同方法</li> <li>如:解决配置文件调用不同类型时,如json、xml等,有利于扩展和维护,不需要在业务层改代码,只需要在底层增加代码</li> <li>factory() thinkphp/library/think/Loader.php</li> </ul> <h2>注册树模式</h2> <ul> <li>将对象实例注册到一棵全局的对象树上,需要的时候从对象树上采摘下来使用</li> <li>解决常用的一些类库挂载到注册树上,用到某个类时,不需要new,直接从注册树上获取到一个内容</li> <li>容器就是用到了注册树的思想 <ul> <li><a href="https://www.cnblogs.com/sgm4231/p/9849836.html">https://www.cnblogs.com/sgm4231/p/9849836.html</a></li> </ul></li> </ul> <h2>依赖注入和控制反转</h2> <ul> <li> <p>可以理解为同一个东西,是编程的一种思想,主要目的是减少代码之间的耦合,有效分离对象和它所需的外部资源</p> <h2>依赖注入代码示例</h2> </li> <li><a href="https://www.cnblogs.com/phpper/p/6716375.html">https://www.cnblogs.com/phpper/p/6716375.html</a></li> </ul> <pre><code class="language-PHP">&lt;?php class Person { /** * 依赖:Person类依赖于Car类 * 注入:Car类注入到Pseron类中 */ public function buy($obj) { return $obj-&gt;pay(); } } class Car { public function pay() { return 50000; } } class Iphone { public function pay() { return 6600; } } $Person = new Person(); // echo $Person-&gt;buy(new Car()) . PHP_EOL; // echo $Person-&gt;buy(new Iphone()) . PHP_EOL;</code></pre> <h2>反射机制</h2> <ul> <li>在php5.0版本以后,增加反射机制特性</li> <li>反射机制提供一个强大的反射api,允许在php运行环境中,去访问和使用类的方法、属性、参数和注释,这些都可以获取到</li> <li>经常使用在高扩展的php框架,自动加载插件,自动生成文档。甚至可以扩展php语言</li> <li>手册位置 函数参考-&gt;变量与类型相关扩展-&gt;反射</li> </ul> <h2>反射机制代码示例</h2> <pre><code class="language-PHP">&lt;?php class A { public $aa = 1; private $bb = 2; public static $instance = null; /** * A类的abc方法 * @param $a * @param $b * @return string */ public function adc($a, $b) { return 'abcd'; } /** * type方法 * @param int $type * @return string */ public function mf($type = 1) { return 'type:' . $type; } } // 正常实例化操作 $A = new A(); //var_dump($A); // 使用反射类 $ReflectionClass = new ReflectionClass($A); $newInstance = $ReflectionClass-&gt;newInstance(); // 相当于实例化这个类 $getMethods = $ReflectionClass-&gt;getMethods(); // 获取类中的所有方法 $getMethods = $ReflectionClass-&gt;getMethods(); foreach ($getMethods as $method) { // 获取类中的所有注释 // var_dump($method-&gt;getDocComment()); } $getProperties = $ReflectionClass-&gt;getProperties(); // 获取类中的所有属性,公有和私有的 </code></pre> <h2>玩转自己的容器类</h2> <ul> <li>thinkphp/library/think/Container.php</li> </ul> <h2>代码示例</h2> <pre><code class="language-PHP">class Person { public function __construct(Car $obj, $a = 12) { $this-&gt;obj = $obj; $this-&gt;a = $a; } public function buy() { return $this-&gt;a . ' | ' . $this-&gt;obj -&gt;pay(); } } class Car { public function pay() { return 50000; } } class Container { protected $instances = []; // 存放容器的数据 protected static $instance; // 容器中的对象实例 private function __construct() {} /** * 获取当前容器的实例(单例) */ public static function getInstance() { if (is_null(static::$instance)) { static::$instance = new static; } return static::$instance; } public function get($key) { if (!empty($this-&gt;instances[$key])) { $key = $this-&gt;instances[$key]; } $ReflectionClass = new ReflectionClass($key); // 获取构造函数 $getConstructor = $ReflectionClass-&gt;getConstructor(); if (!$getConstructor) { return new $key; } // 获取参数 $getParameters = $getConstructor-&gt;getParameters(); // 无参数,直接实例化 if (empty($getParameters)) { return new $key; } foreach ($getParameters as $parameter) { $getClass = $parameter-&gt;getClass(); if (!$getClass) { } else { $args[] = $this-&gt;get($getClass-&gt;name); } } return $ReflectionClass-&gt;newInstanceArgs($args); } public function set($key, $value) { $this-&gt;instances[$key] = $value; } } Container::getInstance()-&gt;set('Person', 'Person'); $Person = Container::getInstance()-&gt;get('Person'); $buy = $Person-&gt;buy(); // var_dump($buy); </code></pre> <h2>Countable 巧用</h2> <ul> <li>Countable::count — 统计一个对象的元素个数</li> <li>php手册位置-&gt;函数参考-&gt;其他基本扩展-&gt;SPL-&gt;接口-&gt;Countable</li> </ul> <h2>Countable代码示例</h2> <pre><code class="language-PHP">class TestCountable implements Countable { public function count() { return 1234; } } $TestCountable = new TestCountable(); // $count = $TestCountable-&gt;count(); // var_dump(count($TestCountable)); </code></pre> <h2>门面模式</h2> <ul> <li>门面为容器中的类提供了一个静态调用接口,相比于传统的静态方法调用,带来了更好的可测试性和扩展性</li> <li>门面模式结合容器思想,静态调用。门面模式的好处是通类的静态调用一些方法</li> <li>父类 thinkphp/library/think/Facade.php</li> <li>子类 thinkphp/library/think/facade</li> </ul> <pre><code class="language-php">class TestCallStatic { /** * 当调用的静态方法不存在或权限不足时,会自动调用__callStatic方法。 */ public static function __callStatic($callback, array $param_arr) { var_dump($callback); // getInfo var_dump($param_arr); // array('100', 'zhangsan'); } } TestCallStatic::getInfo('100', 'zhangsan');</code></pre> <h2>自定义门面模式实例</h2> <ul> <li>application/common/Facadetest.php</li> </ul> <pre><code class="language-php">namespace app\common; class Facadetest { public function getInfo() { return __METHOD__; } } // application/facade/Facadetest.php namespace app\facade; use think\Facade; class Facadetest extends Facade { // 从thinkphp/library/think/facade/目录中复制文件修改 protected static function getFacadeClass() { return '\app\common\Facadetest'; //没有绑定类的别名,所以要返回全的命名空间 } }</code></pre> <ul> <li>application/index/controller/Index.php</li> </ul> <pre><code class="language-php">namespace app\index\controller; class Index { public function facadeTest() { echo \app\facade\Facadetest::getInfo(); } }</code></pre> <h2>自定义门面模式实例-绑定</h2> <ul> <li>application/common/Facadebindtest.php</li> </ul> <pre><code class="language-php">namespace app\common; class Facadebindtest { public function getInfo() { return __METHOD__; } } // application/facade/Facadebindtest.php namespace app\facade; use think\Facade; class Facadebindtest extends Facade { } // application/index/controller/Index.php namespace app\index\controller; class Index { public function facadeBindTest() { \think\facade::bind('app\facade\Facadebindtest', 'app\common\Facadebindtest'); echo \app\facade\Facadebindtest::getInfo(); } }</code></pre>

页面列表

ITEM_HTML