批改状态:合格
老师批语:直播时间是有限的, 无法将每一个知识点细节全部涉及, 很多东西,还要靠大家课后自觉


demo1
<?phpnamespace _1205;use PDO;//单例模式class Temp{}//创建一个实例$obj1 = new Temp();//再创建一个实例用于比较;$obj2 = new Temp();//查看对象的类型var_dump($obj1,$obj2);echo '<br>';var_dump($obj1===$obj2);//这样创建的实体其实是两个完全不同的对象echo '<hr>';//单例模式//应该场景,如数据库连接,只允许有限的连接数,不允许无限连接,一般一个对象创建一次连接就行class Demo1{//1.构造方法私有化private function __construct(){}//目前只能在类的内部将类实例化,这样类中访问只能用静态成员// 当前类的实例public static $instance=null; //可以不赋值,默认也是null//实例化当前类的方法,类中也不能实例化调用,也要申明为一个静态方法public static function getInstance(){//实例化当前类,并返回实例/对象//判断当前类是否已经被实例化过了,如果没有的化就实例化,如果已创建就返回他if(is_null(self::$instance)){//判断当前类实例是否是空// 没有就创建类实例self::$instance=new self(); //new产生的实例保存在当前静态类成员中}return self::$instance;}private function __clone(){// 禁用克隆魔术方法// 设置魔术方法__clone为私有方法,内容为空}}//思路:把外面实例化的操作功能禁用掉,禁用new新实例//new Demo1();//创建一个实例$obj1 = Demo1::getInstance();//再创建一个实例用于比较;$obj2 = Demo1::getInstance();var_dump($obj1===$obj2);echo '<br>';var_dump($obj1,$obj2);//单例模式的应用场景class Db{//1.构造方法私有化private function __construct(...$connectParams){$dsn=$connectParams[0];$username=$connectParams[1];$password=$connectParams[2];self::$pdo = new PDO($dsn,$username,$password);}//如果前面不加use PDO 这里要写成 \PDO() 在根目录全局下//目前只能在类的内部将类实例化,这样类中访问只能用静态成员// 当前类的实例public static $pdo=null; //可以不赋值,默认也是null//实例化当前类的方法,类中也不能实例化调用,也要申明为一个静态方法public static function getInstance(...$connectParams){//实例化当前类,并返回实例/对象//判断当前类是否已经被实例化过了,如果没有的化就实例化,如果已创建就返回他if(is_null(self::$pdo)){//判断当前类实例是否是空// 没有就创建类实例//构造函数不需要返回,因为在__construct中self::$pdo = new PDO($dsn,$username,$password);已经初始化了new self(...$connectParams);//构造函数没有返回值,这里无需写成self::$pdo=new self(...$connectParams)赋值,将new产生的实例保存在当前静态类成员中的格式}return self::$pdo;}private function __clone(){// 禁用克隆魔术方法// 设置魔术方法__clone为私有方法,内容为空}}echo '<hr>';$connectParams=['mysql:host=localhost;dbname=youya','root','root'];//当前DB类实例化$pdo =Db::getInstance(...$connectParams);print_r($pdo->query('SELECT * FROM `user`')->fetchAll());// 为了演示这里没用预处理
demo2
<?phpnamespace _1205;//工厂模式:批量new类生产,用于批量创建类的实例/对象class Demo2{}//file1.php$obj1 = new Demo2();//file2.php$obj2 = new Demo2();//file3.php$obj3 = new Demo2();/************************************************************///创建一个批量生成器class Test1{public function __construct($arg1){echo '对象创建成功,参数是:'.$arg1;}}class Test2{public function __construct($arg1,$arg2){echo '对象创建成功,参数是:'.implode(',',[$arg1,$arg2]);//数组切割implode拆成字符串}}class Test3{public function __construct($arg1,$arg2,$arg3){echo '对象创建成功,参数是:'.implode(',',[$arg1,$arg2,$arg3]);//数组切割implode拆成字符串}}//把上面三个类Test1,Test2,Test3,都实例化//原始的笨办法 new Test1();new Test2();new Test3();//现在优化的方法就是用工厂类class Factory{//尽可能不要实例化,用类来访问,写成静态方法// creat(类名称,构造方法的参数)public static function creat($className,...$argments){//里面专业new类,最后return出来给调用者return new $className(...$argments);}}echo Test1::class; //Test1::class返回来的类名是带有命名空间的完成的类名//用工厂类来创建类实例Factory::creat(Test1::class,100);//☆☆☆☆☆☆☆☆注意,类是有命名空间的,要写上命名空间,不要忽略了,写成_1205\Test1,或者Test1::classecho '<hr>';Factory::creat(Test2::class,100,200);echo '<hr>';Factory::creat(Test3::class,100,200,300);
demo3 依赖注入的知识复习
<?phpnamespace _1205;//依赖注入:解决对象调用之间的耦合问题//依赖注入需要两个类://1.工作类 :真正干活的class Person{//这是一个工作类,先把要依赖的外部对象创建成属性private $car=null;//构造方法中把依赖的外部对象全部实例化//就是把注入点放在构造方法中,在new的过程中直接完成注入public function __construct()// 依赖注入的目标就是将类方法中的new干掉{$this->car=new Car();}// 外部对象执行一个动作public function work(){return $this->car->drive();}}//2.依赖的外部类class Car{// 这个Car类就是Person类所依赖的外部对象public function drive(){return '开车去上班';}}//客户端访问 实例化工作类(真正干活的)$person=new Person();//然后直接访问工作类的一个方法echo $person->work();echo '<hr>';//以上为传统模式,但耦合度太高,类中出现类new 实例化对象方法/***************************************************************///那么在那里实例化呢?把它放在客户端class Person1{//这是一个工作类,先把要依赖的外部对象创建成属性private $car=null;//构造方法中把依赖的外部对象全部实例化//就是把注入点放在构造方法中,在new的过程中直接完成注入public function __construct(Car $car)// 这里先写一个类型申明,然后创建一个变量叫$car,这样就实现了通过外部对象注入到当前类中// 依赖注入的目标就是将类方法中的new干掉{$this->car=$car;}// 外部对象执行一个动作public function work(){return $this->car->drive();}}//2.依赖的外部类class Car1{// 这个Car类就是Person类所依赖的外部对象public function drive(){return '开车去上班';}}//客户端访问 实例化工作类(真正干活的)//那么在那里实例化呢?把它放在客户端:$car=new Car();,然后注入到构造方法的参数中$person=new Person1($car)$car=new Car();$person=new Person1($car);//然后直接访问工作类的一个方法echo $person->work();echo '<hr>';
demo4容器的知识复习
<?php//容器类namespace _1205;//引入闭包别名use Closure; //类的new创建过程代码是个闭包函数,先use引入class Container{//类实例容器protected $instance=[];// 1.将类实例化的过程绑定到容器中public function bind($alias,Closure $process)//绑定的时候需要参数?哪些参数--实例对象名,绑定过程的闭包函数{$this->instance[$alias]=$process;// $product=new Product(); ↑对应关系}// 2.取出保存在容器中的实例化过程的闭包,并执行它public function make($alias){return $this->instance[$alias]();// 用户代理call_user_func_array是异步调用的过程,由系统决定何时运行,不会导致堵塞}}
<?phpnamespace _1205;//先不用容器.用传统方式//先创建一个客户端的类use http\Client;require 'Product.php';require 'Maker.php';require 'Container.php';//把产品类和制造商类导入class Client2{// 输出商品与制造商public function show(Product $product,Maker $maker){// //1.创建一个产品的实例// $product=new Product();// //2.创建一个制造商的实例// $maker=new Maker();// 用了容器,传统方法的1.2.步骤就不用了//3.把制造商注入到产品类中return $product->get($maker);}}//客户端调用//将类实例绑定到容器中并实例化且返回$container = new Container();//将实例化代码绑定到容器实例中$container->bind('product',function(){return new Product();});$container->bind('maker',function(){return new Maker();});//这里bind('product')别名无所谓,写'abc'也可以,只要对应起来就可以,function()不用参数{return new 类}//创建实例并返回$product=$container->make('product');// 这里make要传参数,你调用谁就传谁,实例化的别名$maker=$container->make('maker');echo (new Client2())->show($product,$maker);//依赖注入
demo5
<?php//旅行,使用最原始的方式namespace base;//设置引用的外部别名use base\inc2\Car;use base\inc2\Ship;use base\inc2\Train;use base\inc2\Plane;use base\inc2\iVehicle; //导入接口空间require __DIR__ . '/autoload.php'; //自动加载类class Travel3{//交通工具private $vehicle;//构造方法public function __construct(iVehicle $vehicle){$this->vehicle=$vehicle;// 实现了接口的类实例可以这样直接调用}// 调用外部依赖对象public function travelModel(){return $this->vehicle->drive().'======去旅行';}}//客户端调用$car=new Car();echo (new Travel3($car))->travelModel().'<br>';//这里需要传参,传什么参数,这里需要的是一个对象了public function __construct(iVehicle $vehicle)echo (new Travel3(new Train()))->travelModel().'<br>';echo (new Travel3(new Plane()))->travelModel().'<br>';echo (new Travel3(new Ship()))->travelModel().'<br>';

