[php] 자동로드와 함께 PHP 네임 스페이스를 어떻게 사용합니까?

자동로드 및 네임 스페이스를 사용하려고하면이 오류가 발생합니다.

치명적인 오류 : 10 행의 /usr/local/www/apache22/data/public/php5.3/test.php 에서 ‘Class1’클래스를 찾을 수 없습니다.

아무도 내가 뭘 잘못하고 있는지 말해 줄 수 있습니까?

내 코드는 다음과 같습니다.

Class1.php :

<?php

namespace Person\Barnes\David
{
    class Class1
    {
        public function __construct()
        {
            echo __CLASS__;
        }
    }
}

?>

test.php :

<?php

function __autoload($class)
{
    require $class . '.php';
}

use Person\Barnes\David;

$class = new Class1();

?>



답변

Class1은 전역 범위에 없습니다.

작동 예는 아래를 참조하십시오.

<?php

function __autoload($class)
{
    $parts = explode('\\', $class);
    require end($parts) . '.php';
}

use Person\Barnes\David as MyPerson;

$class = new MyPerson\Class1();

편집 (2009-12-14) :

명확히하기 위해 “use … as”를 사용하여 예제를 단순화했습니다.

대안은 다음과 같습니다.

$class = new Person\Barnes\David\Class1();

또는

use Person\Barnes\David\Class1;

// ...

$class = new Class1();


답변

Pascal MARTIN에서 언급했듯이 ‘\’를 DIRECTORY_SEPARATOR로 바꿔야합니다. 예를 들면 다음과 같습니다.

$filename = BASE_PATH . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
include($filename);

또한 코드를 더 읽기 쉽게 만들기 위해 디렉토리 구조를 재구성하는 것이 좋습니다. 이것은 대안이 될 수 있습니다.

디렉토리 구조 :

ProjectRoot
 |- lib

파일: /ProjectRoot/lib/Person/Barnes/David/Class1.php

<?php
namespace Person\Barnes\David
class Class1
{
    public function __construct()
    {
        echo __CLASS__;
    }
}
?>
  • 정의한 각 네임 스페이스에 대한 하위 디렉터리를 만듭니다.

파일: /ProjectRoot/test.php

define('BASE_PATH', realpath(dirname(__FILE__)));
function my_autoloader($class)
{
    $filename = BASE_PATH . '/lib/' . str_replace('\\', '/', $class) . '.php';
    include($filename);
}
spl_autoload_register('my_autoloader');

use Person\Barnes\David as MyPerson;
$class = new MyPerson\Class1();
  • 자동 로더 선언에 PHP 5 권장 사항을 사용했습니다. 여전히 PHP 4를 사용하는 경우 이전 구문으로 바꾸십시오. function __autoload ($ class)

답변

귀하의 __autoload기능은 네임 스페이스 이름을 포함한 전체 클래스 이름을 받게됩니다.

즉, 귀하의 경우 __autoload함수는 ‘ Person\Barnes\David\Class1‘뿐만 아니라 ‘ Class1‘를 수신합니다.

따라서 “더 복잡한”이름을 처리하려면 자동 로딩 코드를 수정해야합니다. 자주 사용되는 솔루션은 네임 스페이스의 “수준”당 한 수준의 디렉터리를 사용하여 파일을 구성하고, 자동로드 할 때 \네임 스페이스 이름의 ‘ ‘를 DIRECTORY_SEPARATOR.


답변

다음과 같이합니다 : 이 GitHub 예제보기

spl_autoload_register('AutoLoader');

function AutoLoader($className)
{
    $file = str_replace('\\',DIRECTORY_SEPARATOR,$className);

    require_once 'classes' . DIRECTORY_SEPARATOR . $file . '.php';
    //Make your own path, Might need to use Magics like ___DIR___
}


답변

Flysystem 에서이 보석을 찾았습니다.

spl_autoload_register(function($class) {
    $prefix = 'League\\Flysystem\\';

    if ( ! substr($class, 0, 17) === $prefix) {
        return;
    }

    $class = substr($class, strlen($prefix));
    $location = __DIR__ . 'path/to/flysystem/src/' . str_replace('\\', '/', $class) . '.php';

    if (is_file($location)) {
        require_once($location);
    }
});


답변

자동로드 함수는 다음 두 가지 경우에만 “전체”클래스 이름 (앞에있는 모든 네임 스페이스 포함)을받습니다.

[a] $a = new The\Full\Namespace\CoolClass();

[b] use The\Full\Namespace as SomeNamespace; (at the top of your source file) followed by $a = new SomeNamespace\CoolClass();

다음과 같은 경우 자동로드 기능이 전체 클래스 이름을받지 못하는 것을 확인했습니다.

[c] use The\Full\Namespace; (at the top of your source file) followed by $a = new CoolClass();

업데이트 : [c]는 실수이며 어쨌든 네임 스페이스가 작동하는 방식이 아닙니다. [c] 대신 다음 두 경우도 잘 작동한다고보고 할 수 있습니다.

[d] use The\Full\Namespace; (at the top of your source file) followed by $a = new Namespace\CoolClass();

[e] use The\Full\Namespace\CoolClass; (at the top of your source file) followed by $a = new CoolClass();

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


답변

이 간단한 해킹을 한 줄로 사용합니다.

spl_autoload_register(function($name){
        require_once 'lib/'.str_replace('\\','/',$name).'.php';
    });