많은 수의 파일이 다른 클래스를 사용해야 하는 경우 각 파일에 올바른 클래스 파일이 포함되어 있는지 확인하는 것은 확실히 악몽이 될 것입니다. PHP5는 클래스 자동 로드 메커니즘으로 이 문제에 대한 솔루션을 제공합니다. 자동 로드 메커니즘을 사용하면 처음부터 모든 클래스 파일을 포함하는 대신 PHP 프로그램이 클래스를 사용할 때만 클래스 파일을 자동으로 포함할 수 있습니다. 이 메커니즘을 지연 로딩이라고도 합니다. 다음은 자동 로드 메커니즘을 사용하여 Person 클래스를 로드하는 예입니다. /* autoload.php */
function __autoload($classname) {
일반적으로 PHP5는 클래스를 사용할 때 클래스가 로드되지 않은 것을 발견하면 자동으로 __autoload() 함수를 실행합니다. 이 함수에서는 사용해야 하는 클래스를 로드할 수 있습니다. 간단한 예에서는 ".class.php" 확장자를 사용하여 클래스 이름을 직접 추가하여 클래스 파일 이름을 구성한 다음 require_once를 사용하여 로드합니다. 이 예에서 자동 로드는 최소한 세 가지 작업을 수행해야 함을 알 수 있습니다. 먼저 클래스 이름을 기준으로 클래스 파일 이름을 결정합니다. 두 번째는 클래스 파일이 있는 디스크 경로를 결정하는 것입니다(우리의 경우 가장 간단한 경우 클래스는 이를 호출하는 PHP 프로그램 파일과 동일한 폴더에 있습니다). 세 번째는 디스크 파일의 클래스를 시스템으로 로드하는 것입니다. 세 번째 단계는 가장 간단합니다. include/require를 사용하면 됩니다.첫 번째와 두 번째 단계의 기능을 구현하려면 개발 중에 클래스 이름과 디스크 파일 간의 매핑 방법을 합의해야 합니다. 그래야만 클래스 이름을 기반으로 해당 디스크 파일을 찾을 수 있습니다. 따라서 포함할 클래스 파일 수가 많은 경우 해당 규칙만 결정한 다음 __autoload() 함수에서 클래스 이름을 실제 디스크 파일과 일치시켜 지연 로딩을 구현하면 됩니다. 효과 . 여기서 __autoload() 함수 구현에서 가장 중요한 것은 클래스 이름과 실제 디스크 파일 간의 매핑 규칙 구현임을 알 수 있습니다. 그러나 이제 문제가 발생합니다. 시스템 구현에서 다른 많은 클래스 라이브러리를 사용해야 하는 경우 이러한 클래스 라이브러리는 다른 개발자가 작성할 수 있으며 클래스 이름과 실제 디스크 파일 간의 매핑 규칙은 그리 좋지 않습니다. 같은. 이때, 클래스 라이브러리 파일의 자동 로딩을 구현하려면 __autoload() 함수에서 모든 매핑 규칙을 구현해야 합니다. 이 경우 __autoload() 함수는 구현하기가 매우 복잡하거나 불가능할 수도 있습니다. 결국 __autoload() 함수는 매우 비대해질 수 있습니다. 구현이 가능하더라도 향후 유지 관리 및 시스템 효율성에 큰 부정적인 영향을 미칠 것입니다. 이런 경우에는 더 간단하고 명확한 해결책은 없을까요? 대답은 물론입니다: NO! 추가 솔루션을 살펴보기 전에 먼저 PHP의 자동 로드 메커니즘이 어떻게 구현되는지 살펴보겠습니다.
2. PHP 자동 로드 메커니즘 구현 PHP가 객체를 인스턴스화할 때(실제로 인터페이스를 구현할 때, 클래스에서 클래스 상수나 정적 변수를 사용하거나, 클래스에서 정적 메서드를 호출할 때) 먼저 시스템에서 클래스(또는 인터페이스)를 검색합니다. 존재하지 않으면 자동 로드 메커니즘을 사용하여 클래스를 로드해 보십시오.자동 로드 메커니즘의 주요 실행 프로세스는 다음과 같습니다. (1) 실행기 전역 변수 함수 포인터 autoload_func가 NULL인지 확인합니다. (2) autoload_func==NULL이면 시스템에 __autoload() 함수가 정의되어 있는지 확인하고 그렇지 않은 경우 오류를 보고하고 종료합니다. (3) __autoload() 함수가 정의되어 있으면 __autoload()를 실행하여 클래스 로드를 시도하고 로드 결과를 반환합니다. (4) autoload_func가 NULL이 아니면 autoload_func 포인터가 가리키는 함수를 직접 실행하여 클래스를 로드한다. 이때는 __autoload() 함수가 정의되어 있는지 확인하지 않습니다. PHP는 자동 로딩 메커니즘을 구현하는 두 가지 방법을 제공합니다. 이전에 언급한 한 가지 방법은 일반적으로 PHP 소스 프로그램에서 구현되는 사용자 정의 __autoload() 함수를 사용하는 것입니다. 다른 하나는 함수를 설계하고 이를 가리키는 autoload_func 포인터를 지정하는 것입니다. 이는 일반적으로 C 언어를 사용하는 PHP 확장에서 구현됩니다. __autoload() 함수와 autoload_func가 모두 구현된 경우(autoload_func가 특정 PHP 함수를 가리킴) autoload_func 함수만 실행됩니다.
3. SPL 자동 로드 메커니즘 구현 SPL은 Standard PHP Library의 약자입니다.PHP5에 도입된 확장 라이브러리입니다. 주요 기능에는 자동 로드 메커니즘과 다양한 Iterator 인터페이스 또는 클래스의 구현이 포함됩니다. SPL 자동 로드 메커니즘은 자동 로드 기능이 있는 자체 구현 함수에 함수 포인터 autoload_func를 지정하여 구현됩니다. SPL에는 spl_autoload와 spl_autoload_call이라는 두 가지 서로 다른 함수가 있습니다. autoload_func를 이 두 가지 함수 주소로 지정하여 서로 다른 자동 로딩 메커니즘을 구현합니다. spl_autoload는 SPL에서 구현한 기본 자동 로딩 기능이며, 그 기능은 비교적 간단합니다. 두 개의 매개변수를 받을 수 있습니다. 첫 번째 매개변수는 클래스 이름을 나타내는 $class_name이고, 두 번째 매개변수 $file_extensions는 선택사항으로 클래스 파일의 확장자를 나타냅니다. $file_extensions에는 여러 확장자를 지정할 수 있으며, 확장자 이름은 세미콜론으로 구분할 수 있습니다. 지정하지 않으면 기본 확장자 .inc 또는 .php가 사용됩니다. spl_autoload는 먼저 $class_name을 소문자로 변경한 다음 모든 포함 경로에서 $class_name.inc 또는 $class_name.php 파일을 검색하고($file_extensions 매개변수가 지정되지 않은 경우) 발견되면 클래스 파일을 로드합니다. spl_autoload("Person", ".class.php")를 수동으로 사용하여 Person 클래스를 로드할 수 있습니다. 실제로 여러 확장을 지정할 수 있다는 점을 제외하면 require/include와 유사합니다. spl_autoload가 자동으로 작동하도록 하는 방법, 즉 autoload_func에서 spl_autoload를 지정하는 방법은 무엇입니까? 대답은 spl_autoload_register 함수를 사용하는 것입니다. 매개 변수 없이 PHP 스크립트에서 처음으로 spl_autoload_register()를 호출하면 autoload_func에서 spl_autoload를 지정할 수 있습니다. 위의 설명을 통해 spl_autoload의 기능은 비교적 간단하고 SPL 확장에 구현되어 있으며 해당 기능을 확장할 수 없다는 것을 알 수 있습니다. 보다 유연한 자동 로딩 메커니즘을 구현하고 싶다면 어떻게 해야 할까요? 이때 spl_autoload_call 기능이 데뷔합니다. 먼저 spl_autoload_call 구현의 놀라운 기능을 살펴보겠습니다. SPL 모듈 내부에는 본질적으로 HashTable인 전역 변수 autoload_functions가 있지만 간단히 연결 목록으로 생각할 수 있습니다. 연결 목록의 각 요소는 다음과 같은 기능을 가진 함수를 가리키는 함수 포인터입니다. 자동으로 클래스를 로드하는 기능입니다. spl_autoload_call 구현 자체는 매우 간단하며, 단순히 연결 리스트에 있는 각 함수를 순서대로 실행한 후, 필요한 클래스가 로드되었는지 판단하여 로딩에 성공하면 바로 반환을 하게 됩니다. 연결된 목록의 다른 기능을 계속 실행합니다. 이 연결된 목록의 모든 함수가 실행된 후에도 클래스가 로드되지 않은 경우 spl_autoload_call은 사용자에게 오류를 보고하지 않고 직접 종료됩니다. 따라서 자동 로드 메커니즘을 사용한다고 해서 클래스가 자동으로 올바르게 로드되는 것은 아닙니다. 핵심은 여전히 자동 로드 기능이 구현되는 방식에 따라 달라집니다. 그럼 자동 로딩 기능 목록 autoload_functions는 누가 관리하나요? 앞서 언급한 spl_autoload_register 함수입니다. 이 연결 목록에 사용자 정의 자동 로딩 함수를 등록하고 autoload_func 함수 포인터를 spl_autoload_call 함수에 지정할 수 있습니다. spl_autoload_unregister 함수를 통해 autoload_functions 연결 목록에서 등록된 함수를 삭제할 수도 있습니다. 이전 섹션에서 언급했듯이 autoload_func 포인터가 null이 아니면 __autoload() 함수가 자동으로 실행되지 않습니다. 이제 autoload_func가 spl_autoload_call을 가리켰습니다. 여전히 __autoload() 함수를 원한다면 어떻게 해야 할까요? 일하러? 물론, autoload_functions 연결 목록에 등록하려면 여전히 spl_autoload_register(__autoload) 호출을 사용하세요. 이제 첫 번째 섹션의 마지막 질문으로 돌아가서 해결책이 있습니다. 각 클래스 라이브러리의 다양한 명명 메커니즘에 따라 자체 자동 로딩 기능을 구현한 다음 spl_autoload_register를 사용하여 SPL 자동 로딩 기능 대기열에 각각 등록하는 것입니다. 훌륭해요. 이렇게 하면 매우 복잡한 __autoload 기능을 유지할 필요가 없습니다. 4. 오토로드 효율 문제 및 대책 자동 로드 메커니즘을 사용할 때 많은 사람들의 첫 번째 반응은 자동 로드를 사용하면 시스템 효율성이 떨어진다는 것입니다. 어떤 사람들은 효율성을 위해 자동 로드를 사용하지 말라고 제안하기도 합니다. 자동 로드 구현의 원리를 이해한 후에는 자동 로드 메커니즘 자체가 시스템 효율성에 영향을 미치는 이유가 아니라는 것을 알게 됩니다. 자동 로드는 불필요한 클래스를 시스템에 로드하지 않기 때문에 시스템 효율성을 향상시킬 수도 있습니다. 그렇다면 많은 사람들이 자동 로드를 사용하면 시스템 효율성이 떨어진다고 생각하는 이유는 무엇일까요? 사실 자동 로드 메커니즘의 효율성에 영향을 미치는 것은 바로 사용자가 설계한 자동 로드 기능입니다. 클래스 이름과 실제 디스크 파일을 효율적으로 일치시킬 수 없는 경우(참고, 이는 파일 이름뿐만 아니라 실제 디스크 파일을 의미함) 시스템은 파일이 존재하는지(이는 ) 파일이 존재하는지 확인하려면 디스크 I/O 작업이 필요합니다. 우리 모두 알고 있듯이 디스크 I/O 작업의 효율성이 매우 낮기 때문에 이것이 효율성을 저하시키는 원인입니다. 자동 로드 메커니즘 ! 따라서 시스템을 설계할 때 클래스 이름을 실제 디스크 파일에 매핑하는 명확한 메커니즘을 정의해야 합니다. 이 규칙이 더 간단하고 명확할수록 자동 로드 메커니즘은 더 효율적입니다. 결론: 자동 로드 메커니즘은 본질적으로 비효율적입니다. 자동 로드의 남용과 잘못 설계된 자동 로드 기능만이 효율성 감소로 이어질 것입니다. |