>  기사  >  백엔드 개발  >  PHP에 대해 모르는 것 - 자동 로딩

PHP에 대해 모르는 것 - 자동 로딩

高洛峰
高洛峰원래의
2016-11-07 16:51:311484검색

많은 친구들이 PHP를 배울 때 가장 먼저 직면하는 문제 중 하나는 require, include 및 require_once, include_once 사이의 사랑과 죽음입니다.

그들의 사랑과 죽음에 대한 이야기를 이해한 후에는 액자를 사용하기 시작하는 경우가 많습니다. 프레임워크는 확실히 작업에 좋은 도구이지만 일반적으로 새 클래스를 새로 만들면 어떤 일이 발생하는지 알고 계십니까? 사양을 따를 때 왜 모든 것이 자동으로 로드되는지 궁금한 적이 있습니까? 신비를 탐험하고 발견해 봅시다.

타임라인

Steam Age

PHP 코드 상단에서 이런 코드를 자주 보시나요?

require 'lionis.php';
require 'is.php';
require 'cool.php';

PHP 스크립트 몇 개만 소개한다면 괜찮습니다. 수천 개의 스크립트가 도입되면 폭발은 불가피합니다. 스크립트의 이름을 변경하면 변경된 스크립트를 소개하는 각 스크립트의 이름도 변경해야합니까? 이 문장을 타이핑하는 것조차 어떻게 할 수 있나요?

전기 시대

PHP 전기 시대에는 사용자 정의 자동 로딩 전략을 등록하기 위해 __autoload 및 spl_autoload_register 함수가 나타나기 시작했습니다.

일반인의 관점에서 보면 __autoload 및 spl_autoload_register는 킬러 조직이며 다양한 국가의 킬러(기능)를 고용합니다. 누군가(신규)를 제거하고 싶을 때 이름(클래스 이름)만 제공하면 나머지 "Killer"가 이를 완료하는 데 도움이 됩니다.

__autoload

PHP 5에서는 Portal 기능을 제공하기 시작합니다. 사용하는 클래스를 찾을 수 없으면 클래스 이름을 매개변수로 이 함수에 넣습니다.

<?php// Lionis.phpclass Lionis {  
  public function __construct() {    
      echo &#39;欧耶耶, 我就是 Lionis&#39;;
    }
}
<?php
// index.php
function __autoload($classname) {
    $filename = &#39;./&#39; . $classname . &#39;.php&#39;;
    require_once $filename;
}

$lionis = new Lionis();

출력

欧耶耶, 我就是 Lionis

spl_autoload_register

우리 프로젝트가 매우 크고 오래되었거나 던지기를 좋아하는 젊은 선구자라면 다음이 필요합니다. 소개하자면 사양이 다른 것들이 있는데 모두 __autoload 함수에 넣으면 이 함수는 곧 확장될 것입니다. 게다가 __autoload는 전역적으로 고유하며 다른 사람이 사용하는 경우 오류가 발생할 수 있습니다. (사람을 죽이려면 먼저 부풀려야 한다.)

PHP 5.1.2에서는 주어진 기능을 __autoload의 구현으로 등록하여 이 기능 포털을 제공하기 시작합니다. 따라서 일부 프레임워크나 플러그인을 사용할 때 호환성을 위해 function_exists(spl_autoload_register)가 나타날 수 있습니다.

<?php
function lionisIsCoolFind($classname) {
    require &#39;./&#39; . $classname . &#39;.php&#39;;
}

