>  기사  >  백엔드 개발  >  PHP 네임스페이스 로딩 문제

PHP 네임스페이스 로딩 문제

WBOY
WBOY원래의
2016-09-23 11:31:041233검색

현재 디렉토리 구조가 다음과 같다고 가정합니다.
PHP 네임스페이스 로딩 문제

A.php의 코드는 다음과 같습니다.

네임스페이스 A;
클래스 A{
공용 함수 __construct()
{
echo 'AAAAAAAAAAAA';
}
}

B.php의 코드는 다음과 같습니다.
네임스페이스 B;
AA 사용;
new A();
?>

오류: 치명적인 오류: 'AA' 클래스를 찾을 수 없습니다. . .

저는 항상 PHP의 네임스페이스 명명 규칙에 대해 혼란스러워했습니다.

  1. PHP는 네임스페이스 이름에 따라 해당 클래스를 자동으로 로드합니까?

  2. 네임스페이스를 사용하더라도 한 파일이 다른 파일의 클래스를 호출할 때 require, include 등을 사용하여 다른 클래스 파일을 현재 파일에 로드해야 인스턴스화하여 사용할 수 있습니다

  3. 위의 2번 항목이 '예'인 경우 자동 로드 또는 다른 방법을 사용하여 로드해야 합니까? 소위 말하는 네임스페이스는 클래스를 구별하기 위해 사용하는 이름일 뿐, 클래스를 자동으로 불러오는 기능은 없는 것이 사실인가요?

답글 내용:

현재 디렉토리 구조가 다음과 같다고 가정합니다.
PHP 네임스페이스 로딩 문제

A.php의 코드는 다음과 같습니다.

네임스페이스 A;
클래스 A{
공용 함수 __construct()
{
echo 'AAAAAAAAAAAA';
}
}

B.php의 코드는 다음과 같습니다.
네임스페이스 B;
AA 사용;
new A();
?>

오류 보고서: 치명적인 오류: 'AA' 클래스를 에서 찾을 수 없습니다. . .

저는 항상 PHP의 네임스페이스 명명 규칙에 대해 혼란스러워했습니다.

  1. PHP는 네임스페이스 이름에 따라 해당 클래스를 자동으로 로드합니까?

  2. 네임스페이스를 사용하더라도 한 파일이 다른 파일의 클래스를 호출할 때 require, include 등을 사용하여 다른 클래스 파일을 현재 파일에 로드해야 인스턴스화하여 사용할 수 있습니다

  3. 위의 2번 항목이 '예'인 경우 자동 로드 또는 다른 방법을 사용하여 로드해야 합니까? 소위 말하는 네임스페이스는 클래스를 구별하기 위해 사용하는 이름일 뿐, 클래스를 자동으로 불러오는 기능은 없는 것이 사실인가요?

먼저 네임스페이스가 하는 일을 명확히 해야 합니다. 네임스페이스는 이름에서 알 수 있듯이 자신을 선언하는 공간의 이름입니다(classestool: 내가 도구 공간에 있음을 알리는 것과 동일). 즉, use를 사용하여 도입한 네임스페이스는 최종적으로 "위치 이름" 에 불과합니다. 또는 require. PHP는 include 또는 require를 통해 실제 본문을 도입해야 하며 이 두 가지에서 벗어나는 것은 불가능합니다.

우리가 보는 __autoload 및 spl_autoload_register는 PHP의 매직 도입 방법에 속합니다(사실 이 개념은 객체 지향(개인 이해)의 제어 반전과 유사합니다). 매직 도입은 일반인의 용어로 마법 상자를 생성합니다. 이 마법 상자는 지루한 포함 및 요구 작업을 처리하는 데 도움을 줍니다. 네임스페이스를 통해 자동 로딩을 구현하려면 규칙을 따라야 합니다: psr-0 자동 로딩 사양 규칙에 따라 위치 이름이 선언되면 "위치 이름" 사용하여 소개할 수 있습니다. 매직박스로 위치명을 파싱한 후, 그림에 따라 검색한 후, include 또는 require를 통해 해당 파일을 가져옵니다.

요약하자면 다음 세 가지입니다.

  1. 사용은 실제 본체가 아닌 공간 이름만 소개합니다.

  2. php는 php 파일을 도입할 때 require와 include를 사용해야 합니다.

  3. 항상 변화하라, 환상에 현혹되지 말라

참고:

  1. 자동로드 자동로드

  2. Composer가 자동으로 로드하고 구문 분석합니다.

  3. IDE 도구를 사용하여 PHP 관련 프레임워크(예: laravel)의 자동 파싱 소스 코드를 볼 수 있습니다

  1. spl_autoload_register()을 설정하지 않으면 자동으로 로드되지 않습니다.

  2. 예. 클래스 파일을 로드하려면 require_once 또는 include_onece과 같은 기능을 사용해야 합니다.

  3. 네임스페이스는 디렉터리로 간주할 수 있습니다. 이름 충돌을 피하기 위해 서로 다른 디렉터리가 동일한 파일 이름을 가질 수 있습니다. 네임스페이스에는 클래스를 자동으로 로드하는 기능이 없습니다.

1. 자동으로 로드되지 않습니다

<code>自动加载:
    类库映射
    PSR-4自动加载检测
    PSR-0自动加载检测
</code>

2.在TP5,可以用use 关键字即可, 不需要做require这样繁琐的操作了
3.已经该用spl_autoload_register了替代autoload, composer的出现不就是为了解决这种加载问题么?所以一定要设置命名空间,命名空间不具有自动加载类的作用,他是为了避免命名冲突和可视化类的路径和真正的懒加载等。

使用spl_autoload_register注册了自动装载函数才能使用use,demo:

<code><?php
class Autoload
{
    /**
     * 类映射
     * @var array
     */
    // private static $_classMap = [];

    public function __construct()
    {
        # code...
    }
    
    public static function init()
    {
        spl_autoload_register('Autoload::autoload');
    }

    public static function autoload($class_name='')
    {
        // if (self::$_classMap[$class_name]) {
        //     require(self::$_classMap[$class_name]);
        // }
        require(str_replace('\\', '/', $class_name).'.php');
    }

}


/* register autoload funxtion|注册自动装载函数 */
require('./Autoload.php');
Autoload::init();</code>

  1. pho不会自动加载类。spl_autoload的加载是从include配置中找对应的 类名.inc或者 类名.php来加载。(具体查看 php文档)

  2. ThinkPHP和Laravel以及Composer之类的框架程序,都是通过spl_autoload_resigster来实现按照一定功能加载类。

  3. 命名空间设置的初衷是为了区分不同区的同名类,不一定是按照文件夹来命名,命名空间相当于对类进行分区,比如,你有个类叫 Router 我也有个类叫 Router,类名重复了,这时命名空间就可以起作用了。

  4. 我的回答是是,ThinkPHP的原理是通过 命名空间 来解析成 路径 ,再注册了autoload来加载, 如 abc,会在指定目录找a/bc.class.php (.class.php是tp指定的加载后缀,指定目录通常是library ),Zend 框架是通过 _ 来分割路径,如 a_b_c 类。会变成 /a/b/c.php来在指定目录找。

去了解下php面向对象设计模式 他们说的就是这些

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.