PHP单例模式
某个类仅允许实例化一次,即仅允许创建一个类实例。
单例模式确保某一个类只有一个实例,并且对外提供这个全局实例的访问入口。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。
应用场景有:数据库的连接对象,HTTP请求;游戏中的主角模式,例如等级一创建一次实例,等级二又创建一个新的实例。
案例:在未使用单例模式时,new出来的每一个实例都具有不同的ID号,若用“ === ”全等符号去判断两个对象是否相等时,将会得到false的结果。
// 普通方法创建对象,即使对象来源一致,但是ID不同,即创建了不同对象
class Temp
{
// ...一些实现实现方法
}
$obj1 = new Temp(); // object(Temp)#1 (0) { }
$obj2 = new Temp(); // object(Temp)#2 (0) { }
var_dump($obj1 === $obj2); // bool(false)
若要构造一个单例模式,仅需将构造方法私有化。私有化后在类的外部将无法new一个实例化。
// 单例模式创建对象,来源一致,ID一致,即创建了同一个对象
class Temp
{
// ...一些实现实现方法
}
class DanLi
{
private function __construct()
{
// ...占位符,此处被私有化
// ...外部无法获取此处内容,因此在该处不要写内容
}
// 创建一个当前类的实例对象
private static $instance = null;
// 用类访问的成员是静态成员,因此用static声明一个静态方法
public static function getInstance()
{
// 该方法用在类外部,来创建当前类的实例
// 如果当前类的实例是null,说明当前类还未被实例化
// 如果不是null,说明已被实例化过,直接返回实例
if(is_null(self::$instance))
{
self::$instance = new self(); //new self()实例化当前方法
}
return self::$instance; // 不是null返回当前类实例
}
}
//在类外部创建类实例,无法用$onj1 = new Danli();创建对象
$obj1 = DanLi::getInstance(); // object(DanLi)#1 (0) { }
$obj2 = DanLi::getInstance(); // object(DanLi)#1 (0) { }
var_dunp($obj1 === $obj2); // bool(true)
PHP工厂模式
工厂模式,顾名思义,如同工厂一样,你把原材料放入工厂中,出来的是成品,而你并不需要知道工厂里做了什么,工厂模式主要用于解耦。
把对象的创建和使用的过程分开,比如: ClassB 调用 ClassA,那么 ClassB 只调用ClassA 的方法,至于实例化 ClassA 则在工厂内实现。这样既减少了代码的重复使用,也方便对 ClassA 的后期维护。
优点:如果已经使用的类内部发生改变,哪不需要在所有的地方都改变,只需要在类工厂类里改变既可,比如连接数据库,可以使用mysql 、mysqli、pdo,根据不同参数配置使用不同的数据库操作类。
应用场景有:①做支付接口的时候,未来可能对应不同的支付网关:支付宝、财付通、网银在线等;②用户注册的时候,分为很多种角色的用户。比如册用户,匿名用户、管理员等。完全可以使用工厂的思想来实现,为每种角色生成对应操作的类,代码也容易维护。
class GongChang1
{
public function __construct($arg1)
{
echo '对象创建成功, 参数是: ' . $arg1;
}
}
class GongChang2
{
public function __construct($arg1, $arg2)
{
echo '对象创建成功, 参数是: ' . implode(', ', [$arg1, $arg2]);
}
}
class GongChang3
{
public function __construct($arg1, $arg2, $arg3)
{
echo '对象创建成功, 参数是: ' . implode(', ', [$arg1, $arg2, $arg3]);
}
}
class GongChang4
{
public function __construct()
{
echo '对象创建成功, 无参数';
}
}
// 工厂类: 用于创建类实例
interface iFactory
{
public static function create($className, ...$arguments);
}
class Factory implements iFactory
{
public static function create($className, ...$arguments)
{
return new $className(...$arguments);
}
}
Factory::create(GongChang1::class, 100);
echo '<br>';
Factory::create(GongChang2::class, 100, 200);
echo '<br>';
Factory::create(GongChang3::class, 100, 200, 300);
echo '<br>';
Factory::create(GongChang4::class);
echo '<br>';
浏览器显示结果为:
对象创建成功, 参数是: 100
对象创建成功, 参数是: 100, 200
对象创建成功, 参数是: 100, 200, 300
对象创建成功, 无参数
PHP MVC模式
MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)
下面将用女娲造人的案例来讲解MVC模型、MVC视图和MVC控制器。
模型:简单来说就是人体的骨骼框架,人类有头有手有脚,女娲先把一堆和水稀泥捏成人形,这就成了MVC的模型。视图:女娲从这步开始给小人的五官润色,这步完成后,每个小人有不同的脸孔,这就是MVC的视图,给别人看的。控制器:人类的灵魂。有了控制器,才能把死的模型和视图给它整活。把模型作为骨骼,把视图作为容貌,遂为人。
下面定义了模型和视图,随后将用控制器将模型和视图搭配起来,输出信息。
// MVC模型:定义基本信息
class Model
{
public function getData()
{
return [
['id'=>1, 'name'=>'张三','address'=>'中国北京','age'=>50],
['id'=>2, 'name'=>'李四','address'=>'中国香港,'age'=>15],
['id'=>3, 'name'=>'王五','address'=>'中国台湾','age'=>5],
];
}
}
// MVC视图:渲染(五官润色)模型
class View
{
public function fetch($data)
{
$table = '<table border="1" cellspacing="0" width="400">';
$table .= '<caption>女娲造人表</caption>';
$table .= '<tr bgcolor="lightblue"><th>ID</th><th>人名</th><th>地址</th><th>年龄</th></tr>';
foreach ($data as $product) {
$table .= '<tr>';
$table .= '<td>' . $product['id'] . '</td>';
$table .= '<td>' . $product['name'] . '</td>';
$table .= '<td>' . $product['address'] . '</td>';
$table .= '<td>' . $product['age'] . '</td>';
$table .= '</tr>';
}
$table .= '</table>';
return $table;
}
}
调用控制器方法,将模型和视图搭配起来,然后输出。
// MVC控制器
require 'Model.php'; // 加载MVC模型
require 'View.php'; // 加载MVC视图
// 构造控制器
class Controller
{
public function index()
{
// 1. 获取数据
$model = new Model();
$data = $model->getData();
// 2. 渲染模板/视图
$view = new View();
return $view->fetch($data);
}
}
// 调用控制器
$controler = new Controller();
echo $controler->index();
最后输出结果为一个表格,很普通的表格。当然,MVC模式也基本有个了解了。