访问控制属性和方法的访问控制(可见标识):publicanywhere私有类本身protected类本身,子类和父类实例化后,公共函数__construct(){}__destruct会在对象对被销毁时自动执行。公共函数__destruct(){}已定义且无法更改。constONE=1constTWO=self::ONE+1;Class::Twoparentparent可以在类外调用代表父类publicfunction__construct(){parent::__construct();}finalfinalclassDad(){}加在类定义前面,表示爸爸类不想被继承classDad(){finalpublicfunctionrun(){}//加在方法声明前面,表示方法不继承不想被子类重写}namespacenamespace必须放在代码文件的第一行受namespace影响的类型:类(包括抽象类、traits)、接口、函数、常量。当namespace关键字没有指定命名空间时,当前脚本存在于全局命名空间中。用\来表示。\Class1类全部在指定的命名空间中查找,没有找到则抛出错误。在指定的命名空间中搜索函数和常量。如果未找到,则会在全局命名空间中搜索它们。如果未找到它们,则会抛出错误。函数ns1\ns2\fn()constantdefine定义的常量是全局的,不受命名空间的影响。const定义的常量受名称空间的影响。namespacens1\ns2;constONE=1;echons1\ns2\ONE;useimportclassuseuse导入命名空间下的类usens1\ns2\class1;使用as重命名导入的类usens1\ns2\class1asclass2;导入函数usefunctionns1\ns2\fnasfn1;导入常量useconstns1\ns2\ONE;自动加载__autoloadfunction__autoload($className){需要$className。'.php';}spl_autoload_register传递匿名函数spl_autoload_register(function($className){require$className.'.php';});传递函数名称functiontest($className){require$className.'.php';}spl_autoload_register('测试');通过classMomo{functionautoload($className){require$className.'.php';}}spl_autoload_register([newMomo,'autoload']);static声明了静态属性和静态方法,可以通过类名调用,不需要实例化。类Person(){publicstatic$hand='hand';publicstaticfunctionrun(){echo'running...';}}echoPerson::$hand;Person::run();调用类内部的静态属性和静态方法使用self关键字echoself::$hand;自我::运行();调用父类的静态属性和静态方法使用parent关键字echoparent::$hand;父母::运行();laterstaticBindingclassA{publicstaticfunctionwho(){echo'类A的who方法';}publicstaticfunctiontest1(){self::who();}publicstaticfunctiontest2(){static::who();}}classBextendsA{publicstaticfunctionwho(){echo'who类B的方法';}}B::test1();//test1内部使用的self调用自身(A类)静态方法B::test2();//后期绑定。内部使用static,根据后面的调用环境决定,调用B类的静态方法魔术方法。__setclass测试{private$name='';publicfunction__set($var,$val){//为$valProcess设置数据$this->$var=$val;}}$test=newTest();$test->name='tom';//分配tom__getclass测试{private$name='jack';公共函数__get($var){返回$this->$var;}}$test=newTest();echo$test->name;//jack__isset用于检测私有属性是否存在classTest{private$name='mary';公共函数__isset($var){返回isset($this->$var);}}$test=newTest();var_dump($test->name);//如果未设置__isset,返回false,设置后返回true__unset用于删除私有属性classTest{private$name='Levi';公共函数__unset($var){unset()}}$test=newTest;unset($test->name);//会触发__unset__call避免在调用不存在的方法时出错。当调用的方法不存在时,__call方法会自动调用classTest{publicfunction__call($fn_name,$fn_arguments){echo$fn_name;print_r($fn_argum条目);}}$test=newTest();$test->go(1,'ok');//自动调用`__call`方法,打印出函数名和参数数组__callStatic类似于__call,避免调用一个不存在的静态方法classTest{publicstaticfunction__callStatic($fn_name,$fn_arguments){echo$fn_name;print_r($fn_arguments);}}//`__callStatic`必须声明为静态方法Test::go(1,'ok');__invoke当对象作为函数调用时,自动调用__invoke方法classTest{publicfunction__invoke($参数){返回$args;}}$test=newTest();$test('go.....');//运行__invoke__toString将在打印对象类时调用__toString方法Test{publicfunction__toString(){return'Helloworld!';}}$test=newTest;echo$test;//输出你好世界!对象拷贝浅拷贝节省内存,对象拷贝默认是浅拷贝$a=newTest();$b=$a;//浅拷贝。地址。改变$b。$a也会改变。对象被浅层复制。地址。普通变量的拷贝是深拷贝。传值。深拷贝$a=newTest();$b=克隆$a;//深拷贝。改变$b不会改变$a。__clone当使用clone关键字时,会自动调用__clone方法classTest{public$obj=null;公共函数__clone(){$this->obj=clone$this->obj;}}classPerson{public$sex=0;}$a=newTest;$a->obj=newPerson;$b=clone$a;//触发`__clone`来深拷贝obj$b->obj->sex=1;//$b中的obj对象被改变了。$a中的obj对象没有改变。类型约束类A{publicfunctiongo(){echo'go.....';}}functiontest(A$a){$a->go();}test(newA());Traitsingle继承PHP语言的代码重用机制。TraitBt{publicfunctionatest(){echo'Hello';}publicfunctionbtest(){echo'world';}publicfunctionab(){$this->atest();$this->btest();}classTest{使用Bt;//使用BtTrait,你拥有Bt的所有方法}$test=newTest;$test->ab();继承多个TraitTraitA{public$name='tom';publicfunctiona(){echo'你好';}}特征B{publicfunctionb(){echo'world';}}classTest{使用A,B;公共函数c(){echo$this->name;$test=newTest;$test->a();$test->b();$test->c();//HelloworldtomTrait支持嵌套TraitA{}TraitB{}TraitC{useA,B;}ClassTest{useC;}interface接口是类的模板。接口中只定义了需要实现的空方法,接口中并没有实现这些方法。接口不能被实例化。接口人{publicfunctioneat();publicfunctionsleep();}classmanimplementsPerson{publicfunctioneat(){echo'eating...';}publicfunctionsleep(){echo'睡觉...';}}classL{publicstaticfunctionfactory(Person$user)//使用接口作为类型约束{return$user;}}$user=L::factory(newMan());$user->eat();$用户->睡眠();接口可以继承接口。一个接口可以继承多个接口。接口可以使用常量,称为接口常量,与类常量相同。接口Ia{constONE=1;publicfunctioneat();}InterfaceIb{publicfunctionsleep();}InterfaceABextendsIa,Ib{}//classTestimplementsIa,Ib类可以同时继承多个接口classTestimplementsAB{publicfunctioneat(){echo'吃...';}publicfunctionsleep(){echo'睡觉...';}}$test=newTest;$test->eat();$test->sleep();echoIa::ONE;//使用接口常量abstract抽象类不能被实例化。如果至少有一个方法被声明为抽象的,则该类必须被声明为抽象的。抽象方法只能声明,不能用具体的函数来实现。抽象类可以有实现的方法。要继承一个抽象类,子类必须实现父类中的所有抽象方法。这些方法的访问控制必须和父类一样,或者更宽松一些,不能比父类更严格。调用方法的方式也必须匹配。参数的类型和个数必须一致,但子类可以定义父类中不存在的可选参数。abstractAB{publicfunctionrun(){echo'running...';}抽象公共函数eat();abstractpublicfunctionsleep();}classTestextendsAB{publicfunctioneat(){echo'eating...';}publicfunctionsleep($time='21:00PM')//可以定义父类方法中不存在的可选参数{echo'sleep@'.$时间;}}单例模式只能实例化保存内存空间classTest{privatestatic$instance=null;私有函数__constrct(){}私有函数__clone(){}公共静态函数getInstance(){if(!(self::instanceofself)){self::instance=newself();返回自我::实例;}}$test=Test::getInstance();//多次调用只实例化工厂模式InterfaceCacheI{publicfunctionset($key,$value);公共函数get($key);publicfunctiondelete($key);}类Memcache实现CacheI{publicfunctionset($key,$value){}publicfunctionget($key){}publicfufunctiondelete($ke){}}classRedis实现CacheI{publicfunctionset($key,$value){}publicfunctionget($key){}publicfunctiondelete($ke){}}classCache{publicstaticfunctionfactory(){returnnewMemcache();//这可以是任何继承CacheI接口的类,例如Redis}}$cache=Cache::factory();$cache->set('name','tom');$cache->get('名字');$cache->delete('名字');
