首页 > php知识, 未分类 > php接口学习 —— php面向对象编程

php接口学习 —— php面向对象编程

2010年3月31日

php-interface
先来看一段php面向对象编程的代码:
[php]
<?php
class DBPersonProvider
{
public function getPerson($givenName, $familyName)
{
/*省略了 链接数据库,获取person信息 */
$person = new Person();
$person->setPrefix("Mr.");
$person->setGivenName("John");
return $person;
}
}

/*获取persoin信息 */
$provider = new DBPersonProvider();
$person = $provider->getPerson("John", "Doe");

echo($person->getPrefix());
echo($person->getGivenName());

?>
[/php]
这一段代码可以实现从数据库中取出数据,赋值给Person对象然后返回这一功能。在环境发生更改之前,代码都可以正常运行。但是,从数据库装入 Person 可能适用于第一个版本的应用程序,但是对于第二个版本,可能需要添加从 Web 服务装入人员的功能。此时,因为上述代码直接使用实现类导致了现在能做的更改十分有限(修改的话,可能会大范围改动代码)。
为了今后升级和维护起来方便,我们需要用到php的接口来改造上面的方法。先介绍一下php接口的相关知识:

PHP使用implements实现接口

[php]
<?php
interface User
{
const MAX_GRADE = 99; //此处不用声明,就是一个静态常量
function setName($name);
static function getName() {
}
}
class NoumalUser implements User
{
}
?>
[/php]
通过implements来实现一个接口时,只需要写出抽象方法,不需要给出具体实现,否则将会如下报错:
Fatal error: Interface function User::getName() cannot contain body
看一下正确的php接口实现:
[php]
<?php
interface User
{
const MAX_GRADE = 99; //此处不用声明,就是一个静态常量
function setName($name);
function getName();
}
//实现接口
class NoumalUser implements User
{
private $name;
function getName() {
return $this->name;
}
function setName($_name) {
$this->name = $_name;
}
}
$normalUser = new NoumalUser(); //创建对象
$normalUser->setName("http://www.isstudy.com");
echo "URL is " . $normalUser->getName();
echo "<br />";
echo "MAX_GRADE is " . NoumalUser::MAX_GRADE; //静态常量
?>
[/php]

PHP还可以实现多个接口

一个类可以实现多个接口。只要使用 ‘,’ 将多个接口链接起来就可以。
[php]
<?php
interface User
{
const MAX_GRADE = 99; //此处不用声明,就是一个静态常量
function setName($name);
function getName();
}
interface administrator
{
function setBulletin($_bulletin) ;
}
//多个接口
class NoumalUser implements User, administrator
{
private $name;
function getName() {
}
function setName($_name) {
}
function setBulletin($_setBulletin) {
}
}
?>
[/php]

PHP还可以继承并实现接口

[php]
<?php
class Student
{
protected $grade;
public function getGrade() {
return $this->grade;
}
}
interface User
{
function getName();
function setName($_name);
}
//只有管理员可以设置公告
interface Administrator
{
function setBulletin($_bulletin);
}
//为了节省版面,下面方法只写空的实现.不写具体内容了
class StudentAdmin extends Student implements User, Administrator
{
function getName() {
}
function setName($_name) {
}
function setBulletin($_bulletin) {
}
}
$s = new StudentAdmin();
echo $s->getGrade();
echo $s->getName();
echo $s->setBulletin("公告内容");
?>
[/php]

再来说一下工厂模式

当我们了解了php接口类之后,又一个问题出现了,那就是要针对不同的类来写不同的实例化语句,举个例子:
假设我的代码既要实现MySQL的数据连接,又要兼容SQL Server,Oracle,以及DB2. 那我在不同情况下实例化的时候,就需要使用下面的语句。
[php]
$db = new MySQLClass();

$db = new SQLServerClass();

$db = new OracleClass();

$db = new DB2Class();
[/php]
麻烦了,还是需要指定具体实例化的是哪个类,用了接口跟没用一样, 所以我们需要一个工厂:
[php]

$db = new DBFactory.getConnect();

[/php]
  这就是23种模式中最基础的普通工厂(Factory),工厂类负责具体实例化哪个类,而其他的程序逻辑都是针对DB这个接口进行操作,这就是“针对接口编程”, 责任都被推卸给工厂类了。

使用php接口编程之后代码的改善

当我们明白了接口以及工厂的意义时,之前那段代码的修改方案已经呼之欲出了:
[php]
<?php
interface PersonProvider
{
public function getPerson($givenName, $familyName);
}

class DBPersonProvider implements PersonProvider
{
public function getPerson($givenName, $familyName)
{
/* pretend to go to the database, get the person… */
$person = new Person();
$person->setPrefix("Mr.");
$person->setGivenName("John");
return $person;
}
}

class PersonProviderFactory
{
public static function createProvider($type)
{
if ($type == ‘database’)
{
return new DBPersonProvider();
} else {
return new NullProvider();
}
}
}

$config = ‘database’;
/* I need to get person data… */
$provider = PersonProviderFactory::createProvider($config);
$person = $provider->getPerson("John", "Doe");

echo($person->getPrefix());
echo($person->getGivenName());
?>
[/php]

作者: 石巍
原载: 10V
版权所有,转载时必须以超链接形式注明作者和原始出处及本声明。

本文链接: http://www.smartwei.com/php-oop-interface.html
参考文章:在 PHP 中养成 7 个面向对象的好习惯 | klinghr的专栏:PHP类接口的实现接口

本文的评论功能被关闭了.