本文目录
前言
在
PHP
的广阔开发领域中,高效管理类和对象、灵活运用设计模式,是提升代码质量、增强应用可维护性的重要途径。本指南将带您深入探索PHP
中的类加载机制、对象克隆技术,以及几种经典设计模式的应用,为您的PHP
编程之路增添新的动力。
首先,我们将揭开类加载的神秘面纱,从手动加载到自动加载,特别是通过__autoload()
函数和spl_autoload_register()
实现灵活的类自动加载,让您的项目结构更加清晰,代码加载更加高效。接着,我们将探讨对象的克隆技术,包括clone
关键字和__clone()
魔术方法的使用,帮助您理解对象复制背后的原理与注意事项。
最后,本指南将引领您走进设计模式的殿堂,通过单例模式、工厂模式和策略模式的详细解析与实战应用,让您掌握设计模式的核心思想与应用技巧,提升代码的可复用性、可扩展性和可维护性。无论您是PHP
编程的新手还是资深开发者,本指南都将为您的编程技能带来质的飞跃。
1、类的规则
- 一个文件中只能放一个类(必须的)
- 文件名和类名同名(必须的)
- 类文件以.class.php结尾(不是必须的)
1.1 手动加载类
在项目开发中,因为一个文件中只能写一个类,并且在执行过程中会有很多的类参与,我们先演示手动一个个加载类。
项目结构如下:
php
├── Book.class.php
├── Goods.class.php
├── index.php
├── Phone.class.php
Book.class.php
代码如下:
<?php
// 图书类
class Book extends Goods {
public function getName () {
echo "《{$this->name}》<br/>";
}
}
?>
Good.class.php
代码如下:
<?php
// 商品类
abstract class Goods {
protected $name;
final public function setName ($name) {
$this->name = $name;
}
public abstract function getName();
}
?>
index.php
代码如下:
<?php
require './Goods.class.php';
require './Book.class.php';
require './Phone.class.php';
// 测试
$book = new Book();
$book -> setName('面向对象编程');
$phone = new Phone();
$phone -> setName('华为');
$book -> getName();
$phone -> getName();
?>
Phone.class.php
代码如下:
<?php
// 电话类
class Phone extends Goods {
public function getName () {
echo $this->name,'<br/>';
}
}
?>
运行结果如下:
可以看到,我们这边一个个的手动去加载类非常的麻烦,下面介绍自动加载类。
1.2 自动加载类
在项目开发中,因为一个文件中只能写一个类,并且在执行过程中会有很多的类参与,如果一个一个的加载很麻烦,所以,就需要一个机制实现在PHP执行过程中自动加载需要的类。
1.2.1 __autoload()函数
方法一:__autoload()函数
当缺少类的时候自动的调用__autoload()函数,并且将缺少的类名作为参数传递给__autoload()。
项目结构还是如下:
php
├── Book.class.php
├── Goods.class.php
├── index.php
├── Phone.class.php
改变index.php中的内容如下(其他不改变):
<?php
// 自动加载类
function __autoload ($class_name) {
require "./{$class_name}.class.php";
}
// 测试
$book = new Book();
$book -> setName('面向对象编程');
$phone = new Phone();
$phone -> setName('华为');
$book -> getName();
$phone -> getName();
?>
效果如下:
可以看到我们使用了自动加载类,可以很方便。
但是注意:__autoload()函数在PHP7.2以后就不支持了。
1.2.2 spl_autoload_register()
注册__autoload()函数
项目结构还是不变。
index.php改为如下:
<?php
// 方法一
function loadClass ($class_name) {
require "./{$class_name}.class.php";
}
//注册加载类函数
spl_autoload_register('loadClass');
// 方法二
// spl_autoload_register(function ($class_name) {
// require "./{$class_name}.class.php";
// });
// 测试
$book = new Book();
$book -> setName('面向对象编程');
$phone = new Phone();
$phone -> setName('华为');
$book -> getName();
$phone -> getName();
?>
效果:
也可以注册多个函数(以队列的形式,先进先出),进行(区分)不同类的加载。
1.3 类文件存储不规则
类文件存储不规则的加载方法,将类名和文件地址做一个映射,组成一个关联数组。
代码如下:
<?php
spl_autoload_register(function ($class_name) {
// 类名和文件地址映射成一个关联数组
$map = array(
'Goods' => './aa/Goods.class.php',
'Book' => './bb/Book.class.php',
'Phone' => './cc/Phone.class.php'
);
// 在映射数组中找到就包含
if (isset($map[$class_name])) {
require $map[$class_name];
}
})
// 测试
$book = new Book();
$book -> setName('面向对象编程');
$phone = new Phone();
$phone -> setName('华为');
$book -> getName();
$phone -> getName();
?>
在项目中,绝大部分都是规则存储的,不规则的比较少。
2、clone和__clone()
创建对象的方式有哪些?
方法一:实例化
方法二:克隆
例题:
<?php
class Student {
}
$stu1=new Student;
$stu2=new Student;
var_dump($stu1,$stu2);
?>
效果:
<?php
class Student {
}
$stu1=new Student;
$stu2=$stu1;
var_dump($stu1,$stu2);
?>
效果:
<?php
class Student {
}
$stu1=new Student;
$stu2=clone $stu1;
var_dump($stu1,$stu2);
?>
效果:
__clone()函数在调用clone指令的时候自动调用。
例题:
<?php
class Student {
public function __clone() {
echo '正在克隆';
}
}
$stu1=new Student;
$stu2=clone $stu1;
var_dump($stu1,$stu2);
?>
效果:
小结:
1、clone是创建对象的方法之一
2、当执行clone指令的时候,会自动的调用__clone()方法
3、设计模式
3.1 单例模式
一个类只能有一个对象。
应用场景:多次请求的数据库只需要一个连接对象。
实现:三私一公
1、私有的静态属性用来保存对象单例。
2、私有的构造方法用来阻止在类的外部实例化。
3、私有的__clone阻止在类的外部clone对象。
4、公有的静态方法用来获取对象的单例。
代码:
<?php
// 三私一公
class DB {
// 私有的静态属性用来保存单例
private static $instance;
// 私有的构造方法阻止在类的外部实例化
private function __construct() {
}
// 私有的__clone()阻止在类的外部克隆对象
private function __clone() {
}
// 公有的方法用来获取单例
public static function getInstance () {
if (!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
}
$db1 = DB::getInstance();
// $db2 = clone $db1;
$db2 = DB::getInstance();
var_dump($db1, $db2)
?>
效果:
3.2 工厂模式
特点:传递不同的参数调用不同的策略。(方法)
<?php
class ProductsA {
}
class ProductsB {
}
class Factory {
public function create($num) {
switch ($num) {
case 1:
return new ProductsA;
case 2:
return new ProductsB;
default:
return null;
}
}
}
// 测试
$factory = new Factory();
$obj1 = $factory->create(1);
$obj2 = $factory->create(2);
var_dump($obj1, $obj2);
?>
效果:
3.3 策略模式
特点:传递不同的参数调用不同的策略(方法)
<?php
class Walk {
public function way() {
echo '走着去<br/>';
}
}
class Bus {
public function way() {
echo '坐车去<br/>';
}
}
// 策略模式
class Student {
public function play ($obj) {
$obj->way();
}
}
// 测试
$stu = new Student;
// $stu->play(new Walk()); // 走着去
$stu->play(new Bus()); // 坐车去
?>
在学习的php的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。