PHP面向对象编程的基本原则,以及三种基本设计模式
面向对象编程的基本原则
1.单一职责:一个类,只需要做好一件事情
2.开放封闭:一个类,应该是可扩展的,而不可修改的
3.依赖倒置:一个类,不应该强依赖另一个类。每个类对于另外一个类都是可替换的
4.配置化:尽可能地使用配置,而不是硬编码
5.面向接口编程:只需要关心接口,不需要关心实现
PSR-0命名规范
1. 命名空间必须与绝对路径一致
2. 类名首字母必须大写
3. 除入口文件外,其他“.php”必须只有一个类
开发符合PSR-0规范的基础框架
1. 全部使用明明空间
2. 所有PHP文件必须自动载入,不能有include/require
3. 单一入口
类的自动载入
Test1.php
<?php class Test1{ static function test(){ echo __METHOD__; } }
Test2.php
<?php class Test2{ static function test(){ echo __METHOD__; } }
test.php
<?php spl_autoload_register('autoload1'); spl_autoload_register('autoload2'); function autoload1($class){ require __DIR__.'/'.$class.'.php'; } function autoload2($class){ require __DIR__.'/'.$class.'.php'; } Test1::test(); Test2::test();
运行test.php会得到这样的结果:
Test1::testTest2::test
__autoload()函数只可以存在一个,如果重复定义会报致命错误,所以目前一般使用spl_autoload_regisiter()来实现类的自动加载。
PHP链式调用的实现
Database.php
<?php class Database{ function where($where){ ... } function order($order){ ... } function limit($limit){ ... } }
如果Database.php是这样,那么在index.php中就需要这样来写以实现sql查询:
index.php
<?php $db=new Database(); $db->where("id=2"); $db->where("name=2"); $db->order("id desc"); $db->limit(10);
要实现链式调用只需要这样做:
Database.php
<?php class Database{ function where($where){ return $this; } function order($order){ return $this; } function limit($limit){ return $this; } }
在每个方法的末尾加上'return $this;',然后就可以:
Data
<?php $db->where("id=1")->where("name=2")->order("id desc")->limit(10);
三种基础的设计模式包括工厂模式、单例模式和注册器模式。
工厂模式
Factory.php
<?php class Factory{ static function createDatabase(){ $db = new Database(); return $db; } } $db = Factory::createDatabase();
工厂模式的作用在于不在类外实例化对象。
单例模式
Database.php
<?php class Database{ protected $db; // 第一步 private function __construct(){ // private可以屏蔽外部new这个类 } // 第二步 static function getInstance(){ if(self::$db){ return self::$db; }else{ self::$db = new self(); return self::$db; } } } $db = Database::getInstance();
单例模式用于数据库连接等只需要一个对象的场景,避免资源的浪费。
注册器模式
Register.php
<?php class Register{ protected static $objects; static function set($name, $object){ self::objects[$name] = $object; } static function get($name){ return self::objects[$name]; } static function _unset($name){ unset(self::objects[$name]); } } Register::set('db1',$db); $db = Register::get('$db1');
适配器模式
1.适配器模式,可以将截然不同的函数接口封装成统一的API
2.实际应用举例,PHP的数据库操作有mysql,musqli,pdo三种,可以用适配器模式统一成一致。类似的场景还有cache适配器,将memcache,redis,file,apc等不同的缓存函数,统一成一致
Database.php
<?php interdace IDatabase{ function connect($host, $user, $passwd, $dbname); function query($sql); function close(); }
在Database.php中定义了数据库操作的接口,接下来将MySQL、MySQLi、PDO三种数据库操作适配为接口中定义的方法。
MySQL.php
<?php namespace Database; 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.php
<?php namespace Database; 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){ $res = mysqli_query($this->conn, $sql); return $res; } function close(){ mysqli_close($this->conn); }
PDO.php
<?php namespace Database; class PDO implements IDatabase{ protected $conn; function connect($host, $user, $passwd, $dbname){ new \PDO("mysql:host=$host;dbname=$dbname", $user, $passwd); $this->conn = $conn; } function query($sql){ return $this->conn->query($sql); } function close(){ unset($this->conn); }
然后在应用中可以这样使用:
index.php
<?php $db = new Database\MySQL(); $db->connect('localhost', 'root', 'root', 'test'); $db->query('show database'); $db->close();
或者实例化其他类型的数据库,只需要使用同一种标准。