자동 로딩이란? spl_autoload, __autoload 및 spl_autoload_register를 어떻게 사용합니까?


203

고급 PHP 표준을 배우고 새롭고 유용한 방법을 구현하려고합니다. 이전 __autoload에는 각 페이지에 여러 파일을 포함하여 탈출하는 데 사용 했지만 최근에 팁을 보았습니다.__autoload manual

spl_autoload_register () 는 자동로드 클래스에 대한보다 유연한 대안을 제공합니다. 이러한 이유로 __autoload () 사용 은 권장되지 않으며 향후 더 이상 사용되지 않거나 제거 될 수 있습니다.

하지만 난 정말 구현하는 방법을 알아낼 수 없습니다 spl_autoloadspl_autoload_register

답변:


334

spl_autoload_register() PHP가 스택 / 큐에 넣고 "새 클래스"가 선언 될 때 순차적으로 호출 할 여러 함수 (또는 자체 Autoload 클래스의 정적 메소드)를 등록 할 수 있습니다.

예를 들어 :

spl_autoload_register('myAutoloader');

function myAutoloader($className)
{
    $path = '/path/to/class/';

    include $path.$className.'.php';
}

//-------------------------------------

$myClass = new MyClass();

위의 예에서 "MyClass"는 인스턴스화하려는 클래스의 이름입니다. PHP는이 이름을 문자열로 전달 spl_autoload_register()하여 변수를 선택하고 해당 클래스 / 파일을 "포함"하는 데 사용할 수 있습니다. . 결과적으로 include / require 문을 통해 해당 클래스를 포함시킬 필요가 없습니다 ...

위의 예제와 같이 인스턴스화하려는 클래스를 호출하기 만하면 spl_autoload_register()모든 클래스가있는 위치를 알아내는 자체 함수를 통해 등록했기 때문에 PHP는 해당 함수를 사용합니다.

사용하는 이점은 작성하는 모든 파일에서 자동로드 기능을 구현할 필요가없는 spl_autoload_register()것과 다릅니다 __autoload(). spl_autoload_register()또한 여러 자동로드 기능을 등록하여 자동로드 속도를 높이고 훨씬 쉽게 만들 수 있습니다.

예:

spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');

class MyAutoloader
{
    public static function ClassLoader($className)
    {
         //your loading logic here
    }


    public static function LibraryLoader($className)
    {
         //your loading logic here
    }

spl_autoload 와 관련 하여 수동 상태는 다음과 같습니다.

이 함수는의 기본 구현으로 사용됩니다 __autoload(). 다른 사항을 지정 spl_autoload_register()하지 않고 매개 변수없이 호출하면이 함수는 나중에 호출 할 때 사용됩니다 __autoload().

좀 더 실용적인 용어로, 모든 파일이 단일 디렉토리에 있고 응용 프로그램이 .php 파일뿐만 아니라 확장명이 .inc 인 사용자 정의 구성 파일을 사용하는 경우, 하나의 전략으로 모든 파일을 포함하는 디렉토리를 추가하는 것입니다 PHP의 파일에 포함 경로 (를 통해 set_include_path()).
또한 구성 파일도 필요하므로 spl_autoload_extensions()PHP가 찾고자하는 확장명을 나열하는 데 사용 합니다.

예:

set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();

spl_autoload는 __autoload()magic 메소드 의 기본 구현이므로 새 클래스를 인스턴스화하고 인스턴스화 할 때 PHP는 spl_autoload를 호출합니다.

도움이 되었기를 바랍니다...


35
이것은 답변의 역사에서 가장 좋은 답변 중 하나 일 수 있습니다. 존경. 나는 "OMG! 모두 이해가되었습니다!" 내 좋은 사람 당신 때문에 순간. 팬클럽을 시작한 것 같습니다.
Just Plain High

2
이 방법은 대체 유니버스에서도 모든 답변에 대한 최상의 답변을 제공하기 위해 spl_autoload를 매우 유용하게 추가 할 수 있습니다. "helpfully"(?)는 모든 파일 이름을 소문자로 변환합니다 (아래의 @user에 대한 주석 참조). CapitalLettersAndStuff가 마음에 들면 spl_autoload_register () 바닐라를 사용할 수 없습니다.
Just Plain High

6
@Just Plain High 나는 그 문제가 없으며 모든 수업 파일이 낙타 산입니다. BTW, 이것은 훌륭한 답변입니다. 이 게시물을 읽을 때까지 이해할 수없는 간단한 개념을 이해하는 데 도움이되었습니다. 모든 클래스 파일을 포함하는 85 (및 증가하는) 라인 포함 파일이 이제 7 라인입니다!
kyle

2
이것은 실제로 좋은 대답이지만 한 가지가 빠져 있습니다. 실제 기본 기능은 무엇입니까? 내가 아는 클래스를 사용하면 네임 스페이스를 경로로 사용하고 클래스 이름을 파일 이름으로 사용합니다. 함수와 작동하는 방식을 알 수는 없지만.
SiXoS

2
게으른로드에 파일 / 클래스가 포함된다는 (그리고 일반적으로) 이점 중 하나가 아닙니까? 이것은 대답에 의해 암시되지만 명시 적으로 언급되지 않았습니다. 나에게 이것은 귀하의 답변에 포함시키기에 완벽한 중요한 정보입니다! :)spl_autoload_register()__autoload()
rinogo

