以下皆为本人自我理解内容,如有失误之处,请多多包涵。 1 h( _/ y, \8 N: g) V
文章大纲: 使用namespace的目的 namespace的使用方法 使用use的目的 use的使用方法
: u9 G3 w. i, h" B+ X2 l4 I& l7 o
/ }+ h- r9 p- R7 H使用namespace的目的:团队合作项目时,避免与团队其它成员新建的类发生冲突;个人负责项目时,避免前后新建的类发生冲突;
2 y) X) @4 Y7 P* G" A3 \- z/ h据个人理解,用到所需要的类时,需要先require或include引入,所以会发生类重定义的错误的前提是:两个相同命名的类都有被引入。目前有些php框架会自动加载(即include)所有新建的model类,所以为了避免你新建的model类和项目框架原生的核心类发生重名冲突,采用了namespace。(想了想,与团队成员新建的类产生冲突应该通过沟通避免,即使事发后也应该重新调整类名即时维护,避免后期造成因为对类的理解混淆而带来维护上的复杂度提高)
6 W! k7 O5 y1 X% n, v; F& j# v结合使用方法来进一步理解它的使用目的吧。 $ o1 V: N- m b0 w
" Q6 ?- C Z6 H) m2 o
namespace的使用方法:为了进行测试,我将创建3个文件:1.php和name.php(此文件用来执行测试),后面将不再说明,请自行注意代码的变化。 1.namespace后命名的定义不区分大小写- namespace one;
6 Z1 `1 k( s9 m. O; @! y - namespace One;
8 Q' o) w5 i2 T/ i3 O- D1 e - namespace ONE;
复制代码
2 N% o. K5 m/ ]6 Y$ i+ L& e如上写法都可以,选择一种作为自己的规范即可。(后面代码我采用第一种进行测试哈)
# v$ O0 X2 t$ s) G( I* A9 f. u! O# |2. 没有定义命名空间,就理解为使用顶级命名空间。new类时,可以在类前加上反斜杠\,也可以不加。- //1.php
) b1 ~- t. }! `+ W6 | - class Person{
/ W! d. R& A' Y" U4 g+ ` J - function __construct(){/ y6 W+ z6 x7 o+ T" n2 K8 q
- echo 'I am one!';
% {, ~% M' G% I4 l+ n - }6 i1 X. i- G2 F4 v. B# X% ?
- }
复制代码- //name.php
9 f+ W/ J9 _, E - require_once './1.php';! {" Z+ {& t H
- ( R- N. X5 I% J$ Y* ?3 L2 {
- new Person(); //输出 I am one!;
% R1 a1 R G1 w% w# p7 }* c" N - new \Person(); //输出 I am one!;
复制代码
2 w4 o# @; O8 z8 U! o2 ?8 Q3. new类时,带上命名空间时,之间一定用反斜杠字符,而不是顺斜杠。记忆方法:按找%中斜杠的顺序理解为顺斜杠。(有时说反斜杠,自己都不知道是哪种方向,以前按自左向右上升方向这种方向记忆,现在感觉这个太不靠谱了)
- //name.php) y4 V) i# I2 G, ~
- require_once './1.php';7 [' [& J+ t5 i9 @- u. S, m4 {+ I8 ~
- new /Person(); // 代码报错:Parse error: syntax error, unexpected '/'
复制代码 ! M5 T& P' r; L
4.类在指定命名空间下, new类时,一定要带上指定的命名空间。没有带上指定的命名空间,按照第2点,php就会从顶级命名空间里找这个类。切记:这里不能按照顶级命名空间包含一切其它的命名空间来理解。而应该将顶级命名空间完完全全与其他命名空间区分开。 - //1.php
& } P7 l" X: A* ^+ E/ | - namespace one;: I4 O+ j/ f0 v7 \
- class Person{
$ F$ s) {/ h$ U, Y - function __construct(){
# ]8 q: `3 |" N! I - echo 'I am one!';
{/ `1 Z/ I* [) c - }7 r7 E) a, N p: G1 M
- }
复制代码- //name.php# D9 Q0 B& X! I1 s: s
- require_once './1.php';6 U$ u: @; F* E8 m
- new \one\Person(); //输出 I am one!;8 a4 P5 e( k6 J$ z' W: q
- new \Person(); //代码报错:Fatal error: Class 'Person' not found
复制代码 ! r2 C* E2 @* |0 U' ~
可以举个这个通俗例子来理解:带上指定命名空间代表某人的苹果(在他手里),顶级命名空间代表苹果箱里的苹果(在箱子里)。现在要找某人的苹果,就将某人的命名空间带上,否则就会从箱子里找某人的苹果,结果当然是找不到。 K* ]5 O) _5 A6 z' c. w9 K
5.命名空间声明后的代码便属于这个命名空间,即使有include或require也不影响(重点是对后半句的理解,具体看代码)。
2 G1 a% I& N/ k* l( x7 c- //1.php
1 b2 T" m0 E2 Z8 C, k* N: P* K5 ] - namespace one;
( A4 k2 d& N& e) M! Z- s2 m' b7 u - class Person{! f5 m0 `( {" @' T! x/ ?
- function __construct(){! s- X! d6 z+ W8 i
- echo 'I am one!';' e% h4 j _ l, l0 f, z7 Z5 H/ k& P
- }
7 n: ?* g) g% T0 d0 n" ~- H+ w - }
复制代码- //name.php% J8 j! A$ k2 M9 z; G
- namespace test;
2 z! z o+ `# [ - require './1.php'; _+ W* r% m y( l; S
- new \one\Person(); //输出 I am one!;
+ ^ E2 f6 |+ }4 x# W. n - new Person(); //这里结果会是什么呢,猜猜看7 H/ D) n( _* u* a# a, F0 V
- 最后一行结果报错: O1 Q0 X3 e/ O0 @+ L8 s
- Fatal error: Class 'test\Person' not found
复制代码
$ E/ ~$ e4 Z4 f0 J1 w7 t% ` {) d
6 x: B- a) _; V/ ~首先,这里与第2点比较一下:
第2点,我说,没有命名空间时,new类时,有没有反斜杠意义一样。 在这里,有了命名空间,有和没有反斜杠的意义就不一样了。 最后一行换成 # H- T) U8 ?+ `" s" K
结果报错: - Fatal error: Class 'Person' not found
复制代码 A, Y6 [% K! b$ [
接着,就说说当前这点。 我们可以发现,最后一行代码对应的命名空间为test,并没有受到require文件里的命名空间的影响。 进一步加强验证,我修改了name.php文件如下: - //name.php
0 c# L0 N# X& m- y+ y - namespace test;
$ r9 N. X( s/ X/ p, {. i - require './1.php';
- x% D p' o. z! g' R" b* t
" c6 L& [5 }# Y5 y. U- class Person{
& a3 _# I; P& w2 l* \ - function __construct(){7 B) }( l9 C# C4 o
- echo 'I am test!';
8 x, M- d+ m/ }) @/ B - }8 t0 D% M6 | [/ ?7 W7 a
- }0 {1 ]$ X+ y d% N' f% k7 E( W
) @4 @* g3 i0 x! [# v; z, J a- new \one\Person(); //输出 I am one!;% ^ l, P/ U7 [3 q/ P% M2 ]
- new Person(); //这里结果会是什么,自己猜猜看
复制代码
( t2 p2 g/ d+ I( c8 [最后,这个例子刷新了我对require的认识了。 按照我以前对require的理解:PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部分。所以我常常就简单的理解为替换,只不过把抽离出来的代码再放回原处而已。然后我试了将1.php文件内容放到name.php里: - //name.php
- e8 V" c; f5 q, ^9 n6 w - namespace test;
' R) K/ S7 ?: u - namespace one;* X) j4 Y- m) A) p! u/ f
- class Person{3 g) \) {7 x( N, A/ W, N
- function __construct(){
i/ M, b( X# w: ]1 X - echo 'I am one!';
! \5 K: o$ i8 Y7 P3 A0 Q& J* G - } Y& P" L6 q" j' _- G: Q& A
- }& O- e% ^' L$ y& i( n
) f ~5 S% [# K$ Y$ B; j* J4 n8 \- class Person{
$ j7 a0 x4 G7 j! v+ L+ L0 h - function __construct(){4 t, I0 A0 Z+ x# ?" D0 ]
- echo 'I am test!';
0 H1 M% v( [' t+ ?- l& L, {. | - }
" p P9 C6 q: ]4 j A5 E; g( `2 { - }
复制代码 6 K( V" Y) x J0 a% I7 w
无需new类,该文件就会报错: - Fatal error: Cannot redeclare class one\Person
复制代码 + n/ j _, c$ B% [6 ]; I
看来简单的把require理解为替换,在这里行不通。
7 K3 ]0 Y7 i ^& B6.namespace里不包含类名称,即使存在与类名称同名的部分,那也不代表类。new类时,还是得将这部分带上。
* q3 Z( M9 n; K% l) r" d; \ G- //name.php
9 y$ ^. G o7 s; c O - # ?* J5 l0 G3 v* P. ~
- namespace test\person;
% J* d* [- C# ] - : h' z# {2 `; b4 @# Z' ]
- class Person{
$ J$ m W1 F9 Y& z T$ H/ D - function __construct(){) y1 `+ y$ d0 m
- echo 'I am test!';8 X0 E; s2 S+ T, ]# W$ U3 e4 m7 x
- }
* Z% X) p( }* Q+ d7 X - }5 r' Q7 J2 q G5 i! t
- new \test\person\Person(); //命名空间里person无法代表类名
复制代码 : D2 L- i0 N% b$ H! [; J a" q
不过这样纯粹是画蛇添足,直接干脆点,namespace里不要带类名称就好。
9 C8 @4 s9 M7 |+ R* E- f* u) t7.一个php文件中可以存在多个命名空间,第一个命名空间前不能有任何代码。只说第一个命名空间前不能有任何代码,之后的命名空间之前可以有代码。这个自行测试即可。 - //name.php
, ]9 f9 p, K2 ~0 w - " D: P( |- X- e$ @7 }/ F
- namespace test;! ^ o/ h& ]+ _7 |
- echo 'zhai14';! J) `- L8 e2 r4 m$ V
- namespace zhai;7 H, T$ o+ n' W
- require './1.php';
复制代码 9 ^, w/ X6 ?6 i( V9 C' n
php命名空间namespace告一段落了,接下来说说use的用途。 使用use的目的:在命名空间字符串过长时,使用use可以相应的缩短命名空间。 ( W& w1 h: u, B& h/ s5 ?
use的使用方法:1.new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。0 u$ \- `' z3 F4 s1 h$ r3 g+ j
- //name.php
5 ]- x; `8 C; ]/ V0 B# v! Y
& b [! {8 ]& b" z. ]( I- namespace animal\dog;
1 Y1 H( q1 t7 |) w L8 U
" }% l0 I" W% \0 r, M3 v, R- class Life{: X, F& i) u' q0 O* F4 q
- function __construct(){! F% K7 ^7 C1 I1 A% E1 Z, [
- echo 'dog life!';
8 J% r# z7 j/ ]2 h' @. f! s6 i - }4 e1 U. N5 p% Q8 i9 ?
- }; W3 g* ~9 t; J# ^" u: G
- 2 Y; t2 I* Z% C
- namespace animal\cat;
5 j+ ^; A) G1 ]& ~
8 ~. r; B% T" a% r/ a( Y+ Z- class Life{
$ R; @" ?+ k/ @ - function __construct(){
6 S$ h2 q+ K( W" b: A) h' H - echo 'cat life!';2 t G, F( q U5 N) u+ b
- }
/ g- o3 f0 j" K' T# S$ r - }$ P- Q$ t( d* A( V( U
4 h! R/ w) n2 V8 y) Y" |- new Life(); //按照代码执行顺序,这里默认animal\cat这个命名空间1 |- j3 N9 U2 p
- new \animal\dog\Life(); //A" i+ Z: g V3 U1 o. r5 F* E( S; Y
- / Q0 |/ ~4 I4 u
- use animal\dog; //a
5 h' G8 q) V4 s0 e% n# S# w! B - new dog\Life(); //B
: x: t( P8 ^ H( D6 R, w; y9 n
! ~; M) f# x2 ]8 P+ ~- use animal\dog as d; //b
( r1 y. b" K! y" N P - new d\Life();
复制代码 2 ~) h# b! F% k8 e
通过A、B行代码比较,需要注意: 使用use后,new类时,最前面没有反斜杠。 没使用use时,命名空间最前面有反斜杠 / l5 D" b: r9 \7 ]. D
通过a、b行代码比较,可以理解: use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的: 4 a" ]+ c0 z1 u: g" Q* z" d
相当于 6 F7 k8 i" v1 l( V
2.namespace后面不建议加类名,但use后可以。/ f* \# ?2 \) D
- //name.php, E! Q: M. h6 Q' r
- % o* X3 u' C( k# I+ Z! r
- namespace animal\dog;: f R4 S1 ]6 }) e6 {/ u; D
9 F7 h K0 ^1 B: w- class Life{2 m, z7 C" P& \' g- x
- function __construct(){0 @; K" j0 _! t/ G6 Q
- echo 'dog life!';
2 Y, _% L: R' Y, X - }, T) J, s2 o8 Z9 O) w- G7 ], L- j
- }" b, s2 u. Z5 a+ B2 N( _6 M
, J- ]6 X+ e) o0 p9 n- namespace animal\cat;1 j! g% {9 x" \
" R8 F0 D8 z, T6 k: W0 S5 P- class Life{
1 Y% D/ y1 G" g' c# } - function __construct(){
7 w' ] Z& F* }9 R( n/ } - echo 'cat life!';1 v0 |! n0 M* f! v0 }
- }) m, Y, a4 h; w4 h$ _" f0 C+ I; b
- }9 o' ~9 a! p1 w9 }; ]9 W
% m' a5 ?5 s3 a4 R- use animal\dog\Life as dog; 4 k, W, W- I0 A3 \6 r% v
- new dog();
复制代码
! L) \$ ^! s& B+ y# s* M7 g如上所示,use后加上类名后,就相当于把类改了个名称:由Life改为dog了。 上面不用as dog就会报错: - Fatal error: Cannot use animal\dog\Life as Life because the name is already in use
复制代码 7 M; t, b: E6 e8 K( K
因为cat下也有个一样名称的Life类。 可以理解为,使用use后,这个昵称对应的类只能归当前命名空间占有,其它命名空间下不允许存在该类。 - //name.php1 S" z5 v) {- R w
' j# y2 m/ o: \' f/ Q- namespace animal\dog;4 I# ^( X( l+ _! k- G
- 4 Z) ^: o" v5 l& L# t
- class Life{
% Q; S' L$ S" [ - function __construct(){
, ]4 q1 D' i/ E; M! f - echo 'dog life!'; w* K6 ? I3 G9 R; _+ ^2 G) D
- }
5 G8 C0 {, u4 c& u - }5 ~0 x+ F& s& |0 n: q: l2 ^
- class Dog{
, ^/ G$ h- `* u- g/ Y5 e - function __construct(){& K' Y- R& |2 P
- echo 'dog in dog!';
; @2 s, x7 E+ z* W8 Y - }* \( v- q2 s6 F
- }8 F5 n0 J, X# \9 |
7 A1 m y, a8 m* e" H& ?! t7 h. z- namespace animal\cat;
' [+ N" a \4 e - ( |/ h u! t$ W# |/ b
- // class Dog{
- W6 x+ w+ h/ R; [) Q6 h6 n - // function __construct(){. G. C) v; [7 @0 E
- // echo 'dog in cat!';6 M, b! `+ v8 o2 T/ Z, j
- // }
' O" k- O9 r( |' W: q) Z5 |9 J - // }
2 I0 V1 Q+ W# c+ q$ l) R - class Life{
( I4 c: I8 d& |# `$ e - function __construct(){: s1 U3 [6 M& c# I ^7 U l
- echo 'cat life!';
1 b* a3 R6 {" `7 ^ - }, e6 M8 L! X7 B/ v8 ?1 ^
- }
/ j& n' _! b3 G - / M2 y7 c& m6 j) R
- use animal\dog;
0 R0 ~0 v; ^+ i - new dog\Dog();
复制代码 7 M4 k) w5 f' ~, D5 G
如上,使用了 5 p0 B: I; |& A. p
cat 通过上面代码,我想使用use的目的效果(缩短命名空间名称)就很明显了。
3 I$ [0 h7 t, E1 H简单总结一下: namespace就是划分领域的作用,代表这些东西是属于某个命名空间下的。 use就是起小名的作用,不论写起来还是说起来都可以省不少事儿。 ! j: v. B. R4 _- b- F- y& s3 c
+ U+ H: i, G0 @8 c) l9 C" K( H- x; y; G
- R& m! \2 H2 N7 E0 H% s6 Q8 s' x2 i! b6 k; A
|