搜索
首页后端开发php教程PHP命名空间的加载问题

假设现在的目录结构是这样的:
PHP命名空间的加载问题

在A.php里面代码是:

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

在B.php里面代码是:
namespace B;
use A\A;
new A();
?>

报错:Fatal error: Class 'AA' not found in 。。。

我对php的命名空间命名规则一直存在疑惑:

  1. php到底会不会自动根据命名空间的名字加载那个类?

  2. 是不是就算使用了命名空间,在一个文件调用另一个文件的类的时候,也要使用require、include等把另一个类文件加载到当前文件才能实例化使用

  3. 如果上面第2点YES的话,是不是就是使用autoload等方式来加载?是不是所谓的命名空间其实就是个用来区别类的名字而已,并没有自动加载类的作用?

回复内容:

假设现在的目录结构是这样的:
PHP命名空间的加载问题

在A.php里面代码是:

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

在B.php里面代码是:
namespace B;
use A\A;
new A();
?>

报错:Fatal error: Class 'AA' not found in 。。。

我对php的命名空间命名规则一直存在疑惑:

  1. php到底会不会自动根据命名空间的名字加载那个类?

  2. 是不是就算使用了命名空间,在一个文件调用另一个文件的类的时候,也要使用require、include等把另一个类文件加载到当前文件才能实例化使用

  3. 如果上面第2点YES的话,是不是就是使用autoload等方式来加载?是不是所谓的命名空间其实就是个用来区别类的名字而已,并没有自动加载类的作用?

首先要清楚命名空间是干啥的,命名空间正如其名,是声明自己所在空间的名称(classes\tool:相当于宣布——我在classes空间位置中的tool空间中),换句话说就是表面自己在什么位置,你用use引入的命名空间,说到底只是引入了一个“位置名”,真身并没被include或require引入过来,php引入真身须通过include或require,脱离了这两个是不可能的。

我们看到的__autoload、spl_autoload_register属于php的魔术引入法(其实这种概念类似于面向对象中的控制反转(个人理解)),魔术引入——通俗点来说就是生产一个魔法箱,这个魔法箱负责帮你处理繁琐的include、require这些累活。如果想实现通过命名空间的自动加载,你需要按规矩来,规矩就是:psr-0自动加载规范,如果按规矩声明了位置名,通过use引入的“位置名”就能被魔法箱解析,解析了它的位置名后,按图索骥,然后通过include或require导入对应的文件。

总结起来就这三点:

  1. use引入的只是空间名称,真身并没引入;

  2. php引入php文件必须要走require和include;

  3. 万变不离其宗,不要被假象所迷糊

参考资料:

  1. Autoload 自動載入

  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></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
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么查找字符串是第几位php怎么查找字符串是第几位Apr 22, 2022 pm 06:48 PM

查找方法:1、用strpos(),语法“strpos("字符串值","查找子串")+1”;2、用stripos(),语法“strpos("字符串值","查找子串")+1”。因为字符串是从0开始计数的,因此两个函数获取的位置需要进行加1处理。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具