// 函数
spl_autoload_register(&#39;lionisIsCoolFind&#39;);

// 匿名函数
spl_autoload_register(function($require) {
    require &#39;./&#39; . $classname . &#39;.php&#39;;
});

// 类中的函数
spl_autoload_register(array(&#39;Lionis&#39;, &#39;loadClass&#39;));

아, 이제 다양한 자동 로딩 기능을 작성할 수 있습니다.

정보화 시대

스승님, 조심하세요. 앞에 악마가 있습니다! . 우리 각자가 자체 자동 로딩 방법 세트를 구현하는 경우 각 PHP 구성 요소와 프레임워크는 고유한 자동 로더를 사용하고 각 프레임워크는 서로 다른 논리를 사용하여 PHP 클래스, 인터페이스 및 특성을 로드합니다.

일부 타사 프레임워크를 사용하는 경우 부팅 파일에서 자동 로더를 파악해야 하는데 시간이 많이 걸립니다. PHP-FIG는 이 문제를 인식하고 자동 로더를 사용할 수 있도록 구성 요소 간의 상호 운용성을 촉진하기 위해 PSR-4 사양을 사용할 것을 권장합니다.

PSR-4 规范

利用命名空间的前缀和文件系统中的目录对应起来。

映射关系为

namespace    => filePath
\Lionis\Cool => cool

带有命名空间的类

<?php // 该文件为 
cool/Real.phpnamespace \
Lionis\Cool;class Real {
}

创建一个对象

<?php// 该文件为 
index.php$lionis = new \
Lionis\Cool\Real;

这个时候,按照 PSR-4 的规范,自动加载器应该去加载 cool/ 目录下的 Real.php。

不对!那这样不是还要自己去实现 自动加载器 嘛,不然怎么 无中生有 出现 自动加载器 呢?难道官方 内置 了?

你 out 了吧,我们可以使用依赖管理器 composer 来生成 PSR-4 自动加载器。你可能会疑问,那我的旧项目没有遵循 PSR-4 规范怎么办?嘿嘿,让我们来探索发现一下 composer 是怎么解决这个问题的吧。

Composer

哦吼吼,我们这次的重点在与探究自动加载,所以 composer 的安装和使用等,就不去讨论了。

composer 自动加载设置了 4种 加载方式:

PSR-0

PSR-4

classmap

files

PSR-0

要求命名空间和目录层层对应,且可以使用 _ 作为路径分隔符,但是这会导致目录结果变得过深。

在 composer 执行 install 等操作时,composer 会把文件中的配置存储在 vendor/composer/autoload_psr0.php文件中的返回数组中。

例如:定义了Very\Good=>vendor\Lionis\IsReal\Cool,在调用 use Very\Good\Love\SomeClass,PSR-0 加载的实际目录为 vendor/Lionis/IsReal/Cool/Very/Good/Love/SomeClass.php。

对吧,这简直深得吓人,所以 PSR-0 被官方废除了。但是一些主流的框架已经实现了 PSR-0,为了向下兼容还是要实现 PSR-0。

composer.json配置:

"autoload": {
    "psr-0": {
        "Very\\Good": "vendor\Lionis\IsReal\Cool"
    }
}

PSR-4

PSR-4 是现在比较推荐的方法,用于替代 PSR-0。
与 PSR-0 不同的是,取消掉了 _ 作为分隔符和目录结构。

在 composer 执行 install 等操作时,composer 会把文件中的配置存储在 vendor/composer/autoload_psr4.php文件中的返回数组中。

例如:定义了Very\Good=>vendor\Lionis\IsReal\Cool,在调用 use Very\Good\
Love\SomeClass,PSR-4 加载的实际目录为 vendor/Lionis/IsReal/Cool/Love/SomeClass.php。

composer.json配置:

"autoload": {
    "psr-4": {
        "Very\\Good": "vendor\Lionis\IsReal\Cool"
    }
}

classmap

classmap 通过配置指定的目录和文件,在 composer 执行 install 等操作时,composer 会去扫描对应的目录下以.php结尾的文件中的 class,并存储在 vendor/composer/autoload_classmap.php文件中的返回数组中。

composer.json配置:

"autoload": {
    "classmap": [
        "Lionis/",
        "Xiaoer/" 
    ]
}

如果 Lionis 下有一个叫 VeryCool的文件,那么在vendor/composer/autoload_classmap.php 中会生成。

<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    &#39;VeryCool&#39; => $baseDir . &#39;/Lionis/VeryCool.php&#39;,
    // 其他的映射
);

files

files 就是直接简单粗暴的加载文件。在 composer 执行 install 等操作时,composer 会把文件中的配置存储在vendor/composer/autoload_static.php文件中的生成一个 $files 数组。

composer.json 配置:

"autoload": {
    "files": ["Lionis/Very/Cool.php"]
}


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.