Home  >  Article  >  Backend Development  >  PHP namespace loading problem

PHP namespace loading problem

WBOY
WBOYOriginal
2016-09-23 11:31:041203browse

Suppose the current directory structure is like this:
PHP namespace loading problem

The code in A.php is:

namespace A;
class A{
public function __construct()
{
echo 'AAAAAAAAAAAA';
}
}

The code in B.php is:
namespace B;
use AA;
new A();
?>

Error report: Fatal error: Class 'AA' not found in . . .

I have always been confused about PHP’s namespace naming rules:

  1. Will php automatically load that class based on the name of the namespace?

  2. Even if a namespace is used, when one file calls a class in another file, it must use require, include, etc. to load the other class file into the current file before it can be instantiated and used

  3. If the 2nd point above is YES, is it possible to use autoload or other methods to load? Is it true that the so-called namespace is just a name used to distinguish classes, and does not have the function of automatically loading classes?

Reply content:

Assume that the current directory structure is like this:
PHP namespace loading problem

The code in A.php is:

namespace A;
class A{
public function __construct()
{
echo 'AAAAAAAAAAAA';
}
}

The code in B.php is:
namespace B;
use AA;
new A();
?>

Error report: Fatal error: Class 'AA' not found in . . .

I have always been confused about PHP’s namespace naming rules:

  1. Will php automatically load that class based on the name of the namespace?

  2. Even if a namespace is used, when one file calls a class in another file, it must use require, include, etc. to load the other class file into the current file before it can be instantiated and used

  3. If the 2nd point above is YES, is it possible to use autoload or other methods to load? Is it true that the so-called namespace is just a name used to distinguish classes, and does not have the function of automatically loading classes?

First of all, you must be clear about what the namespace does. The namespace, as its name suggests, is the name of the space where you declare yourself (classestool: equivalent to announcing that I am in the tool space in the classes space location). In other words, it is the name of the space where you declare yourself. At which position, the namespace you introduced using use, in the final analysis, only introduced a "location name", the real body was not introduced by include or require. PHP must introduce the real body through include or require, and it is separated from these two This is impossible.

The __autoload and spl_autoload_register we see belong to the magic introduction method of PHP (in fact, this concept is similar to the inversion of control in object-oriented (personal understanding)). Magic introduction-in layman's terms, it is to produce a magic box. This Magic Box is responsible for helping you handle the tedious work of include and require. If you want to implement automatic loading through the namespace, you need to follow the rules. The rules are: psr-0 automatic loading specification. If the location name is declared according to the rules, the "location name" introduced through use can be parsed by the magic box , after parsing its location name, search according to the picture, and then import the corresponding file through include or require.

To sum up, here are three points:

  1. use only introduces the space name, not the real body;

  2. php requires require and include when introducing php files;

  3. Always change, don’t be confused by illusions

Reference:

  1. Autoload Automatic loading

  2. composer automatically loads analysis

  3. You can use IDE tools to see the automatic parsing source code of PHP related frameworks (such as laravel)

  1. It will definitely not load automatically unless you set spl_autoload_register().

  2. Yes, you still need to use functions such as require_once or include_onece to load class files.

  3. Namespaces can be regarded as directories. Different directories can have the same file name to avoid naming conflicts. Namespaces do not have the function of automatically loading classes.

1. Will not load automatically

<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面向对象设计模式 他们说的就是这些

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn