# tp51_study **Repository Path**: liiy250/tp51_study ## Basic Information - **Project Name**: tp51_study - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-05-12 - **Last Updated**: 2024-05-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ##
这是学习thinkphp5.1的学习笔记
### 第一章 类的自动加载 1. ##### 类的自动加载函数 spl_autoload_register() spl.php 文件中新建类 A 调用 方法找不到类。注册自动加载以后当类找不到的时候会去 找到注册好的自动加载类,运行定义好的方法进行自动加载。 A.php文件 ```php class A { public function say() { print("in class A say method" . PHP_EOL); } } ``` spl.php文件 ```php /**注册类的自动加载 */ spl_autoload_register('auto_load',true,true); function auto_load($class_name){ echo '没找到的类名为:'.$class_name.PHP_EOL; require('./'.$class_name.'.php'); } /**类的自动加载 */ $tom = new A(); $tom->say(); ``` 2. ##### get_declared_classes() 获取已经定义的所有的类。(包括当前调用函数的php文件中定义的类。但是后续 通过require 或者 include引入的类 则不会被加载) dec_test.php ```php print_r(get_declared_classes()); include('./C.php'); //这一句放在这里 C类不会加载。需要放在调用方法的前面 class A{ } class B{ } ``` 3. ##### property_exists()方法会判断当前类中是否存在某一个属性。loader.php文件中通过这个方法,将composer类中所有的已经定义的这些属性加载成当前的实例对象属性。 4. ##### extend为扩展目录。extend下面定义的类不需要写命名空间,可以直接在模块中去使用(需要注意类名跟文件名要一致,文件名首字母大写)。里面可以创建扩展工具包。放在目录下的包就需要注册命名空间了。 例如:extend/phpmailer/Sms.php ```php namespace phpmailer; class Sms{ public static function send(){ echo 'mail have send to others'; } } ``` 调用代码 ```php \phpmailer\Sms::send(); ``` 5. ##### 需要扩展extend目录。就需要在 loader.php文件中添加 ```php self::addAutoLoadDir($rootPath . 'xiaoliu'); ``` ### 第二章 解读配置文件 1. ##### ArrayAccess接口 如果你的类实现了ArrayAccess接口,那么这个类的对象就可以使用$foo['xxx']这种结构了。 $foo['xxx'] 对应调用offsetGet方法。 $foo['xxx'] = 'yyy' 对应调用offsetSet方法。 isset($foo['xxx']) 对应调用offsetExists方法。 unset($foo['xxx']) 对应调用offsetUnset方法。 ```php class Person implements \ArrayAccess{ public function offsetExists( $offset ) { echo "这里是 offsetExists() 方法 你输入的参数是 {$offset}"; } public function offsetGet( $offset ) { echo "这里是 offsetGet() 方法 你输入的参数是 $offset"; } public function offsetSet( $offset, $value ) { echo "这里是 offsetSet() 方法 你输入的 {$offset}={$value}"; } public function offsetUnset( $offset ) { echo "这里是 offsetUnset() 方法 你输入的参数是 {$offset}"; } } $xiaoming = new Person(); $t = $xiaoming['name']; //获取值时候 调用offsetGet $xiaoming['name']="小明"; //获取值时候 offsetSet isset($xiaoming['name']); //获取值时候 调用offsetExists unset($xiaoming['name']); //获取值时候 调用offsetGet ``` 2. ##### yaconf高性能配置扩展 如果项目中有很多个配置文件,那么一次次调用配置消耗很大资源。使用yaconf扩展可以一次性的把所有的配置加载到内存中。 1 安装yaconf扩展 可以编译安装,这里使用命令 pecl install yaconf 2 在php.ini文件中指定yaconf需要加载的目录 ```ini extension="yaconf.so" yaconf.directory=/www/wwwroot/my.tp51.com/config ``` config/abc.ini ```ini title="singwa" ``` 3 调用方式1 程序中直接调用获取 ```php $config=\YaConf::get('abc'); $title=\YaConf::get('abc.title'); print_r($config); //打印数组 print_r($title); //打印 singwa ``` 4 调用方式2 来自tp官方 https://www.kancloud.cn/top-think/thinkphp-blog/783762 1)common.php 中添加 ```php think\facade\Config::setYaconf('abc'); ``` 2) 调用数据 助手函数yaconf('config_name', 'default_value') ```php $title = yaconf('title'); print($title); //打印 singwa ``` ### 第三章 IOC容器类及Facade深度解析 1. ##### 单例模式 ```php /** * 单利模式 */ class Single{ static $instance=null; //第二步 定义一个静态属性,初始值为null private function __construct(){ //第一步 私有化构造方法防止new创建对象 echo 'class instance .
'; } public static function getInstance(){ //第三步 定义一个静态方法,判断对象是否生成并返回该对象 if(is_null(self::$instance)){ self::$instance=new self(); } return self::$instance; } public function abc(){ return 'abc'; } } $ob1 = Single::getInstance(); //只会实例化一次 $ob2 = Single::getInstance(); $ob3 = Single::getInstance(); $ob4 = Single::getInstance(); echo $ob1->abc(); //打印 class instance abc echo $ob2->abc(); //打印 abc echo $ob3->abc(); //打印 abc echo $ob4->abc(); //打印 abc ``` 2. ##### 注册树模式 一个注册树上有很多个对象,可以设置对象。需要的时候从树上取下来调用相应的方法。 SingwaRegister.php ```php /** * 注册树模式 */ class SingwaRegister{ /**注册树池子 */ protected static $objects=null; /**树上挂载对象 */ public static function set($key,$object){ self::$objects[$key]=$object; } /**获取对象 */ public static function get($key){ if(is_null(self::$objects[$key])){ self::$objects[$key]=new $key; } return self::$objects[$key]; } /**注销对象 */ public static function _unset($key){ unset(self::$objects[$key]); } } ``` 创建测试类 A.php ```php class A{ public function abc(){ return 'abcd'; } } ``` 使用时通过注册树调用 ```php $abc=\SingwaRegister::get('A'); //获取到当前模型 dump($abc->abc()); ``` 3. 依赖注入(控制反转)思想 B类中需要调用A类中的方法,就把A类的实例传递给B类。 Car.php类 ```php namespace di; class Car{ public function run(){ return '汽车正在路上跑...'; } } ``` Person.php ```php namespace di; class Person{ public function __construct(Car $obj,$a=123) { $this->obj=$obj; $this->a=$a; } public function buy(){ // $bmw=new Car(); // $bmw=new $obj; return $this->a.'|'.$this->obj->run(); } } ``` 调用 ```php $bmw=new \di\Car(); $person=new \di\Person($bmw); var_dump($person->buy()); ``` 4. 反射机制 A.php ```php class A{ /**反射测试类 */ public $a=1; private $abc=2; public function abc($a,$b){ return 'abcd'; } public function mf($type=1){ return 'type:'.$type; } public function ddd(){ return "ddddd"; } } ``` 方法中调用 ```php public function rel(){ //反射 $obj=new \A(); // var_dump($obj); // 打印 A类 object(A)#34 (2) { ["a"]=> int(1) ["abc":"A":private]=> int(2) } $obj2=new \ReflectionClass($obj); // var_dump($obj2); // 打印 反射类 object(ReflectionClass)#35 (1) { ["name"]=> string(1) "A" } $instance=$obj2->newInstance(); //相当于实例化A类 // var_dump($instance); // object(A)#36 (2) { ["a"]=> int(1) ["abc":"A":private]=> int(2) } $methods=$obj2->getMethods(); //获取类中的方法 // var_dump($methods);die(); // array(3) { [0]=> object(ReflectionMethod)#37 (2) { ["name"]=> string(3) "abc" ["class"]=> string(1) "A" } [1]=> object(ReflectionMethod)#38 (2) { ["name"]=> string(2) "mf" ["class"]=> string(1) "A" } [2]=> object(ReflectionMethod)#39 (2) { ["name"]=> string(3) "ddd" ["class"]=> string(1) "A" } } // foreach ($methods as $key => $m) { // var_dump($m->getDocComment()); //获取注释内容 // } $properties=$obj2->getProperties(); //获取类的属性 var_dump($properties);die(); // array(2) { [0]=> object(ReflectionProperty)#40 (2) { ["name"]=> string(1) "a" ["class"]=> string(1) "A" } [1]=> object(ReflectionProperty)#41 (2) { ["name"]=> string(3) "abc" ["class"]=> string(1) "A" } } //调用方法 方式一 echo $instance->abc(1,2); //调用方法 方式二 $method=$obj2->getMethod("abc"); echo $method->invokeArgs($instance,['mmmm','555444a']); //调用方法 方式三 $method=$obj2->getMethod("ddd"); echo $method->invoke($instance); /**判断某个方式是否是公用的 */ $method=new \ReflectionMethod($obj,"ddd"); if($method->isPublic()){ echo '是公用方法'; } $method2=new \ReflectionMethod($obj,"abc"); dump($method2->getParameters()); //获取参数 dump($method2->getNumberOfParameters()); //获取参数个数 } ``` 5. 玩转自己的容器类 Container.php ```php namespace di; class Container{ /** * 存放容器的数据 */ public $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 set($key,$value){ $this->instances[$key]=$value; } /** * 获取容器里的实例 会用到反射机制 */ public function get($key){ if(!empty($this->instances[$key])){ $key=$this->instances[$key]; } $reflect=new \ReflectionClass($key); $c=$reflect->getConstructor(); //获取类的构造函数 if(!$c){ return new $key; } $params=$c->getParameters(); //返回构造函数参数 if(empty($params)){ //有构造函数,构造函数无参数 return new $key; } foreach ($params as $key => $param) { $class=$param->getClass(); if(!$class){ //todo }else{ $args[]=$this->get($class->name); } return $reflect->newInstanceArgs($args); } } } ``` 容器类中调用 ```php \di\Container::getInstance()->set('person','\di\Person'); \di\Container::getInstance()->set('car','\di\Car'); $obj=\di\Container::getInstance()->get('person'); var_dump($obj->buy()); ``` 6. Countable类 SingwaCount.php 中实现 Countable接口 并重写count 方法 ```php class SingwaCount implements Countable{ public function count(){ return '234'; } } ``` 方法中调用 ```php $obj=new \SingwaCount(); // echo $obj->count(); // 返回 234 echo count($obj); // 返回 234 ``` 7. 方法调用方式 ```php $config = new \Config(); //第一种方式 dump($config::get('app.')); //获取配置 $config=Container()::get('config')->get('app.'); //容器类获取 dump($config); $config=app('config'); // 第三种方式 dump($config->get('app.')); ``` 8. 调用不存在的静态方法会自动去调用魔术方法 __callStatic() ```php public static function __callStatic($name, $arguments) { var_dump($name); var_dump($arguments); } ``` 9. static::A(); ```php 容器中的实例 -> 不存在则创建实例放到容器中 在 application\common中创建文件 Singwa.php ```php abc(); ``` 调用方式二 facade模式的思想调用 在 application\facade中创建文件 Singwa.php ```php namespace app\facade; use \think\Facade; class Singwa extends Facade{ protected static function getFacadeClass() { return '\app\common\Singwa'; } } ``` 调用的代码 ```php \app\facade\Singwa::abc(); // 通过门面方式调用类 ``` facade bind方法 在 application\facade中创建文件 Xiaoliu.php ```php namespace app\facade; use \think\Facade; class Xiaoliu extends Facade{ } ``` 如果一个类 application\facade中 Xiaoliu.php 中没有定义 getFacadeClass 方法 ```php namespace app\facade; use \think\Facade; class Xiaoliu extends Facade{ } ``` 调用 ```php \think\Facade::bind('app\facade\Xiaoliu','app\common\Xiaoliu'); \app\facade\Xiaoliu::abc(); ``` ### 第四章 框架执行流程