PHP 네임스페이스를 자동 로드와 함께 사용하려면 어떻게 해야 합니까?
자동 로드 및 네임스페이스를 사용하려고 하면 다음 오류가 나타납니다.
치명적인 오류: 클래스 'Class1'을(를) /usr/local/www/apache22/data/public/php5에서 찾을 수 없습니다.3/test.2010 회선
내가 뭘 잘못하고 있는지 누가 말해줄래?
코드는 다음과 같습니다.
Class1.php:
<?php
namespace Person\Barnes\David
{
class Class1
{
public function __construct()
{
echo __CLASS__;
}
}
}
?>
test.filename:
<?php
function __autoload($class)
{
require $class . '.php';
}
use Person\Barnes\David;
$class = new Class1();
?>
Class1
는 글로벌 범위에 포함되지 않습니다.
까지의 일이 해 주세요.spl_autoload_register()
PHP 5.1 php php(((((((((!
요즘에는 Composer를 사용하고 있을 것입니다.후드 아래에는 클래스 자동 로딩이 가능하도록 이 스니펫의 내용을 따릅니다.
spl_autoload_register(function ($class) {
// Adapt this depending on your directory structure
$parts = explode('\\', $class);
include end($parts) . '.php';
});
완성도를 높이기 위해 오래된 답은 다음과 같습니다.
글로벌 범위에서 정의되지 않은 클래스를 로드하려면 자동 로더를 사용해야 합니다.
<?php
// Note that `__autoload()` is removed as of PHP 8 in favour of
// `spl_autoload_register()`, see above
function __autoload($class)
{
// Adapt this depending on your directory structure
$parts = explode('\\', $class);
require end($parts) . '.php';
}
use Person\Barnes\David as MyPerson;
$class = new MyPerson\Class1();
또는 에일리어스 없음:
use Person\Barnes\David\Class1;
$class = new Class1();
Pascal MARTIN에서 언급했듯이 다음과 같이 '\'을 DIRECTOR_SEPARTOR로 대체해야 합니다.
$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
의 "코드를 의 "레벨로딩 에는 "이러한 레벨의 디렉토리"를치환하는 대부분의 솔루션은, 네임스페이스의 「레벨」당 1 레벨의 디렉토리를 사용해 파일을 정리하는 것입니다.또, 자동 로드시에는, 파일을 치환하는 것입니다.\
에서 '는 네임스페이스 이름에서 '어(어)는 '입니다.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___
}
자동 로드 함수는 다음 두 가지 경우 앞에 모든 네임스페이스가 있는 "전체" 클래스 이름만 수신합니다.
[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] 대신에, 다음의 2개의 케이스가 올바르게 기능하고 있는 것을 보고할 수 있습니다.
[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($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);
}
});
이 간단한 해킹을 한 줄에 씁니다.
spl_autoload_register(function($name){
require_once 'lib/'.str_replace('\\','/',$name).'.php';
});
https://thomashunter.name/blog/simple-php-namespace-friendly-autoloader-class/
은 '수업하다'라는 게 것 같아요.Classes
PHP 애플리케이션의 엔트리 포인트와 같은 디렉토리에 있습니다.클래스에서 네임스페이스를 사용하는 경우 네임스페이스는 디렉토리 구조로 변환됩니다.
다른 많은 자동 로더와 달리 밑줄은 디렉토리 구조로 변환되지 않습니다(PHP < 5.3 의사 네임스페이스와 PHP > = 5.3 실제 네임스페이스를 함께 사용하는 것은 어렵습니다).
<?php
class Autoloader {
static public function loader($className) {
$filename = "Classes/" . str_replace("\\", '/', $className) . ".php";
if (file_exists($filename)) {
include($filename);
if (class_exists($className)) {
return TRUE;
}
}
return FALSE;
}
}
spl_autoload_register('Autoloader::loader');
메인 PHP 스크립트(엔트리 포인트)에 다음의 코드를 넣을 필요가 있습니다.
require_once("Classes/Autoloader.php");
디렉토리 레이아웃의 예를 다음에 나타냅니다.
index.php
Classes/
Autoloader.php
ClassA.php - class ClassA {}
ClassB.php - class ClassB {}
Business/
ClassC.php - namespace Business; classC {}
Deeper/
ClassD.php - namespace Business\Deeper; classD {}
에서도 같은 문제가 발생했지만, 다음과 같은 문제가 발견되었습니다.
포함된 클래스의 네임스페이스와 일치하는 하위 폴더 구조를 만들 때 자동 로더를 정의할 필요가 없습니다.
spl_autoload_extensions(".php"); // comma-separated list
spl_autoload_register();
그것은 마법처럼 작동했다.
자세한 내용은 이쪽:http://www.php.net/manual/en/function.spl-autoload-register.php#92514
편집: 백슬래시로 인해 Linux에서 문제가 발생합니다.immeermosol의 솔루션 실시에 대해서는, 여기를 참조해 주세요.
네임스페이스 자동 로드는 윈도에서는 동작하지만 Linux에서는 동작하지 않습니다.
using에는 gotcha가 있는데, 이것이 가장 빠른 방법이지만 모든 파일 이름은 소문자로 표시됩니다.
spl_autoload_extensions(".php");
spl_autoload_register();
예를 들어 다음과 같습니다.
SomeSuperClass 클래스를 포함하는 파일에는 somesuperclass라는 이름을 붙여야 합니다.php, Linux와 같은 대소문자를 구분하는 파일 시스템을 사용하는 경우 파일 이름이 SomeSuperClass.php이지만 Windows에서는 문제가 되지 않는 경우 이 파일은 gotcha입니다.
코드에서 __autoload를 사용하면 현재 버전의 PHP에서 계속 작동할 수 있지만, 이 기능은 나중에 사용되지 않고 최종적으로 삭제될 것으로 예상됩니다.
남은 옵션은 다음과 같습니다.
이 버전은 PHP 5.3 이상에서 동작하며 SomeSuperClass.php 파일명과 somesuperclass.php 파일명을 사용할 수 있습니다.5.3.2 이후를 사용하고 있는 경우, 이 오토 로더는 한층 더 고속으로 동작합니다.
<?php
if ( function_exists ( 'stream_resolve_include_path' ) == false ) {
function stream_resolve_include_path ( $filename ) {
$paths = explode ( PATH_SEPARATOR, get_include_path () );
foreach ( $paths as $path ) {
$path = realpath ( $path . PATH_SEPARATOR . $filename );
if ( $path ) {
return $path;
}
}
return false;
}
}
spl_autoload_register ( function ( $className, $fileExtensions = null ) {
$className = str_replace ( '_', '/', $className );
$className = str_replace ( '\\', '/', $className );
$file = stream_resolve_include_path ( $className . '.php' );
if ( $file === false ) {
$file = stream_resolve_include_path ( strtolower ( $className . '.php' ) );
}
if ( $file !== false ) {
include $file;
return true;
}
return false;
});
상대적인 초보자나 간단한 spl_autoload_register() 셋업을 원하지 않는 모든 이론 없이 2센트를 투입하겠습니다.클래스별로 1개의 php 파일을 만들고 해당 php 파일의 이름을 클래스 이름과 동일하게 하여 해당 클래스 파일을 문제의 php 파일과 같은 디렉토리에 보관하면 됩니다.이렇게 하면 됩니다.
spl_autoload_register(function ($class_name) {
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . $class_name . '.php';
});
이 기능 내의 조각을 검색하면 작동 방식에 대한 답이 나옵니다.PS: Linux를 사용하고 있습니다.Linux에서 동작합니다.윈도우 사용자는 먼저 테스트해야 합니다.
나는 최근에 타네르카이의 대답이 매우 도움이 된다는 것을 발견했어!다음 방법으로 추가하려고 합니다.strrpos()
+substr()
보다 약간 빠르다explode()
+end()
:
spl_autoload_register( function( $class ) {
$pos = strrpos( $class, '\\' );
include ( $pos === false ? $class : substr( $class, $pos + 1 ) ).'.php';
});
<?php
spl_autoload_register(function ($classname){
// for security purpose
//your class name should match the name of your class "file.php"
$classname = str_replace("..", "", $classname);
require_once __DIR__.DIRECTORY_SEPARATOR.("classes/$classname.class.php");
});
try {
$new = new Class1();
} catch (Exception $e) {
echo "error = ". $e->getMessage();
}
?>
언급URL : https://stackoverflow.com/questions/1830917/how-do-i-use-php-namespaces-with-autoload
'source' 카테고리의 다른 글
JavaScript를 사용하여 부모의 하위 요소 찾기 (0) | 2022.12.18 |
---|---|
Python의 상대 경로 (0) | 2022.12.18 |
Python을 사용하여 HTML 파일에서 텍스트 추출 (0) | 2022.12.18 |
최대 절전 모드에서 결과 집합을 추출할 수 없습니다. (0) | 2022.12.18 |
HashTables는 충돌에 어떻게 대처합니까? (0) | 2022.12.18 |