面向对象编程的基本原则:
- 单一职责:一个类,只需要做好一件事
- 开放封闭:一个类,应该是可扩展的,而不是可修改的
- 依赖倒置:一个类,不应该强依赖另一个类。每个类对应另外一个类都是可替换的
- 配置化:尽可能地使用配置,而不是硬编码
- 面向接口编程:只需要关心接口,不需要关心实现
1、设置类的属性
class ShopProduct {
public $title = 'default product';
public $producterMainName = 'main name';
public $producterFirstName = 'first name';
public $price = 0;
} $product1 = new ShopProduct(); //设置属性
$product1->title = "My Antonia";
$product1->producterFirstName = "Cather";
$product1->producterMainName = "Willa";
$product1->price = 5.99; //访问
echo 'author: '.$product1->producterFirstName.' '.$product1->producterMainName;
用以上方法设置属性值会有很多问题:
第一:PHP允许动态设置属性,如果拼错或忘记属性名时并不会得到警告。例如错误地把
$product1->producterMainName = "Willa";
写作
$product1->producterSecondName = "Willa";
,当我们输出作者名字的时候,会有意想不到的结果。
第二:类太过松散,我们没有强制设置标题、价格或者产品名称,客户端代码可以确定的是这些属性存在,但是面对的可能是默认值也可能不是,理想情况下,我们希望实例化ShopProduct对象时设置有意义的属性值。
第三:不得不重复做一些经常做的事,比如多次需要完整输出作者的名字,就要重复使用
echo 'author: '.$product1->producterFirstName.' '.$product1->producterMainName;
改进后的:
2、使用方法
class ShopProduct {
public $title;
public $producterMainName;
public $producterFirstName;
public $price = 0;
//设置默认值,$this伪变量把类指向一个对象实例,$this可以理解为当前实例
public function __construct($title, $producterMainName, $producterFirstName, $price){
$this->title = $title;
$this->producterMainName = $producterMainName;
$this->producterFirstName = $producterFirstName;
$this->price = $price;
}
//获取作者名
public function getProducter(){
return $this->producterFirstName.' '.$this->producterMainName;
} } $product1 = new ShopProduct('My Antonia', 'Willa', 'Cather', 5.99); //访问
echo 'author: '.$product1->getProducter();
3、使用AccessArray实现配置文件的加载
ArrayAccess 是提供像访问数组一样访问对象的能力的接口。
Config.php
<?php
namespace Baobab; class Config implements \ArrayAccess{ protected $path;
protected $configs = array();
/**
* @param $path 配置文件所在的文件系统目录
*/
function __construct($path){
$this->path = $path;
} function offsetGet($key){
if (empty($this->configs[$key])){
$file_path = $this->path.'/'.$key.'.php';
$config = require $file_path;
$this->configs[$key] = $config;
}
return$this->configs[$key];
} function offsetSet($key, $value){
throw new \Exception("can't write config file");
} function offsetExists($key){
return isset($this->configs[$key]);
} function offsetUnset($key){
unset($this->configs[$key]);
}
}
/Configs/database.php
<?php
$config = array(
'master' => array(
'type' => 'MySQL',
'host' => '127.0.0.1',
'user' => 'root',
'password' => 'root',
'dbname' => 'test'
)
); return $config;
index.php
define('BASEDIR',__DIR__);
$config = new \Baobab\Config(BASEDIR.'/Configs');
//从文件系统加载一个配置文件Configs/database.php
print_r($config['database']);