命名空间与自动加载系列(六)--自动加载(完)
为什么要使用类的自动加载?
前面可以看到,使用到其它类时需要通过include
关键字将其引入,如果有N多个需要通过include
来引入,不太现实,为了解决这个问题,可以使用类的自动加载。
__autoload
已经被废弃,旧代码中可能还可以看到。现在推荐使用sqp_autoload_register
准备测试目录与文件,结构如下:
<span style="box-sizing: border-box;padding-right: 0.1px">demo01</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> bootstrap.php</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> App</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> Controller</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> Index.php</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> Post.php</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> Module</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> Post.php</span>
每个文件内容如下:
<span style="box-sizing: border-box; padding-right: 0.1px;">// App/Controller/Index.php</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style=""><?</span><span style="">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">namespace</span> <span style="">App\Controller</span>;</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">class</span> <span style="">Index</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">public</span> <span style="">static</span> <span style="">function</span> <span style="">index</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">echo</span> <span style="">'Index控制器:'</span> . <span style="">__METHOD__</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box; padding-right: 0.1px;">// App/Controller/Post.php</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style=""><?</span><span style="">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">namespace</span> <span style="">App\Controller</span>;</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">class</span> <span style="">Post</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">public</span> <span style="">static</span> <span style="">function</span> <span style="">index</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">echo</span> <span style="">'Post控制器:'</span> . <span style="">__METHOD__</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box; padding-right: 0.1px;">// App/Module/Post.php</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style=""><?</span><span style="">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">namespace</span> <span style="">App\Module</span>;</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">class</span> <span style="">Post</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">public</span> <span style="">static</span> <span style="">function</span> <span style="">index</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">echo</span> <span style="">'Post模型:'</span> . <span style="">__METHOD__</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>
方式一,使用函数方式实现自动加载
<span style="box-sizing: border-box; padding-right: 0.1px;">// App/bootstrap.php</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style=""><?</span><span style="">php</span></span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box; padding-right: 0.1px;">// 自动加载类文件</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box; padding-right: 0.1px;">/**</span><br></br><span style="box-sizing: border-box; padding-right: 0.1px;">* @param string $class 类的命名空间,如 App\Controller\Index</span><br></br><span style="box-sizing: border-box; padding-right: 0.1px;">*/</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">spl_autoload_register</span>(<span style="">function</span>(<span style="">$class</span>){</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">// 将命名空间命名路径转为文件路径</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">$fileName</span> <span style="">=</span> <span style="">str_replace</span>(<span style="">'\\'</span>, <span style="">'/'</span>, <span style="">$class</span>) . <span style="">'.php'</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">require</span> <span style="">$fileName</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">});</span>
<span style="box-sizing: border-box; padding-right: 0.1px;">// App/index.php</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style=""><?</span><span style="">php</span></span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">include</span> <span style="">'./bootstrap.php'</span>;</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">use</span> <span style="">App\Controller\Index</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">use</span> <span style="">App\Module\Post</span>;</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">Index</span>::<span style="">index</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">Post</span>::<span style="">index</span>();</span>
使用函数方式实现类的自动加载完成。需要使用哪一个类直接引入(当然了,这个类是要存在的,不然要报错咯)。
方式二,使用面向对象方式实现
现在来bootstrap.php
改造为面向对象
<span style="box-sizing: border-box; padding-right: 0.1px;">// App/bootstrap.php</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">?</span><span style="">php</span></span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">namespace</span> <span style="">App</span>;</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box; padding-right: 0.1px;">// 自动加载类文件</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">class</span> <span style="">Bootstrap</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">public</span> <span style="">static</span> <span style="">function</span> <span style="">boot</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">// 实例化自身并调用autoload方法</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">spl_autoload_register</span>([<span style="">new</span> <span style="">self</span>, <span style="">'autoload'</span>]);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">public</span> <span style="">function</span> <span style="">autoload</span>(<span style="">string</span> <span style="">$class</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">echo</span> <span style="">$class</span>;<span style="">die</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">$fileName</span> <span style="">=</span> <span style="">str_replace</span>(<span style="">'\\'</span>, <span style="">'/'</span>, <span style="">$class</span>) . <span style="">'.php'</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="">require</span> <span style="">$fileName</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="">Bootstrap</span>::<span style="">boot</span>();</span>
方式三,使用composer实现自动加载
1)删除bootstrap.php
文件
2)使用composer进行初始化
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="">cd</span> demo</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">composer init</span><br></br><span style="padding-right: 0.1px; box-sizing: border-box;"></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">This command will guide you through creating your composer.json config.</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">Package name (<vendor>/<name>) [root/demo]:</span>
执行
composer init
出现的一系列东西暂时不用管,直接回车即可。如是出现 Author [, n to skip]: Invalid author string. Must be in the format: John Smith john@example.com
输入 n 跳过
执行完composer init
后,根目录中多出一个composer.json
文件,其内容如下:
<span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span class="cm-string cm-property" style="">"name"</span>: <span style="">"45796/demo"</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span class="cm-string cm-property" style="">"require"</span>: {}</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>
3)修改composer.json
<span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span class="cm-string cm-property" style="">"name"</span>: <span style="">"45796/demo"</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span class="cm-string cm-property" style="">"require"</span>: {},</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span class="cm-string cm-property" style="">"autoload"</span>:{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span class="cm-string cm-property" style="">"psr-4"</span>: {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span class="cm-string cm-property" style="">"App\\"</span>:<span style="">"App"</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>
自动加载遵循
psr-4
规范,"App\\":"App"
的关系时,"命名空间":"对应的文件夹"
4)生成自动加载
composer install # 执行结果 No lock file found. Updating dependencies instead of installing from lock file. Use composer update over composer install if you do not have a lock file. Loading composer repositories with package information Updating dependencies Nothing to modify in lock file Writing lock file Installing dependencies from lock file (including require-dev) Nothing to install, update or remove Generating autoload files
执行成功后,会在应用根目录生成
vendor
目录,其中就包含自动加载的文件
5)使用自动加载
index.php文件中引入并使用自动加载
// index.php <?php include './vendor/autoload.php'; use App\Controller\Index; use App\Module\Post; Index::index(); Post::index();
加载文件案例
使用composer
自动加载后,还可以自动加载文件。TP框架中有一个common.php文件,可以存放通用文件。以Laravel文件,如想要添加一个公用的助手函数文件,其没有直接提供,此时就可以通过composer
自动加载文件实现。
第一步:修改compsoer.json
{ "name": "45796/demo", "require": {}, "autoload":{ "files":[ "Help/Helper.php" ], "psr-4": { "App\\":"App" } } }
第二步:应用中添加对应的文件
// 文件位置:App/Help/Helper.php <?php function show() { echo '公共文件'; }
第三步:composer更新
composer update
第四步:使用
<?php
show();
命名空间系列完