13

PHP 5.3부터 spl_autoload_register()네임 스페이스와 함께 사용할 수 있습니다. 즉, __autoload()함수를 요구하거나 포함하지 않고 프로젝트를 구성하고 PHP 클래스를 자동로드 할 수 있습니다 .

이 동작을 설명하려면 index.php 파일을 만드십시오.

<?php
spl_autoload_register();
var_dump(new Main\Application);

그런 다음 index.php 파일 옆에 Main이라는 이름의 폴더를 만듭니다. 마지막으로 Main에 위치한 Application.php라는 파일을 만들고 다음 코드를 붙여 넣습니다.

<?php namespace Main;
class Application{}

9
spl_autoload ()-따라서 spl_autoload_register ()-파일 이름을 소문자변환합니다 (버그 보고서, 탄원 및 격렬한 투표에도 불구하고). 이것은 "Main \ Application"을 찾고 있지만 spl_autoload가 "main \ application"을 찾고 있음 의미 합니다 . 낙타를 좋아한다면 나처럼 자신 만의 기능을 작성해야합니다. 여기에 좋은 스타터 예제가 있습니다 : github.com/ircmaxell/PHP-CryptLib/blob/…
Just Plain High

1
장점 : spl_autoload_register ()는 가장 빠른 자동 로딩 방법입니다. 소문자 파일 / 클래스 및 네임 스페이스에서만 작동합니다. 오늘날과 시대에는 sux가 큰 시간입니다 (CamelCase 등을 사용하도록 지시하는 옵션 없음). 그러나 namespace / classname.php 구조로 살 수 있다면 더 이상 보지 마십시오.
스탬 스터

1
spl_autoload_register()기본 구현은 상속 된 클래스를 찾을 수 없습니다. 따라서 네임 스페이스 경로를 반영하는 기본값, 소문자 파일 및 디렉토리를 사용하면 다른 클래스 (부모)를 확장하는 클래스가 없으면 모든 것이 잘 작동합니다. 그런 다음 PHP는 부모 클래스를 찾을 수 없다는 오류를 던집니다. 모두 동일한 디렉토리 / 네임 스페이스에 있습니다! 혼란스러운 것은 말 그대로 첫 번째 수준의 클래스 만 발견된다는 것이므로 spl_autoload_register()수동으로 누락 된 부모 / 상속 된 클래스를 수동으로 포함하기 위해 첫 번째 클래스 직후에 익명 함수 규칙을 사용하여 다른 함수를 사용해야했습니다 .
stamster

1

자동로드를 사용하는 방법은 다음과 같습니다. 주어진 예에서 나는 3 개의 다른 디렉토리에서 클래스를로드하려고합니다.

function namespaceAutoload($rawClass){

$class = str_replace('\\', DIRECTORY_SEPARATOR, $rawClass);

$possiblePaths[] = '..\sys\class\file.php';
$possiblePaths[] = '..\sys\class\lib\file.php';
$possiblePaths[] = '..\sys\class\class.file.inc.php';

foreach ($possiblePaths as $templatePath) {
    $path = str_replace(["\\", "file"], [DIRECTORY_SEPARATOR, $class], $templatePath);
    if (file_exists($path)) {
        require_once "$path";
        break;
    }
} spl_autoload_register("namespaceAutoload"); 

주어진 예제에서, PHP는이 세 가지 파일 이름 형식을 사용하여이 세 디렉토리에서 namespace \ class를 찾습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.