자동로드 및 네임 스페이스를 사용하려고하면이 오류가 발생합니다.
치명적인 오류 : 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___
}
답변
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';
});