문제

요즘 대부분의 웹 개발자와 마찬가지로 저는 웹 앱 및 사이트에 대한 견고한 MVC 아키텍처의 이점을 철저히 즐기고 있습니다. PHP로 MVC를 수행 할 때 자동로드는 분명히 매우 편리합니다.

나는 팬이되었습니다 spl_autoload_register 단순히 싱글을 정의합니다 __autoload() 기능적으로, 각각 자체 자동 로딩을 사용하는 다른 기본 모듈을 통합하는 경우 기능이 분명히 유연합니다. 그러나 나는 내가 쓴 로딩 기능에 대해 결코 기분이 좋지 않았습니다. 로드 할 수있는 클래스를 찾기 위해 많은 문자열 검사 및 디렉토리 스캔이 포함됩니다.

예를 들어, 기본 경로가 다음과 같이 정의 된 앱이 있다고 가정 해 봅시다. PATH_APP, 디렉토리가있는 간단한 구조 models, views 그리고 controllers. 나는 종종 파일이 명명 된 이름 지정 구조를 사용합니다. IndexView.php 그리고 IndexController.php 적절한 디렉토리 내부 및 모델에는 일반적으로 기본적으로 특정 체계가 없습니다. 이 구조에 대한 로더 기능이 등록되는이 구조에 대한 로더 기능이있을 수 있습니다. spl_autoload_register:

public function MVCLoader($class)
{
    if (file_exists(PATH_APP.'/models/'.$class.'.php')) {
        require_once(PATH_APP.'/models/'.$class.'.php');
        return true;
    }
    else if (strpos($class,'View') !== false) {
        if (file_exists(PATH_APP.'/views/'.$class.'.php')) {
            require_once(PATH_APP.'/views/'.$class.'.php');
            return true;
        }
    }
    else if (strpos($class,'Controller') !== false) {
        if (file_exists(PATH_APP.'/controllers/'.$class.'.php')) {
            require_once(PATH_APP.'/controllers/'.$class.'.php');
            return true;
        }
    }
    return false;
}

그 후 발견되지 않은 경우 모델 디렉토리에서 하위 다이렉터를 스캔하는 다른 기능이있을 수 있습니다. 그러나 모든 if/else-ing, 문자열 검사 및 디렉토리 스캔은 나에게 비효율적 인 것처럼 보이며 개선하고 싶습니다.

다른 개발자가 다른 개발자가 사용할 수있는 파일 이름 지정 및 자동로드 전략이 매우 궁금합니다. 나는 효율적인 자동 로딩을 위해 사용하는 좋은 기술을 고용하고 자동로드에 대한 대안이 아니라 특별히 찾고 있습니다.

도움이 되었습니까?

해결책

이것이 제가 모든 프로젝트에서 사용한 것입니다 (마지막 프로젝트의 출처에서 바로 들어 올렸습니다).

public static function loadClass($class)
{
    $files = array(
        $class . '.php',
        str_replace('_', '/', $class) . '.php',
    );
    foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $base_path)
    {
        foreach ($files as $file)
        {
            $path = "$base_path/$file";
            if (file_exists($path) && is_readable($path))
            {
                include_once $path;
                return;
            }
        }
    }
}

someclass_seperatedwith_underscores를 찾으면 someclass_seperatedwith_underscores.php에 이어 Someclass/seperatedwith/inderscores.php가 현재 포함 된 경로의 각 디렉토리에 루팅됩니다.

편집하다: 나는 단지 개발의 효율성을 위해 이것을 사용하고 반드시 처리 시간이 필요하지는 않다는 것을 거기에두고 싶었습니다. 당신이 당신의 길에 배를 가지고 있다면, 당신은 클래스를 사용할 수 있고 필요할 때 그것들을 포함 할 필요가 없습니다.

나는 네임 스페이스를 분해하는 밑줄과 함께 수업을 계층 구조로 유지하는 경향이 있습니다.이 코드는 파일 구조를 원한다면 파일 구조를 멋지고 깔끔하게 유지하거나 원하는 경우 중첩 된 디렉토리없이 빠른 클래스 파일을 주입 할 수 있습니다. 피고인이지만 현재 진행중인 프로젝트의 일부는 아니지만 단일 클래스 또는 2 개를 도서관에 추가합니다.)

다른 팁

이 솔루션에 착륙했습니다.

클래스 라이브러리 폴더 (별도의 모듈 / 시스템에 대한 서브 폴더가 포함 된)를 통과하는 단일 스크립트를 만들고 클래스 정의를 찾는 파일 내용을 구문 분석했습니다. PHP 파일 (매우 간단한 Regex 패턴)에서 클래스 정의를 찾으면 Symlink를 만듭니다.

class_name.php -> actual/source/file.php

이를 통해 클래스 이름과 기본 Symlink 폴더로의 경로 만 필요한 단일의 간단한 자동로드 함수를 사용할 수 있으며 경로/문자열 조작을 수행 할 필요가 없습니다.

가장 좋은 점은 소스 코드를 완전히 재 배열하거나 새 서브 시스템을 추가하고 모든 것을 자동 으로드하도록 링크 생성 스크립트를 실행할 수 있다는 것입니다.

효율성을 원한다면 자동로드 기능을 전혀 사용해서는 안됩니다. 자동로드 기능은 게으른 것입니다. 포함 할 때 포함 된 파일에 대한 명백한 경로를 제공해야합니다. 자동로드 기능에서 이러한 파일을 찾을 수있는 경우 코드를 명시 적으로 찾을 수 있습니다. 코드의보기 부분에서 작업하고 새로운보기 클래스를로드하려고 할 때 자동로드 함수가 처리하도록하여 먼저 클래스가 모델 클래스라고 가정합니까? 비효율적입니다. 대신 코드는 다음과 같아야합니다.

include_once $this->views_path . $class . '.php';

여러 "보기"경로가 필요한 경우 뷰를로드하는 함수를 만드십시오.

public function load_view($class) {
    // perhaps there's a mapping here instead....
    foreach ($this->views_paths as $path) {
        $filename = $path . $class . '.php';
        if (file_exists($filename)) {
            include_once $filename;
        }
    }
    throw ....
}

어쨌든 포함이 발생하는 시점에서로드하려는 클래스에 대한 가장 큰/가장 정확한 정보가 있습니다. 해당 정보를 사용하여 클래스를 완전히로드하는 것은 유일한 효율적인 클래스 로딩 전략입니다. 그렇습니다. 더 많은 클래스 변수 또는 일부 전 세계 변수로 끝날 수 있습니다. 그러나 그것은 단지 당신의 클래스를 위해 파일 시스템의 부분을 스캔하는 것보다 더 나은 트레이드 오프입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top