blazebattle
118.04 MB · 2025-10-24
想象你在学校点名:
这就叫:重名冲突。
在 PHP 中,如果两个类都叫 User,就会出错:
class User { } // 用户类
class User { } // 学生类 ❌ 报错!不能重复定义
怎么办?—— 给它们“贴标签”!
命名空间(Namespace)就是给类、函数、常量起“全名”的方式。
比如:
namespace Admin;
class User { } // 全名是:AdminUser
namespace Student;
class User { } // 全名是:StudentUser
<?php
namespace 项目名模块名子模块;
class User { }
function login() { }
const VERSION = '1.0';
? 注意:
<?php 之后)MyAppAdminAuth就像公司分部门:
namespace MyProjectUser; // 用户部
namespace MyProjectOrder; // 订单部
namespace MyProjectPayment; // 支付部
好处:
? 文件夹建议对应命名空间:
src/
└── User/
└── UserService.php → namespace MyProjectUser;
假设你在 MyProjectOrder 这个“办公室”里。
| 写法 | 类型 | 含义 | 比喻 |
|---|---|---|---|
User::login() | 非限定 | 找 MyProjectOrderUser | “叫小明!”(默认是本部门的) |
UserUser::login() | 限定 | 找 MyProjectOrderUserUser | “叫用户组的小明!” |
MyProjectUserUser::login() | 完全限定 | 绝对路径,从根找 | “总部三楼的小明!” |
如果你覆盖了 PHP 内置函数,想调原始的怎么办?
function strlen($str) { return 0; } // 自己写的
strlen("hello"); // ❌ 调的是自己的
strlen("hello"); // ✅ 调全局的内置函数
✅ 所有全局类、函数、常量都可以加 `` 调用:
DateTime::createFromFormat(...);
Exception("错误");
INI_ALL;
全名太长?可以用 use 简化:
<?php
namespace MyApp;
use MyProjectDatabaseConnection as DB;
use function MyProjectUtilshelper as help;
use const MyProjectConfigHOST as SERVER;
// 使用别名
$db = new DB(); // 相当于 new MyProjectDatabaseConnection
help(); // 相当于 MyProjectUtilshelper()
echo SERVER; // 相当于 MyProjectConfigHOST
? use 必须写在 namespace 之后,其他代码之前。
有时候名字是“变量”,比如:
$className = "MyProjectUserUser";
$obj = new $className(); // ✅ 可以!
$funcName = "MyProjecthelp";
$funcName(); // ✅ 可以!
echo constant("MyProjectVERSION"); // ✅ 读常量
在动态调用中:
"MyProjectUser" 和 "MyProjectUser" 效果一样__NAMESPACE__ 和 namespace 关键字这是两个“定位工具”,帮你更灵活地写代码。
__NAMESPACE__:GPS 定位器返回当前命名空间的名字(字符串):
namespace MyProjectOrder;
echo __NAMESPACE__;
// 输出:MyProjectOrder
用途:动态拼类名
$full = __NAMESPACE__ . 'User';
$obj = new $full; // new MyProjectOrderUser
namespace 关键字:指南针用来“从当前空间出发”访问元素,类似 self:
namespacelogin(); // 调当前空间的 login 函数
namespaceUser::find(1); // 调当前空间的 User 类
$obj = new namespaceOrder(); // 创建当前空间的 Order 对象
$version = namespaceVERSION; // 获取当前空间的常量
? 它让你不用写死全名,更安全、更灵活。
PHP 允许,但非常不推荐!
<?php
namespace MyProject {
class User { }
}
namespace YourProject {
class User { }
}
namespace { // 全局代码
echo "这是公共代码";
}
<?php
namespace A;
class User {}
namespace B;
class User {} // 混乱,易出错
? 使用场景:
| 错误 | 正确做法 |
|---|---|
在命名空间外直接写 echo | 放进 namespace { } 或移到外面 |
| 非静态方法当函数调用 | 要 new 对象 或 加 static |
use 写错位置 | 必须在 namespace 后,其他代码前 |
| 文件编码问题 | 推荐 UTF-8,可用 declare(encoding='UTF-8'); |
use 简化长名字根空间
├── AdminUser → AdminUser
├── StudentUser → StudentUser
├── MyProjectOrder → 当前空间
├── User → 非限定:User → MyProjectOrderUser
├── PaymentPay → 限定:PaymentPay → MyProjectOrderPaymentPay
└── GlobalFun → 完全限定:绝对路径