以下皆为本人自我理解内容,如有失误之处,请多多包涵。
: v2 a# W" O" ^4 G+ e6 i文章大纲: 使用namespace的目的 namespace的使用方法 使用use的目的 use的使用方法
/ x0 V4 n5 N- K3 I4 s$ L0 y3 ?8 N# x1 f& |- h/ m
使用namespace的目的:团队合作项目时,避免与团队其它成员新建的类发生冲突;个人负责项目时,避免前后新建的类发生冲突;
0 v- n2 |3 o3 J1 L% M7 m: s& B5 c据个人理解,用到所需要的类时,需要先require或include引入,所以会发生类重定义的错误的前提是:两个相同命名的类都有被引入。目前有些php框架会自动加载(即include)所有新建的model类,所以为了避免你新建的model类和项目框架原生的核心类发生重名冲突,采用了namespace。(想了想,与团队成员新建的类产生冲突应该通过沟通避免,即使事发后也应该重新调整类名即时维护,避免后期造成因为对类的理解混淆而带来维护上的复杂度提高)
: I0 c% _# ?' x* A结合使用方法来进一步理解它的使用目的吧。 4 u4 r. F$ X2 p o$ T
( A/ V7 U! `5 W0 Q+ inamespace的使用方法:为了进行测试,我将创建3个文件:1.php和name.php(此文件用来执行测试),后面将不再说明,请自行注意代码的变化。 1.namespace后命名的定义不区分大小写- namespace one;% i* r2 `3 J. \" S4 ?. Q( @6 u4 I
- namespace One;' F+ T6 {/ R" T, ], v6 l' @
- namespace ONE;
复制代码 " }. S8 f" S8 x2 |1 Z; h. l1 @: s
如上写法都可以,选择一种作为自己的规范即可。(后面代码我采用第一种进行测试哈)
* e( b) ?# X* I! G" H2. 没有定义命名空间,就理解为使用顶级命名空间。new类时,可以在类前加上反斜杠\,也可以不加。- //1.php ) \' e( ]9 q9 t& i2 M r2 ~
- class Person{* t2 ~3 x' |0 E3 f; T1 s% U' D5 V, }6 W
- function __construct(){& Z1 L- Z" I" e0 M, z) p
- echo 'I am one!';
% ?% q6 t1 g9 O+ k% } - }
}. C' Z/ Z0 z: k2 e - }
复制代码- //name.php
; s! I" J* P( w5 i* q5 b& k. V - require_once './1.php';
- n% L9 z# ~( _/ Z: Q+ ?7 B) J
4 W4 v4 B2 G; @: N4 \- new Person(); //输出 I am one!;
7 u0 f: D" T2 p4 X - new \Person(); //输出 I am one!;
复制代码
% D7 r/ `# x3 U3. new类时,带上命名空间时,之间一定用反斜杠字符,而不是顺斜杠。记忆方法:按找%中斜杠的顺序理解为顺斜杠。(有时说反斜杠,自己都不知道是哪种方向,以前按自左向右上升方向这种方向记忆,现在感觉这个太不靠谱了)
- //name.php9 D) P2 V! N4 f
- require_once './1.php';
; R C3 W. v! H4 x M% K - new /Person(); // 代码报错:Parse error: syntax error, unexpected '/'
复制代码
' R8 \0 [! P( H- ?" \) p f3 {4.类在指定命名空间下, new类时,一定要带上指定的命名空间。没有带上指定的命名空间,按照第2点,php就会从顶级命名空间里找这个类。切记:这里不能按照顶级命名空间包含一切其它的命名空间来理解。而应该将顶级命名空间完完全全与其他命名空间区分开。 - //1.php % k4 `4 l2 O. U( D9 ?! m
- namespace one;+ s! p5 U5 H# s
- class Person{: Q9 S/ _) r# s& S& [& f5 H9 L( Z
- function __construct(){. a9 U/ m0 Z8 ~+ q
- echo 'I am one!';
$ T! d8 |0 S! ^; Z2 H2 |4 F# S3 s - }6 l2 e; Q1 _0 z" x0 S7 G2 V
- }
复制代码- //name.php1 N0 U" u3 i" L* w$ l/ e$ ]. N
- require_once './1.php';# ^/ [7 T9 p& a% x' L# `5 P
- new \one\Person(); //输出 I am one!;
; {# m# v0 Y# z6 ^) a - new \Person(); //代码报错:Fatal error: Class 'Person' not found
复制代码 3 c% @8 u1 g5 f8 Q0 \- ^. G
可以举个这个通俗例子来理解:带上指定命名空间代表某人的苹果(在他手里),顶级命名空间代表苹果箱里的苹果(在箱子里)。现在要找某人的苹果,就将某人的命名空间带上,否则就会从箱子里找某人的苹果,结果当然是找不到。 % Q( p! {. T$ l& t
5.命名空间声明后的代码便属于这个命名空间,即使有include或require也不影响(重点是对后半句的理解,具体看代码)。
6 H' N) N, K% o4 M- //1.php 1 D. {5 S% N3 E( h) `! b, s2 e
- namespace one;
3 z7 b9 z7 R! S" M2 L: t - class Person{
3 Q6 {- B9 W* D% ]( | - function __construct(){
0 ?* K f! W% y+ z8 K - echo 'I am one!';
3 S* X, h/ A2 t7 l - }6 }/ o$ U5 j8 C3 D
- }
复制代码- //name.php) w. A i7 Z1 P) s4 J
- namespace test;3 K' w2 b! n% \4 e/ _
- require './1.php'; 4 e" `. g! o- n \
- new \one\Person(); //输出 I am one!;# u$ J+ t0 w/ Y" n3 l2 o
- new Person(); //这里结果会是什么呢,猜猜看& E( d$ w$ T4 a" A: M1 m
- 最后一行结果报错:. q" D4 @# V+ z$ _
- Fatal error: Class 'test\Person' not found
复制代码 K" s) e, D! D; y* q- z
3 h( m" ~( f0 A1 X$ d
首先,这里与第2点比较一下: 第2点,我说,没有命名空间时,new类时,有没有反斜杠意义一样。 在这里,有了命名空间,有和没有反斜杠的意义就不一样了。 最后一行换成 6 G5 T. i. H' s. b) ~5 y3 p; y; ^
结果报错: - Fatal error: Class 'Person' not found
复制代码 3 b7 I# ^8 T$ @0 N' a4 g+ A6 g
接着,就说说当前这点。 我们可以发现,最后一行代码对应的命名空间为test,并没有受到require文件里的命名空间的影响。 进一步加强验证,我修改了name.php文件如下: - //name.php2 K- v* E) |( E0 C! \/ p( T; P/ U
- namespace test;
! h4 f. N3 [5 O! L7 w3 S# N - require './1.php'; 8 a# M3 M$ s7 H. E
- : f! T5 L8 g+ u$ c* c
- class Person{3 m& n" _. y% {" y/ ?
- function __construct(){
, C) p) N/ D7 E ~ - echo 'I am test!';
, v7 L2 o9 D& d; t5 M4 Y - }" y$ Y7 `7 P, a& S6 A0 C8 A
- }
4 n- w/ i, K5 w( K5 I& r
; i) D/ z+ l# @* A2 L+ {8 A- new \one\Person(); //输出 I am one!;
+ a4 |: B. y- c- V - new Person(); //这里结果会是什么,自己猜猜看
复制代码 3 X8 g4 M" ^0 b5 q
最后,这个例子刷新了我对require的认识了。 按照我以前对require的理解:PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部分。所以我常常就简单的理解为替换,只不过把抽离出来的代码再放回原处而已。然后我试了将1.php文件内容放到name.php里: - //name.php2 `; L$ W; t m8 `/ l( X
- namespace test;- D( h3 o. n5 y- V" _% }
- namespace one;3 g5 b2 I3 J; P" y# a9 ?. E/ B
- class Person{
( L; u. @' f0 v9 J8 k - function __construct(){. n8 x! J4 G& h! M8 i6 ~3 ?
- echo 'I am one!';7 i+ n; M3 E6 C# y$ A: X% l3 m
- }
# P$ A1 E$ ]3 e l7 Y& r - }
. [+ U2 J9 q7 v - ) T, i2 r. E ]! X; g7 E. u) h* c
- class Person{3 w @, F- [6 T" C3 e [ F; \
- function __construct(){7 q& S$ ^7 i& l$ t8 w' Y
- echo 'I am test!';
; i. A+ ~% L, q) w1 b% R# Q/ u - }
% D% c+ ]5 O$ z4 i$ l/ C5 c - }
复制代码
/ ?* q( V$ Q0 x: a8 B无需new类,该文件就会报错: - Fatal error: Cannot redeclare class one\Person
复制代码 8 i$ e- [$ c, [. x
看来简单的把require理解为替换,在这里行不通。
# T" _( C6 |( c3 T% N, m1 _; ?6.namespace里不包含类名称,即使存在与类名称同名的部分,那也不代表类。new类时,还是得将这部分带上。
6 @0 }/ [9 ?0 d# h4 R0 N- //name.php
5 N s' B3 D; o1 k% Z; Y" Y' l# }. Z
0 O3 g; p: u2 d' Y S9 R- namespace test\person;
! O& M9 r/ p" h$ x - 5 r+ g7 R. C% o
- class Person{( H7 S3 y: Z+ ?/ C6 o$ v
- function __construct(){+ d* ~- ]; B& ~: U
- echo 'I am test!';; ?, z" }0 c4 d7 r
- }' s- G, W$ g# a7 S7 \5 `
- }& g' w) R5 r4 x G a
- new \test\person\Person(); //命名空间里person无法代表类名
复制代码 1 k0 g1 V% ^5 s
不过这样纯粹是画蛇添足,直接干脆点,namespace里不要带类名称就好。 - s, l1 g( w4 c- @& {
7.一个php文件中可以存在多个命名空间,第一个命名空间前不能有任何代码。只说第一个命名空间前不能有任何代码,之后的命名空间之前可以有代码。这个自行测试即可。 - //name.php4 D! c0 c) i4 k: Q+ W0 n
1 N) f7 n2 Y9 E7 I( Q- namespace test;5 K' }! W, s! u; C
- echo 'zhai14';0 c! V; ]% n7 p) v
- namespace zhai;4 {8 P9 K0 |6 G, F
- require './1.php';
复制代码 " J% ?( h& o% v2 ]
php命名空间namespace告一段落了,接下来说说use的用途。 使用use的目的:在命名空间字符串过长时,使用use可以相应的缩短命名空间。 $ C. P- s5 @/ o) N9 e
use的使用方法:1.new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。: E0 J+ M, Z( L2 e5 r0 g# }
- //name.php* X/ Y9 E/ M; X' U$ P4 h
& O$ o' i8 x. |, i- namespace animal\dog;+ Q9 N; f# Y1 X% d0 W
1 e9 a( ~, T7 z/ X0 N- class Life{0 C" m0 ]+ k- J$ Y0 `5 N' C
- function __construct(){1 D* e o) l: n7 S5 o7 h
- echo 'dog life!';
+ E" N7 x9 Y6 m( y8 x' u9 H - }6 ^5 _0 D; q0 [; {1 N- y) e
- }
. y0 j4 ?. p; G/ Z
3 W$ a+ S7 O1 \6 y7 w! ~! V+ r- namespace animal\cat;
0 o: ~ l9 u7 c0 T
0 K8 A3 y) z$ G3 c; N+ q- Y$ {- q- class Life{
+ k/ z" C$ p! {- P' a" r6 d- _ - function __construct(){& P% o. J' w. m S; ^* ]
- echo 'cat life!';7 D. q" _ B2 u" O) L5 z
- }
! K% L- B* `8 h- W - }1 u) E9 P9 n5 N0 f
& Y8 y$ Z/ e4 n/ m+ c5 O2 K- new Life(); //按照代码执行顺序,这里默认animal\cat这个命名空间
9 R- G! ]1 D+ t* ]# i - new \animal\dog\Life(); //A
! j. u) B7 r- c r2 S: A5 m
. H+ [, r: D7 v0 s) D1 F- use animal\dog; //a
, ]; P+ E" r9 A2 n - new dog\Life(); //B
, H& H0 h O- [# G
" ~/ \8 T3 ?; Z1 t+ T! ]& M- use animal\dog as d; //b. U+ A8 r! Y5 ~
- new d\Life();
复制代码
4 I) ~( q/ @4 S" G+ ?通过A、B行代码比较,需要注意: 使用use后,new类时,最前面没有反斜杠。 没使用use时,命名空间最前面有反斜杠
3 G! N% Y* O( I% L$ `! {' _4 P通过a、b行代码比较,可以理解: use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的: 9 l) [0 u6 {/ p& T* O
相当于
# r$ r" @2 H+ Y' Y- M- v6 q6 f& {: q2.namespace后面不建议加类名,但use后可以。! I. S/ v/ F( Y- s g* u- z
- //name.php! V; g8 F- w. d/ u
- 0 O( o0 ~7 @! [& z M F$ O- n
- namespace animal\dog;' p$ T& M7 i6 C/ L- ^: k
; t. c3 s( P, ^1 |- class Life{
& O8 G$ H3 B( v - function __construct(){
$ J k# q+ ?0 C/ { - echo 'dog life!';8 H" ?. L: P7 J( p
- }* o) {' E: ^8 U |$ m* x
- }) b1 A" O' g: X. g: P+ h& U8 A
/ n7 _( _7 }4 s1 T4 D; J) C- namespace animal\cat;4 u5 g( ~ b: J% ], r+ _) z
- ( h# }2 q X6 o* Z4 }
- class Life{2 t8 r0 @3 k2 T( ` O; s
- function __construct(){" E! H1 N2 e) v$ i7 k8 m2 b
- echo 'cat life!';( ?7 |) Y8 I+ `4 J) B
- }" a+ H: @$ d- r& M7 [5 A- N% k
- }
2 m; B6 l, Q& d7 N - 0 c7 ^4 ]5 t+ U
- use animal\dog\Life as dog; * x% w* F) `3 H/ o' l# b' D
- new dog();
复制代码 - d7 {" o: ]7 @( ?, P
如上所示,use后加上类名后,就相当于把类改了个名称:由Life改为dog了。 上面不用as dog就会报错: - Fatal error: Cannot use animal\dog\Life as Life because the name is already in use
复制代码 * }: V$ P: Z- U: l5 X( X: Y9 V4 P
因为cat下也有个一样名称的Life类。 可以理解为,使用use后,这个昵称对应的类只能归当前命名空间占有,其它命名空间下不允许存在该类。 - //name.php# ~' l( H! ?5 B+ i1 y
- ' t+ x& f- [ B; P. e4 W
- namespace animal\dog;& w5 G, d' J! W a0 B" |9 X
" N% }. K2 F; {6 H. \: {- class Life{
- q( }* K% X: @( \6 v; Y - function __construct(){
* L" q1 ?1 w! l' \3 Z* j* ^ - echo 'dog life!';
! N. F" z2 p! e - }! B7 {1 J+ }; G) C! {3 Y
- }
1 V) a- S( ?9 b- Y4 Z2 H; [, @ - class Dog{- a4 a0 p3 x4 I
- function __construct(){
6 P- t4 D' O" h/ R2 F3 \2 ~- s! |/ L: C - echo 'dog in dog!';
. Z0 i8 i! Q: d7 g - }) l- V4 E; x; ?9 O5 C
- }) n9 c. I$ M1 \% O$ f" ~
8 r) a2 c( k- @- ^0 d& l: {- namespace animal\cat;
- `0 Z" ?/ \' m8 u( k - * j# h4 x% K. l/ K, w5 {
- // class Dog{- g1 C4 A8 P1 C
- // function __construct(){
/ n$ R8 Z4 k U- w3 I: U1 C - // echo 'dog in cat!';
2 A9 v$ \# J5 T+ h% A" v - // }
& W8 `) m5 O) t, W$ L+ L. l - // }7 q( j2 w/ b5 W" q3 \/ l# d/ u% I
- class Life{
; p& M/ {: p# O8 H9 ~3 m - function __construct(){0 s' L' T% ~$ c3 K
- echo 'cat life!';3 |" W; Y5 N+ U- v
- }
1 h+ _, G1 T$ n f9 N# _ - }9 |, {/ F. K. x3 _- u2 g
- ' K. z; ?$ |9 w8 |- J
- use animal\dog;
9 {" L% ?5 }* _# R1 k1 ? - new dog\Dog();
复制代码 6 t3 i. H9 }" P4 V* A
如上,使用了
! A" H) ^: o: U) U- _) {cat 通过上面代码,我想使用use的目的效果(缩短命名空间名称)就很明显了。
; O2 n% l% `$ p2 B' J: s/ Y: [简单总结一下: namespace就是划分领域的作用,代表这些东西是属于某个命名空间下的。 use就是起小名的作用,不论写起来还是说起来都可以省不少事儿。 t# o- k! m/ ~* U! K
$ X* w k W) L; k* w' Y- p5 c% P
& H2 h$ _! V. m
) j6 w5 H- w( R7 ~- A8 R
) D7 Y; ^* n$ M. }% B- n& l
|