PHP命名空间和自动加载初探
参考资料:
PHP手册-语言参考:http://php.net/manual/zh/language.namespaces.php
概要:
1. 声明了命名空间之后,下面的const, function, class都会划归到该命名空间。
2. 只有声明过命名空间的PHP 文件才能加载有命名空间的PHP文件。
3. PHP 5.3 及以上才能使用命名空间
名词:
关键字:namespace 用来声明 本PHP文件的命名空间
常量:__NAMESPACE__ 用来返回当前命名空间的名称 默认为空字符串
操作符: use 默认以最后一个\后的字符串为别名,配合 as 则为 as后的字符串,与MySQL的字段别名一致。
实际操作如下:
在apache目录下建立如下文件:index.php,Order.php,User.php
Order.php 的内容为
<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;"> 3</span> <span style="color: #008000;"> * @Author: Martin</span><span style="color: #008080;"> 4</span> <span style="color: #008000;"> * @Support: Martin</span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * @Last Modified by: Martin</span><span style="color: #008080;"> 6</span> <span style="color: #008000;">*/</span><span style="color: #008080;"> 7</span> <span style="color: #000000;">namespace Order;</span><span style="color: #008080;"> 8</span> <span style="color: #008080;"> 9</span> <span style="color: #0000ff;">const</span> STR = 'order list<br>'<span style="color: #000000;">;</span><span style="color: #008080;">10</span> <span style="color: #008080;">11</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> detail()</span><span style="color: #008080;">12</span> <span style="color: #000000;">{</span><span style="color: #008080;">13</span> <span style="color: #0000ff;">return</span> 'order detail<br>'<span style="color: #000000;">;</span><span style="color: #008080;">14</span> <span style="color: #000000;">}</span><span style="color: #008080;">15</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> call_by_self()</span><span style="color: #008080;">16</span> <span style="color: #000000;">{</span><span style="color: #008080;">17</span> <span style="color: #0000ff;">return</span> 'call by self<br>'<span style="color: #000000;">;</span><span style="color: #008080;">18</span> <span style="color: #000000;">}</span><span style="color: #008080;">19</span> <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;">20</span> <span style="color: #008000;"> *</span><span style="color: #008080;">21</span> <span style="color: #008000;">*/</span><span style="color: #008080;">22</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Orderlist</span><span style="color: #008080;">23</span> <span style="color: #000000;">{</span><span style="color: #008080;">24</span> <span style="color: #008080;">25</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> __construct()</span><span style="color: #008080;">26</span> <span style="color: #000000;"> {</span><span style="color: #008080;">27</span> <span style="color: #0000ff;">echo</span> 'Class NameSpace is "', __NAMESPACE__, '"'<span style="color: #000000;">;</span><span style="color: #008080;">28</span> <span style="color: #000000;"> }</span><span style="color: #008080;">29</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> show_list()</span><span style="color: #008080;">30</span> <span style="color: #000000;"> {</span><span style="color: #008080;">31</span> <span style="color: #0000ff;">for</span> (<span style="color: #800080;">$i</span> = 0; <span style="color: #800080;">$i</span> $i++<span style="color: #000000;">) {</span><span style="color: #008080;">32</span> <span style="color: #0000ff;">echo</span> "
index.php 内容为:
<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;"> 3</span> <span style="color: #008000;"> * @Author: Martin</span><span style="color: #008080;"> 4</span> <span style="color: #008000;"> * @Support: Martin</span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * @Last Modified by: Martin</span><span style="color: #008080;"> 6</span> <span style="color: #008000;">*/</span><span style="color: #008080;"> 7</span> <span style="color: #000000;">namespace index;</span><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">include_once</span>('Order.php'<span style="color: #000000;">);</span><span style="color: #008080;"> 9</span> <span style="color: #008080;">10</span> <span style="color: #008000;">//</span><span style="color: #008000;">外部访问class 实例化即可使用</span><span style="color: #008080;">11</span> <span style="color: #0000ff;">use</span><span style="color: #000000;"> Order\Orderlist;</span><span style="color: #008080;">12</span> <span style="color: #800080;">$orderlist</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> orderlist;</span><span style="color: #008080;">13</span> <span style="color: #800080;">$orderlist</span>-><span style="color: #000000;">show_list();</span><span style="color: #008080;">14</span> <span style="color: #008080;">15</span> <span style="color: #008000;">//</span><span style="color: #008000;">外部访问静态变量和function 直接访问</span><span style="color: #008080;">16</span> <span style="color: #0000ff;">use</span><span style="color: #000000;"> Order;</span><span style="color: #008080;">17</span> <span style="color: #0000ff;">echo</span><span style="color: #000000;"> Order\STR;</span><span style="color: #008080;">18</span> <span style="color: #0000ff;">echo</span> Order\detail();
打印结果为:
以上内容包含了:通过命名空间来访问文件和直接实例化访问,以及本空间直接访问。
命名空间的存在是为了防止两个同名的class都被载入,使用命名空间在加载第三方的类时能避免同名冲突。
下面来说一下自动加载
SPL 的全称是:Standard PHP Library PHP标准库,在PHP5以后已经内置在PHP中,无需另外安装。
SPL包含了一套针对数据结构、迭代器、异常、文件处理等的函数库。
自动装载库有以下函数
spl_autoload_call:尝试调用所有已注册的__autoload()函数来装载请求类
User.php 内容为:
<span style="color: #008080;">1</span> <span style="color: #000000;">namespace User;</span><span style="color: #008080;">2</span> <span style="color: #008000;">//</span><span style="color: #008000;">直接载入Order</span><span style="color: #008080;">3</span> <span style="color: #008000;">#</span><span style="color: #008000;">include('Order.php');</span><span style="color: #008080;">4</span> <span style="color: #008000;">//自动载入</span><span style="color: #008080;">5</span> spl_autoload_register(<span style="color: #0000ff;">function</span>(<span style="color: #800080;">$className</span><span style="color: #000000;">) {</span><span style="color: #008080;">6</span> <span style="color: #008080;">var_dump</span>(<span style="color: #800080;">$className</span><span style="color: #000000;">);</span><span style="color: #008080;">7</span> <span style="color: #000000;">});</span><span style="color: #008080;">8</span> spl_autoload_call('Order');
打印结果为:
SPL自动载入函数包含如下:
spl_autoload_extensions: 注册并返回spl_autoload函数使用的默认文件扩展名。
get_include_path: 设置默认引用的文件夹
spl_autoload_register: 自动引入文件
实际操作如下:
我们重新调整目录结构和并复制order 到 lib下面 如下:
修改User.php 如下:
<span style="color: #008080;"> 1</span> <span style="color: #000000;">namespace User;</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #008000;">//</span><span style="color: #008000;">直接载入Order</span><span style="color: #008080;"> 4</span> <span style="color: #008000;">#</span><span style="color: #008000;">include('Order.php');</span><span style="color: #008080;"> 5</span> <span style="color: #008000;">//自动载入</span><span style="color: #008080;"> 6</span> <span style="color: #008080;">define</span>('LIB_DIR', __DIR__ . DIRECTORY_SEPARATOR . 'lib' .<span style="color: #000000;"> DIRECTORY_SEPARATOR);</span><span style="color: #008080;"> 7</span> spl_autoload_register(<span style="color: #0000ff;">function</span> (<span style="color: #800080;">$class</span><span style="color: #000000;">) {</span><span style="color: #008080;"> 8</span> <span style="color: #800080;">$path</span> = LIB_DIR . <span style="color: #800080;">$class</span> . '.lib.php'<span style="color: #000000;">;</span><span style="color: #008080;"> 9</span> <span style="color: #0000ff;">include</span> (<span style="color: #800080;">$path</span><span style="color: #000000;">);</span><span style="color: #008080;">10</span> <span style="color: #000000;">});</span><span style="color: #008080;">11</span> <span style="color: #008080;">12</span> spl_autoload_call('Order'<span style="color: #000000;">);</span><span style="color: #008080;">13</span> <span style="color: #0000ff;">use</span><span style="color: #000000;"> Order;</span><span style="color: #008080;">14</span> <span style="color: #008080;">15</span> <span style="color: #800080;">$orderList</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> \Order\Orderlist();</span><span style="color: #008080;">16</span> <span style="color: #800080;">$orderList</span>->show_list();
打印结果为:
注意:
当采用SPL载入文件时,use并不能触发spl_autoload_register函数,他会被new触发,这样就会提示找不到文件,
所有采用spl_autoload_call 来提前触发自动载入。
本文地址:http://www.cnblogs.com/martin-tan/p/4864539.html
问题:
使用get_include_path,spl_autoload_extensions并且spl_autoload_register默认为空的情况下并不能直接载入目录下的文件,原因如上。(?)