面向对象
PHP的类权限控制修饰符
public(公共的) 、 protected(受保护的)、private(私有的)
public :最高权限 可以在类的内部使用 可以在类的外部使用 可以在子类中使用
protected:可以在类的内部使用 可以在子类当中使用
private:只能在类的内部使用 不可以被继承 不可以在类的外部使用
面向对象的封装、继承、多态
封装:成员访问权限 public protected private 访问权限问题
继承:单一继承 同时只能继承一个类
方法重写 子类继承一个父类 在子类中写一个于父类相同的方法名会把父类的方法覆盖掉
如果不想覆盖可以使用parent先调用一下父类的方法
class Father{ public function test(){ } } class Son extends Father{ public function test(){ parent::test(); ..... } }
多态:
抽象类的定义
抽象类定义前面以abstract关键字开始 类中可以定义多个方法,可以具体实现方法,也可定义抽象方法,抽象方法就是没有绝体实现的方法,需要在方法前加 abstract 关键字,抽象方法需要在子类中实现 类中只要有抽象方法,这个类必须定义为抽象类。 抽象类和接口一样不能直接实例化为对象,只能被普通类继承。 定义一个抽象类 abstract class MyList{ //抽象方法需要在子类中实现 abstract public function selectgroup($where); public function del($where){ echo "删除成功"; } } //Tag类继承MyList抽象类 class Tag extends MyList{ //实现抽象方法 public function selectgroup(){ echo "查找数据"; } } //Plist类继承MyList抽象类 class Plist extends MyList{ //实现抽象方法 public function selectgroup(){ echo "查找数据库"; } }
接口的定义 interface 声明定义接口 一句话说明:类方法必须实现,接口的方法必须为空
不同类的共同方法在接口中定义,然后在不同类中实现不同的功能
接口本身就是抽象的不用加 abstract
一个类可以一次实现多个接口 语法用implements实现
接口可以被继承 用extends
接口定义方法只能使用public
接口不能创建自己的对象
interface Action(){ public function eat($foods); } //普通类实现接口方法 calss Human implements Action(){ //实现接口必须提供接口中的方法 public function eat($foods){ echo "Human eat"; } } class Animal implements Action(){ public function eat( $foods){ echo "Animal eat {$foods}"; } } //调用完成的方法 $human = new Human(); $human->eat(); $animal = new Animal(); $animal->eat(); /// instanceof 判断某个对象是否实现了某个接口 function CheckEat( $obj ){ if( $obj instanceof Action ){ $obj->eat( 'orange' ); }else{ echo "the object not implements Action"; } } CheckEat( $human ); CheckEat( $animal ); //接口继承 //extends 让接口继承接口 interface IcanPee extends Action(){ public function pee(); } //当类实现子接口时,父接口定义的方法也需要在这个类里面具体实现 Class Human1 implements IcanPee(){ public function pee(){ } public function eat( $foods ){ } }
魔术方法
__construct() 构建对象时使用
__destruct() 明确销毁对象或脚本结束时被调用
__call() 调用不可访问或不存的方法时被调用
__callStatic() 调用不可访问或不存在的静态方法时被调用
__get() 读取不可访问或不存在的属性时被调用
__set() 当给不可访问或不存在的属性赋值时被调用
__isset() 对不可访问或不存在的属性调用isset()或empty()时被调用
__unset() 对不可访问或不存在的属性进行unset时被调用
__sleep() 当使用serialize时被调用,当你不需要保存大对象的所有数据时很有用
__wakeup() 当使用unserialize时被调用,可用于做些对象的初始化操作
__toString() 当一个类被转换成字符串时被调用
__clone() 进行对象clone时被调用 用来调整对象的克隆行为
__invoke() 当以函数方式调用对象时被调用
__set_state() 当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值
__debuginfo() 当调用var_dump()打印对象时被调用(不想打印所有属性)PHP5.6版本
class MyExample{ public $var = 'test'; //构造函数 public function __construct() { echo '__contruct'.PHP_EOL; } //对象的引用都被删除、对象被销毁、调用exit()后、脚本关闭时被调用 public function __destruct() { echo '__destruct'.PHP_EOL; } //调用不可访问或不存在的方法时被调用 public function __call($name, $arguments) { echo '__call'.PHP_EOL; } //调用不可访问或不存在的静态方法时被调用 public static function __callStatic($name, $arguments) { echo '__callStatic'.PHP_EOL; } //读取不可访问或不存在的属性时被调用 public function __get($name) { echo '__get'.PHP_EOL; } //不可访问或不存在的属性赋值时调用 public function __set($name, $value) { echo '__set'.PHP_EOL; } //不可访问或不存在的属性调用isset()或empty()时被调用 public function __isset($name) { echo '__isset'.PHP_EOL; } //不可访问或不存在的属性unset时被调用 public function __unset($name) { echo '__unset'.PHP_EOL; } //serialize时被调用 ,不需要保存大对象的所有数据时有用 public function __sleep() { echo '__sleep'.PHP_EOL; return array('var111111111111111'); } //unserialize时被调用,可用于做些对象的初始化操作 public function __wakeup() { echo '__wakeup'.PHP_EOL; $this->var = 'test after wakeup'; } //一个类被转换为字符串时被调用 public function __toString() { return '__toString'.PHP_EOL; } //进行对象clone时被调用 用来调整对象的克隆行为 public function __clone() { echo '__clone'.PHP_EOL; } //以函数方式调用对象时被调用 public function __invoke() { echo '__invoke'.PHP_EOL; } //当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值。 public static function __set_state($arr) { return '__set_state'.PHP_EOL; } //调用var_dump()打印对象时被调用(当你不想打印所有属性)适用于PHP5.6版本 public function __debuginfo() { echo '__debuginfo'.PHP_EOL; return array( 'var' =>'test fro __debuginfo' ); } } $m = new MyExample(); //__construct()被调用 $m->not_exist_property = test; //__set()被调用 echo $m->not_exist_property; //__get()被调用 $m->abc(1,2,3); //__call()被调用 echo isset($m->not_exist_property); //__isset()被调用,返回bool值 unset($m->not_exist_property); //__unset()被调用 echo $tmp = serialize($m); //__sleep()被调用 unserialize($tmp); //__wakeup()被调用 $m1 = clone $m; //__clone()被调用,对象默认是引用传递,使用clone关键词则可实现对象复制 $m(); //__invoke() eval( '$m2 = ' . var_export ( $m , true ) . ';');var_dump($m2); var_dump($m); //最后__destruct()被调用
设计模式
常见的设计模式:工厂模式、单例模式、注册树模式、适配器模式、观察者模式、策略模式
工厂模式
工厂模式是最常用的实例化对象模式,使用工厂方法代替new操作的一种模式
工厂模式的好处是,你想要更改所实例化的类名等,则只需要更改工厂方法内容即可,不需逐一寻找代码中具体实例化的地方修改。为系统结构提供了灵活的动态扩展机制,减少耦合。
/** *简单工厂模式(静态工厂方法模式) */ /** * Interface people 人类 */ interface people { public function say(); } /** * Class man 继承people的男人类 */ class man implements people { // 具体实现people的say方法 public function say() { echo '我是男人<br>'; } } /** * Class women 继承people的女人类 */ class women implements people { // 具体实现people的say方法 public function say() { echo '我是女人<br>'; } } /** * Class SimpleFactoty 工厂类 */ class SimpleFactoty { // 简单工厂里的静态方法-用于创建男人对象 static function createMan() { return new man(); } // 简单工厂里的静态方法-用于创建女人对象 static function createWomen() { return new women(); } } /** * 具体调用 */ $man = SimpleFactoty::createMan(); $man->say(); $woman = SimpleFactoty::createWomen(); $woman->say();
单例模式
单例模式确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式一种常见的设计模式。比如用于,线程池、缓存、日志对象、对话框、打印机、数据库操作等。
单例模式分为三种:懒汉式单例、饿汉式单例、登记式单例。
有三个特点:
1、只能有一个实例。
2、必须自行创建这个实例
3、必须给其他对象提供这一实例
为什么要使用单例模式?
PHP一个主要应用场合就是引用程序和数据库打交道的场景,在一个应用中会存在大量的数据库操作,针对数据库连接数据库行为,使用单例模式可以避免大量的new操作。因为每一次new操作都会消耗和内存的资源。
class Single { private $name;//声明一个私有的实例变量 private function __construct(){//声明私有构造方法为了防止外部代码使用new来创建对象。 } static public $instance;//声明一个静态变量(保存在类中唯一的一个实例) static public function getinstance(){//声明一个getinstance()静态方法,用于检测是否有实例对象 if(!self::$instance) self::$instance = new self(); return self::$instance; } public function setname($n){ $this->name = $n; } public function getname(){ return $this->name; } } $oa = Single::getinstance(); $ob = Single::getinstance(); $oa->setname('hello world'); $ob->setname('good morning'); echo $oa->getname();//good morning echo $ob->getname();//good morning
注册模式
注册模式,解决全局共享和交换对象。已经创建好的对象,挂在某个全局可以是哟个的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局树上,任何地方直接去访问。
class Register { protected static $objects; function set($alias,$object)//将对象注册到全局的树上 { self::$objects[$alias]=$object;//将对象放到树上 } static function get($name){ return self::$objects[$name];//获取某个注册到树上的对象 } function _unset($alias) { unset(self::$objects[$alias]);//移除某个注册到树上的对象。 } }
适配器模式
将各种截然不同的函数接口封装成统一的API
PHP中的数据库操作有MySQL、MySQLi、PDO三种,可以使用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。
首先定义一个接口(有几个方法,以及相应的参数)。然后,有几种不同的情况,就写几个类实现该接口。将完成相似功能的函数,统一成一致的方法。
//接口 IDatanase interface IDatabase { function connect($host, $user, $passwd, $dbname); function query($sql); function close(); } // Mysql class MySQL implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = mysql_connect($host, $user, $passwd); mysql_select_db($dbname, $conn); $this->conn = $conn; } function query($sql) { $res = mysql_query($sql, $this->conn); return $res; } function close() { mysql_close($this->conn); } } //Mysqli class MySQLi implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = mysqli_connect($host, $user, $passwd, $dbname); $this->conn = $conn; } function query($sql) { return mysqli_query($this->conn, $sql); } function close() { mysqli_close($this->conn); } }
观察者模式
1、观察者模式,当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
2、场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变的那一维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。
3、观察者模式实现了低耦合,非侵入式的通知与更新机制。
// 主题接口 interface Subject{ public function register(Observer $observer); public function notify(); } // 观察者接口 interface Observer{ public function watch(); } // 主题 class Action implements Subject{ public $_observers=array(); public function register(Observer $observer){ $this->_observers[]=$observer; } public function notify(){ foreach ($this->_observers as $observer) { $observer->watch(); } } } // 观察者 class Cat implements Observer{ public function watch(){ echo "Cat watches TV<hr/>"; } } class Dog implements Observer{ public function watch(){ echo "Dog watches TV<hr/>"; } } class People implements Observer{ public function watch(){ echo "People watches TV<hr/>"; } } // 应用实例 $action=new Action(); $action->register(new Cat()); $action->register(new People()); $action->register(new Dog()); $action->notify();
策略模式
策略模式是对象的行为模式,用意是对一组算法的封装。动态的选择徐太的算法并使用。
策略模式指的是程序中涉及决策控制的一种模式。策略模式功能非常强大,因为这个模式本身的核心思想就是面向对象编程的多形性思想
策略模式三个角色
1:抽象策略角色
2:具体策略角色
3:环境角色(对抽象策略角色的引用)
实现步骤:
1:定义抽象角色类 (定义好各个实现的共同抽象方法)
2:定义具体策略类 (具体实现父类的共同方法)
3:定义环境角色类 (私有化申明抽象角色变量,重载构造方法,执行抽象方法)
打个比方说明策略模式:
如果我需要买衣服了,我可以有几种方式买衣服?
1、我可以在京东购买。
2、我可以在淘宝购买。
3、我可以找代购买。
4、我可以去商场买。
每个方式我都可以买到衣服,但是使用了不同方式。
abstract class baseAgent { //抽象策略类 abstract function PrintPage(); } //用于客户端是IE时调用的类(环境角色) class ieAgent extends baseAgent { function PrintPage() { return 'IE'; } } //用于客户端不是IE时调用的类(环境角色) class otherAgent extends baseAgent { function PrintPage() { return 'not IE'; } } class Browser { //具体策略角色 public function call($object) { return $object->PrintPage (); } } $bro = new Browser (); echo $bro->call ( new ieAgent () );