认识命名空间
本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 10 课,共 91 课。
随着你的 PHP 项目不断扩展,你会创建很多类。两个类同名时会发生什么?
例如,你的博客中可能有一个 User 类,商店中还有另一个 User 类。命名空间通过将类组织成逻辑分组来解决这个问题。
命名空间就像存放类的文件夹。你可以在 PHP 文件顶部使用 namespace 关键字来声明它:
<?php
namespace Blog;
class User {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
现在,你可以在另一个命名空间中创建另一个 User 类:
<?php
namespace Shop;
class User {
public $email;
public function __construct($email) {
$this->email = $email;
}
}
要使用带命名空间的类,你需要用反斜杠写出它的完整路径:
<?php
$blogUser = new \Blog\User("Alice");
$shopUser = new \Shop\User("alice@example.com");
echo $blogUser->name . "\n";
echo $shopUser->email . "\n";
输出:
Alice
alice@example.com
反斜杠 \ 用于分隔命名空间层级,类似于斜杠在文件路径中分隔文件夹。你也可以创建嵌套命名空间,例如 App\Models\Blog,以便进行更深入的组织。
要点:命名空间可以防止命名冲突,并让代码保持整洁。在文件中的任何其他代码之前声明命名空间(declare 语句除外)。
挑战
简单让我们使用命名空间组织一个小型应用,避免同名类之间发生命名冲突。
想象一下,你正在构建一个同时处理车辆和动物的系统。这两个领域都有一个名为 Car 的实体:一个代表真正的汽车,另一个则是一只名叫 "Car" 的宠物猫(没错,有些人真的会这样给猫起名!)。
你将创建 3 个文件:
Vehicle/Car.php:在Vehicle命名空间中定义一个Car类,并添加一个public $brand属性。构造函数应接收品牌名称并设置该属性。添加一个describe()方法,返回"Vehicle: [brand]"。Animal/Car.php:在Animal命名空间中定义一个Car类(这是一只名叫 Car 的猫!)。它应包含一个public $age属性。构造函数接收年龄并设置该属性。添加一个describe()方法,返回"Cat named Car, age: [age]"。main.php:使用require_once引入两个类文件。使用完整的命名空间路径分别创建一个对象,然后打印对每个对象调用describe()的结果(每个结果单独占一行)。
在 main.php 中,创建:
- 一个品牌为
"Toyota"的Vehicle\Car - 一个年龄为
3的Animal\Car
创建对象时,记得使用反斜杠 \,通过完整路径引用命名空间中的类。
亲手试试
<?php
// 引入类文件
require_once 'Vehicle/Car.php';
require_once 'Animal/Car.php';
// TODO: 创建一个品牌为 "Toyota" 的 Vehicle\Car 对象
// 记得使用带反斜杠的完整命名空间路径
// TODO: 创建一个年龄为 3 的 Animal\Car 对象
// 记得使用带反斜杠的完整命名空间路径
// TODO: 打印每个对象的 describe() 结果,每个结果各占一行
?>这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: PHP 在线编译器