.
思路:把外面实例化的操作功能禁用掉,禁用new新实例,把构造方法__congstruct改为private
目前只能在类的内部将类实例化,这样类中访问只能用静态成员,成员属性和方法都static静态化
判断当前类是否已经被实例化过了,如果没有的化就实例化,如果已创建就返回他
批量new类生产,用于批量创建类的实例/对象
尽可能不要实例化,用类来访问,写成静态方法
public static function creat($className,...$argments){//里面专业new类,最后return出来给调用者return new $className(...$argments);}
目标:就是将类方法中的new干掉,解决对象调用之间的耦合问题。除了单例模式,其他类中尽量不要出现new xxx()实例化类;
那么不要new在那里实例化呢?——把它放在客户端
拿到对象后,把他注入到构造方法中作为参数*
依赖注入需要两个类:
构造方法中把依赖的外部对象全部实例化,方法很简单,就是把注入点放在构造方法中作为参数
容器里有个数组
例如$instance[对象]=类的new创建过程代码
关键:
(1)类实例容器$instance=[];
(1)放进去:将类实例化的过程绑定到容器中 bind()//绑定的时候需要参数?哪些参数—实例对象名,绑定过程的闭包函数
(2)取出来用:取出保存在容器中的实例化过程的闭包,并执行它。
make()对应类的new创建过程代码
结合用户代理来用call_user_func_arry()
接口命名规划用小写开头 如iVehicle
implements实现接口类
小技巧:按alt键选择可以多点编辑
//构造方法public function __construct(iVehicle $vehicle){$this->vehicle=$vehicle;}
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号