PHP 클래스의 자동 로딩 및 네임스페이스에 대한 간략한 분석
浅析PHP类的自动加载和命名空间
php是使用require(require_once)和include(include_once)关键字加载类文件。但是在实际的开发工程中我们基本上不会去使用这些关键字去加载类。 因为这样做会使得代码的维护相当的困难。实际的开发中我们会在文件的开始位置用use关键字使用类,然后直接new这个类就可以了. 至于类是怎么加载的,一般都是框架或者composer去实现的。
<?php use Illuminate\Container\Container; $container = new Container();
自动加载
我们可以通过一段伪代码来模拟一下在类的实例化工程中类是如何工作的
function instance($class) { // 如果类已加载则返回其实例 if (class_exists($class, false)) { return new $class(); } // 查看 autoload 函数是否被用户定义 if (function_exists('__autoload')) { __autoload($class); // 最后一次加载类的机会 } // 再次检查类是否存在 if (class_exists($class, false)) { return new $class(); } else { // 系统:我实在没辙了 throw new Exception('Class Not Found'); } }
php在语言层面提供了**__autoload** 魔术方法给用户来实现自己的自动加载逻辑。当用户去new一个类的时候,如果该类没有被加载,php会在抛出错误前调用**__autoload方法去加载类。下面的例子中的__autoload**方法只是简单的输出要加载类的名称, 并没有去实际的加载对应的类, 所以会抛出错误。
<?php use Illuminate\Container\Container; $container = new Container(); function __autoload($class) { /* 具体处理逻辑 */ echo $class;// 简单的输出要加载类的名称 } /** *
运行结果
Illuminate\Container\Container Fatal error: Uncaught Error: Class 'Illuminate\Container\Container' not found in D:\project\php\laravel_for_ci_cd\test\ClassLoader.php:5 Stack trace: #0 {main} thrown in D:\project\php\laravel_for_ci_cd\test\ClassLoader.php on line 5 */
明白了 **__autoload** 函数的工作原理之后,我们来用它去实现一个最简单自动加载。我们会有index.php和Person.php两个文件在同一个目录下。
//index.php <?php function __autoload($class) { // 根据类名确定文件名 $file = './'.$class . '.php'; if (file_exists($file)) { include $file; // 引入PHP文件 } } new Person(); /*---------------------分割线-------------------------------------*/ //Person.php class Person { // 对象实例化时输出当前类名 function __construct() { echo '<h1>' . __CLASS__ . '</h1>'; } } /**运行结果 * 输出 <h1>Person</h1> */
命名空间
命名空间并不是什么新鲜的事务,很多语言都早就支持了这个特性(只是叫法不相同),它主要解决的一个问题就是命名冲突! 就好像日常生活中很多人都会重名,我们必须要通过一些标识来区分他们的不同。比如说现在我们要用php介绍一个叫张三的人 ,他在财务部门工作。我们可以这样描述。
namespace 财务部门; class 张三 { function __construct() { echo '财务部门的张三'; } }
这就是张三的基本资料 , namespace是他的部门标识,class是他的名称. 这样大家就可以知道他是财务部门的张三而不是工程部门的张三。
非限定名称,限定名称和完全限定名称
1.非限定名称,或不包含前缀的类名称,例如 $comment = new Comment(); 如果当前命名空间是Blog\Article,Comment将被解析为、\Blog\Article\Comment。如果使用Comment的代码不包含在任何命名空间中的代码(全局空间中),则Comment会被解析为\Comment。
注意: 如果文件的开头有使用use关键字 use one\two\Comment; 则Comment会被解析为 **one\two\Comment**。
2.限定名称,或包含前缀的名称,例如 $comment = new Article\Comment(); 如果当前的命名空间是Blog,则Comment会被解析为\Blog\Article\Comment。如果使用Comment的代码不包含在任何命名空间中的代码(全局空间中),则Comment会被解析为\Article\Comment。
3.完全限定名称,或包含了全局前缀操作符的名称,例如 $comment = new \Article\Comment(); 在这种情况下,Comment总是被解析为\Article\Comment。
spl_autoload
接下来让我们要在含有命名空间的情况下去实现类的自动加载。我们使用 spl_autoload_register() 函数来实现,这需要你的 PHP 版本号大于 5.12。spl_autoload_register函数的功能就是把传入的函数(参数可以为回调函数或函数名称形式)注册到 SPL __autoload 函数队列中,并移除系统默认的 **__autoload()** 函数。一旦调用 spl_autoload_register() 函数,当调用未定义类时,系统就会按顺序调用注册到 spl_autoload_register() 函数的所有函数,而**不是自动调用 __autoload()** 函数。
现在, 我们来创建一个 Linux 类,它使用 os 作为它的命名空间(建议文件名与类名保持一致):
<?php namespace os; // 命名空间 class Linux // 类名 { function __construct() { echo '<h1>' . __CLASS__ . '</h1>'; } }
接着,在同一个目录下新建一个 index.php文件,使用 spl_autoload_register 以函数回调的方式实现自动加载:
<?php spl_autoload_register(function ($class) { // class = os\Linux /* 限定类名路径映射 */ $class_map = array( // 限定类名 => 文件路径 'os\\Linux' => './Linux.php', ); /* 根据类名确定文件路径 */ $file = $class_map[$class]; /* 引入相关文件 */ if (file_exists($file)) { include $file; } }); new \os\Linux();
这里我们使用了一个数组去保存类名与文件路径的关系,这样当类名传入时,自动加载器就知道该引入哪个文件去加载这个类了。但是一旦文件多起来的话,映射数组会变得很长,这样的话维护起来会相当麻烦。如果命名能遵守统一的约定,就可以让自动加载器自动解析判断类文件所在的路径。接下来要介绍的PSR-4 就是一种被广泛采用的约定方式
PSR-4规范
PSR-4 是关于由文件路径自动载入对应类的相关规范,规范规定了一个完全限定类名需要具有以下结构:
<顶级命名空间>(<子命名空间>)*<类名>
PSR-4 规范中必须要有一个顶级命名空间,它的意义在于表示某一个特殊的目录(文件基目录)。子命名空间代表的是类文件相对于文件基目录的这一段路径(相对路径),类名则与文件名保持一致(注意大小写的区别)。
举个例子:在全限定类名 \app\view\news\Index 中,如果 app 代表 C:\Baidu,那么这个类的路径则是 C:\Baidu\view\news\Index.php.我们就以解析 \app\view\news\Index 为例,编写一个简单的 Demo:
<?php $class = 'app\view\news\Index'; /* 顶级命名空间路径映射 */ $vendor_map = array( 'app' => 'C:\Baidu', ); /* 解析类名为文件路径 */ $vendor = substr($class, 0, strpos($class, '\\')); // 取出顶级命名空间[app] $vendor_dir = $vendor_map[$vendor]; // 文件基目录[C:\Baidu] $rel_path = dirname(substr($class, strlen($vendor))); // 相对路径[/view/news] $file_name = basename($class) . '.php'; // 文件名[Index.php] /* 输出文件所在路径 */ echo $vendor_dir . $rel_path . DIRECTORY_SEPARATOR . $file_name;
更多PHP相关知识,请访问PHP中文网!
위 내용은 PHP 클래스의 자동 로딩 및 네임스페이스에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP 오류 해결: 지정된 네임스페이스 클래스를 찾을 수 없습니다. PHP를 사용하여 개발할 때 다양한 오류 메시지가 자주 발생합니다. 일반적인 오류 중 하나는 "지정된 네임스페이스 클래스를 찾을 수 없습니다"입니다. 이 오류는 일반적으로 가져온 클래스 파일이 제대로 네임스페이스를 참조하지 않기 때문에 발생합니다. 이 문서에서는 이 문제를 해결하는 방법을 설명하고 몇 가지 코드 예제를 제공합니다. 먼저 일반적인 오류 메시지의 예를 살펴보겠습니다. Fatalerror:UncaughtError:C

Redis는 오픈 소스 고성능 키-값 스토리지 데이터베이스입니다. 데이터 스토리지로 Redis를 사용할 때 Redis의 성능과 데이터 무결성을 유지하기 위해 키 네임스페이스 및 만료 메커니즘의 설계를 고려해야 합니다. 이 글에서는 Redis의 네임스페이스와 만료 메커니즘의 디자인 아이디어와 구현 방법을 소개합니다. 1. Redis 네임스페이스 디자인 아이디어 Redis에서는 키를 임의로 설정할 수 있습니다. 다양한 데이터 유형의 관리 및 구별을 용이하게 하기 위해 Redis는 네임스페이스 개념을 도입합니다. 삶

F3 프레임워크는 간단하고 사용하기 쉽고 유연하며 확장 가능한 PHPWeb 프레임워크입니다. 네임스페이스(Namespace) 메커니즘은 보다 표준화되고 읽기 쉽고 명확한 코드 구조를 제공합니다. 이 기사에서는 F3 프레임워크에서 네임스페이스를 사용하는 방법을 살펴보겠습니다. 1. 네임스페이스란 무엇입니까? 네임스페이스는 PHP에서 이름 지정 충돌 문제를 해결하는 데 자주 사용됩니다. 네임스페이스는 하나 이상의 클래스, 함수 또는 상수를 네임스페이스에 캡슐화할 수 있으며 이는 접두사를 추가하는 것과 같습니다. 예

C++는 널리 사용되는 고급 프로그래밍 언어로 유연성과 확장성이 뛰어나지만 오류를 방지하려면 개발자가 문법 규칙을 엄격하게 숙지해야 합니다. 일반적인 오류 중 하나는 "정의되지 않은 네임스페이스 사용"입니다. 이 문서에서는 이 오류의 의미, 발생 이유, 해결 방법에 대해 설명합니다. 1. 정의되지 않은 네임스페이스의 용도는 무엇입니까? C++에서 네임스페이스는 모듈화되고 읽기 쉬운 상태로 유지하기 위해 재사용 가능한 코드를 구성하는 방법입니다. 네임스페이스를 사용하여 동일한 이름을 가진 함수를 만들 수 있습니다.

PHP 언어가 점점 대중화되면서 개발자는 점점 더 많은 클래스와 함수를 사용해야 합니다. 프로젝트 규모가 커지면 모든 종속성을 수동으로 도입하는 것은 실용적이지 않습니다. 이때 코드 개발 및 유지 관리 프로세스를 단순화하려면 자동 로딩 메커니즘이 필요합니다. 자동 로딩 메커니즘은 런타임에 필요한 클래스와 인터페이스를 자동으로 로드하고 수동 클래스 파일 도입을 줄일 수 있는 PHP 언어의 기능입니다. 이를 통해 프로그래머는 코드 개발에 집중할 수 있으며, 지루한 매뉴얼 수업 도입으로 인한 오류와 시간 낭비를 줄일 수 있습니다. PHP에서는 일반적으로

PHP8의 새로운 기능 예: 네임스페이스와 코드를 사용하여 코드 구조를 더 잘 구성하는 방법은 무엇입니까? 소개: PHP8은 PHP 프로그래밍 언어의 중요한 버전으로, 많은 흥미로운 새 기능과 개선 사항을 도입했습니다. 가장 중요한 새로운 기능 중 하나는 네임스페이스입니다. 네임스페이스는 동일한 이름을 가진 클래스, 함수 및 상수 간의 충돌을 방지하는 더 나은 구조로 코드를 구성하는 방법입니다. 이 글에서는 네임스페이스와 코드를 활용하여 PHP8 코드를 더 효과적으로 구성하는 방법을 살펴보겠습니다.

개발자가 자신의 이름 지정 범위를 만들고 이름 충돌을 방지할 수 있도록 네임스페이스를 사용하여 사용자 정의 함수를 관리하는 것이 중요합니다. 단계에는 네임스페이스 만들기, use 문을 사용하여 네임스페이스 가져오기, 네임스페이스 함수 호출이 포함됩니다. 실제 사례에서 MyMath 확장은 네임스페이스를 사용하여 수학 함수를 구성하여 가독성과 유지 관리성을 향상시키는 방법을 보여줍니다.

PHP7의 네임스페이스와 자동 로딩 메커니즘을 사용하여 코드 구조를 구성하는 방법은 무엇입니까? 개요: PHP7이 출시되면서 네임스페이스와 자동 로딩 메커니즘은 PHP 개발에서 무시할 수 없는 중요한 기능이 되었습니다. 이 기사에서는 PHP7의 네임스페이스와 자동 로딩 메커니즘을 사용하여 코드 구조를 구성하는 방법을 소개하고 특정 코드 예제를 통해 이를 설명합니다. 1. 네임스페이스란 무엇입니까? 네임스페이스는 서로 다른 클래스 라이브러리나 코드 파일 간에 발생할 수 있는 이름 지정 충돌을 해결하기 위해 PHP7에 도입된 메커니즘입니다. 네임스페이스를 통해
