|
以下皆为本人自我理解内容,如有失误之处,请多多包涵。 L q D7 @' a& {
文章大纲: 使用namespace的目的 namespace的使用方法 使用use的目的 use的使用方法 6 a; d8 T' F$ y3 k
6 Z. [( F& ~' p1 v% k
使用namespace的目的:团队合作项目时,避免与团队其它成员新建的类发生冲突;个人负责项目时,避免前后新建的类发生冲突; % d* `& m" z1 l* G0 x/ P1 J$ d# J: l5 u
据个人理解,用到所需要的类时,需要先require或include引入,所以会发生类重定义的错误的前提是:两个相同命名的类都有被引入。目前有些php框架会自动加载(即include)所有新建的model类,所以为了避免你新建的model类和项目框架原生的核心类发生重名冲突,采用了namespace。(想了想,与团队成员新建的类产生冲突应该通过沟通避免,即使事发后也应该重新调整类名即时维护,避免后期造成因为对类的理解混淆而带来维护上的复杂度提高)
3 ?0 J' g" Q- g' P ]结合使用方法来进一步理解它的使用目的吧。
5 e& k$ {. A2 J% b% P, P+ L; J
; c3 B( u6 X1 }8 A, Y# j6 [! l. X/ snamespace的使用方法:为了进行测试,我将创建3个文件:1.php和name.php(此文件用来执行测试),后面将不再说明,请自行注意代码的变化。 1.namespace后命名的定义不区分大小写- namespace one;
7 [, o- s! {' K' L - namespace One;# {0 H: Y: _7 f2 d4 |
- namespace ONE;
复制代码 . q9 b$ \& M9 E. {- P
如上写法都可以,选择一种作为自己的规范即可。(后面代码我采用第一种进行测试哈) , h7 i' C, {" X% s# F3 t8 k
2. 没有定义命名空间,就理解为使用顶级命名空间。new类时,可以在类前加上反斜杠\,也可以不加。- //1.php / F) T/ R8 M* [' Y+ z
- class Person{
* O* F5 \" p L- o3 v - function __construct(){1 g4 l: \ e' t* ]6 M5 Z. o
- echo 'I am one!';
. F$ r1 a7 b& L; \+ `6 B9 m - }3 E) m2 e# k3 ~7 g8 X' B" }
- }
复制代码- //name.php
( B( v" D b9 q5 }& @ - require_once './1.php';2 \" _( M8 ~( ~3 G2 l9 ^4 T
- ' t Q% i6 `5 P8 R: `$ _
- new Person(); //输出 I am one!;# E/ j" r. Y7 P. a. D7 c' {5 D3 a8 z
- new \Person(); //输出 I am one!;
复制代码
7 |+ `: }) R W3 r! P' {3. new类时,带上命名空间时,之间一定用反斜杠字符,而不是顺斜杠。记忆方法:按找%中斜杠的顺序理解为顺斜杠。(有时说反斜杠,自己都不知道是哪种方向,以前按自左向右上升方向这种方向记忆,现在感觉这个太不靠谱了)
- //name.php2 d) f6 }0 [, m
- require_once './1.php';
! b2 ]" K: t1 z' X2 `. E - new /Person(); // 代码报错:Parse error: syntax error, unexpected '/'
复制代码 / N, U# I" r* v8 M s. D
4.类在指定命名空间下, new类时,一定要带上指定的命名空间。没有带上指定的命名空间,按照第2点,php就会从顶级命名空间里找这个类。切记:这里不能按照顶级命名空间包含一切其它的命名空间来理解。而应该将顶级命名空间完完全全与其他命名空间区分开。 - //1.php
& k, d1 S5 [2 j, \ - namespace one;
( U: Q g. Z9 R1 R+ S$ M6 \, s - class Person{* z, p1 r: e4 ]; _; ?) X2 u" Y3 M
- function __construct(){
, o `$ ]. {0 I - echo 'I am one!';
( y8 ^, {0 f$ u9 `( A - }
1 t f- z3 j2 \# Q1 P - }
复制代码- //name.php9 g: H1 G+ f5 K7 H0 C( e. W' B* v
- require_once './1.php'; f, v9 X' S0 z, s/ ?
- new \one\Person(); //输出 I am one!;% G1 N& G- ~; l
- new \Person(); //代码报错:Fatal error: Class 'Person' not found
复制代码 ) c( d& w u. I; }* @. [5 M2 C+ [+ |
可以举个这个通俗例子来理解:带上指定命名空间代表某人的苹果(在他手里),顶级命名空间代表苹果箱里的苹果(在箱子里)。现在要找某人的苹果,就将某人的命名空间带上,否则就会从箱子里找某人的苹果,结果当然是找不到。
4 O; E' r4 m4 V9 i0 k c/ q! N! c" ?5.命名空间声明后的代码便属于这个命名空间,即使有include或require也不影响(重点是对后半句的理解,具体看代码)。0 l/ \; {7 b+ P0 U' H# R
- //1.php
" C6 P/ `+ }4 R- }! G, C% C+ A - namespace one;2 Q8 Y; g( E" g" B! `. q
- class Person{
+ f& _* ^6 @3 `& Z - function __construct(){
8 @; B3 i. z- d" ~# s - echo 'I am one!';+ s9 g8 w) r' N- G. m
- }
1 p1 O/ ~- @0 _) v8 e$ O' T9 ^! b - }
复制代码- //name.php
# m5 w1 S8 ]5 P - namespace test;
: c; A+ b2 ?: @. f6 s - require './1.php'; 1 @, p4 ~# x, e4 v" c
- new \one\Person(); //输出 I am one!;
" f* s' D1 H5 c# F0 o7 N - new Person(); //这里结果会是什么呢,猜猜看 k" m2 W- l; [! Q
- 最后一行结果报错:3 _$ J2 l: M, u4 i9 i# F) p: h2 |
- Fatal error: Class 'test\Person' not found
复制代码 5 a) s( b; @# d0 [
, T7 s0 p2 I9 H! W- |首先,这里与第2点比较一下:
第2点,我说,没有命名空间时,new类时,有没有反斜杠意义一样。 在这里,有了命名空间,有和没有反斜杠的意义就不一样了。 最后一行换成 0 |% v$ [, a1 P$ W
结果报错: - Fatal error: Class 'Person' not found
复制代码 " g5 ~5 O1 \5 |# e1 W; m9 T* J) u. S
接着,就说说当前这点。 我们可以发现,最后一行代码对应的命名空间为test,并没有受到require文件里的命名空间的影响。 进一步加强验证,我修改了name.php文件如下: - //name.php
J1 j {1 R t4 Z; B' f - namespace test;
- s4 r6 ^% Q! p5 E6 W - require './1.php';
z) ^/ h F9 }* t6 Q0 s% D - 3 S9 r' i5 C8 ` x
- class Person{
) j) Q& J! K& ?0 m" ]1 [& }6 s - function __construct(){8 P/ O- ~5 i; l. p/ j
- echo 'I am test!';
* I# @% r5 y# j5 m - }, {9 A2 \# w# h: g, p* A: N
- }
7 z( |4 g3 R% R! O V7 z, B$ C7 z - 0 m, U4 j% L, |' g2 k {
- new \one\Person(); //输出 I am one!;2 C/ b/ t- \) z3 G e; X* U- A
- new Person(); //这里结果会是什么,自己猜猜看
复制代码 $ e7 K. B+ E; n4 e8 ]
最后,这个例子刷新了我对require的认识了。 按照我以前对require的理解:PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部分。所以我常常就简单的理解为替换,只不过把抽离出来的代码再放回原处而已。然后我试了将1.php文件内容放到name.php里: - //name.php
4 @$ B; }/ k0 f( q& U& _3 `; N6 [ - namespace test;2 r" s+ M. k$ q6 x1 F
- namespace one;
; D0 R& Z7 s4 ~' _ - class Person{
9 s$ B J3 V \ - function __construct(){
) A3 q6 W4 j7 _+ k" }0 o - echo 'I am one!';
7 m1 K/ l: x6 z, { w8 k9 ] - }7 ~0 C" e" s- A
- }2 N4 Y- I+ V* J9 x
5 H6 [1 Z v- Z" A4 ~- f- class Person{
; C7 {% j! z5 o& L6 t- y F! y - function __construct(){
, c8 G- ~/ R# m5 z - echo 'I am test!';
( j: w( V1 d. M5 \ - }
) I/ d5 V f0 ]; R/ ] - }
复制代码 6 d$ g! L4 I& ~; w! p. |0 M
无需new类,该文件就会报错: - Fatal error: Cannot redeclare class one\Person
复制代码 2 ]" p% e6 n) d) X# B" Z& d
看来简单的把require理解为替换,在这里行不通。
, k; n( `8 g& l" R- Z1 o6.namespace里不包含类名称,即使存在与类名称同名的部分,那也不代表类。new类时,还是得将这部分带上。
W$ U. @4 Q5 B* a9 j+ U% p- //name.php
8 J A. f: G% O' u) ^- r - 7 B$ Q! ?6 X$ q. G
- namespace test\person;
6 }0 n, m3 U" e n - 9 ~- t. Z. t! d' b% I
- class Person{
0 B' [" r% R. d) K - function __construct(){/ q4 R; k" E5 o' ]- N, `
- echo 'I am test!';
6 c$ x% N9 I! P. P- T. O - }
. y3 B; g7 e u8 p( e! A2 u' s - }
1 Q1 L" ^& D4 | - new \test\person\Person(); //命名空间里person无法代表类名
复制代码
& b/ c; B' @& ^2 u5 |$ a! w不过这样纯粹是画蛇添足,直接干脆点,namespace里不要带类名称就好。
* D# m+ F; L) s2 O* X% l6 x! C7.一个php文件中可以存在多个命名空间,第一个命名空间前不能有任何代码。只说第一个命名空间前不能有任何代码,之后的命名空间之前可以有代码。这个自行测试即可。 - //name.php
9 {7 e3 ]7 {/ S, T0 U1 F3 U5 B: m5 E' Z - , s5 g R9 v6 n; M, Z+ E
- namespace test;
$ e, P% U( z2 n% g5 s) x% M - echo 'zhai14';0 w5 ^5 r1 L3 F$ {& t3 y
- namespace zhai;
) N9 D6 q* M8 m4 S( |7 o" D; d - require './1.php';
复制代码
8 c: f2 p1 { e: ]' o/ O: Rphp命名空间namespace告一段落了,接下来说说use的用途。 使用use的目的:在命名空间字符串过长时,使用use可以相应的缩短命名空间。
7 V, |! b* h8 i1 g% H' Y8 |use的使用方法:1.new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。, v- M; a% `( q4 C9 W
- //name.php
9 t$ Y. B8 V' F0 L - ) A7 A" t: X, y, u: R, M- `
- namespace animal\dog;# o2 y$ `. I+ @! q
8 P* h% I, ^+ u- class Life{
1 R+ R# P9 k. ^2 B+ r8 L: T - function __construct(){
8 J7 }- W# Z7 Z8 P9 k6 B/ y - echo 'dog life!';1 t2 I/ J" h- X; o
- }
s, b+ b- p2 @1 @# A; q: T2 O - }
7 E# U3 ~5 e& |) e' c' H( u - % M/ V9 L; G! X7 v+ t! [/ l
- namespace animal\cat;: i) }2 z8 s/ i) ^: ]8 B L, D- o
, ?8 v8 y! s, s/ o7 o- class Life{
8 W' L* @3 y( T. V - function __construct(){
9 \4 Z1 D/ ]* w$ Y" Q6 h8 L - echo 'cat life!';; k. H4 Z* Z8 E- c1 G
- }' w) [/ D P, Q
- }
& I+ M; K( V0 d8 Q* Z
. r3 M7 M# y; C4 E! j+ g" }5 |+ O0 y% u% F- new Life(); //按照代码执行顺序,这里默认animal\cat这个命名空间
& C$ l. D/ _# L( W. S- y - new \animal\dog\Life(); //A
2 _" L1 v0 }& M" M - & w; B! y2 ?, ?' A8 x+ _' y1 ?4 D
- use animal\dog; //a
3 U7 y% j. _' } Z) U - new dog\Life(); //B6 Y( V+ b. C6 q6 d6 \
- 0 ^+ ~2 a1 Y+ V: h" n' Y, E
- use animal\dog as d; //b+ d+ j0 |- {3 X! g t3 a8 ~
- new d\Life();
复制代码
* u% z. j+ U9 }, t通过A、B行代码比较,需要注意: 使用use后,new类时,最前面没有反斜杠。 没使用use时,命名空间最前面有反斜杠 & ^. C: z x; S8 X: i. _7 }
通过a、b行代码比较,可以理解: use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的: ; k4 T0 I7 h+ e( s% {" g2 E' w
相当于 2 f0 w. o( v% K% w0 o: ?9 `
2.namespace后面不建议加类名,但use后可以。; t6 A; @+ C3 U5 I( r
- //name.php- A& L. L' w$ e& h
- $ m/ @7 c8 Z' g+ K0 J
- namespace animal\dog;
7 {, L) q0 p6 |- M
2 R, h) y6 o$ U2 E) E: C- class Life{7 {, U% G4 Q$ n7 Q! W; t. G
- function __construct(){
+ Q9 D0 z! T9 d3 J( I0 Y, o5 F - echo 'dog life!';2 x& _( s" N( t, x( M' R
- }* i+ ~- g% i, k$ r* D& ^2 d
- }! j$ S8 g9 M0 \
- ' ?+ ?* Z8 }% a- l5 s* l
- namespace animal\cat;! f6 S3 A$ s, W4 I
- 4 ?, R) \' G2 y \/ P
- class Life{
$ j6 V* K5 a k2 H) i - function __construct(){6 f7 Q$ O R8 E- f, ~) w$ e* Q
- echo 'cat life!';7 r% v C! ~% L' t# m
- }
. w$ |2 D$ l" o% ]0 o' T6 t$ } - }- m# H: ?3 k/ e" W8 p, P. m$ p
- . ^3 _& l! j7 s% V
- use animal\dog\Life as dog; ' \+ }$ }% B& J/ N
- new dog();
复制代码
* y% r, {7 A! V& y如上所示,use后加上类名后,就相当于把类改了个名称:由Life改为dog了。 上面不用as dog就会报错: - Fatal error: Cannot use animal\dog\Life as Life because the name is already in use
复制代码 + D( Z) h4 P$ ~2 k! ^+ r/ M6 G
因为cat下也有个一样名称的Life类。 可以理解为,使用use后,这个昵称对应的类只能归当前命名空间占有,其它命名空间下不允许存在该类。 - //name.php! I7 R* E- E3 ]
4 h+ j; f: C2 ]5 i- namespace animal\dog;
% m0 j, y# W( I( J5 W$ `' C
. h; b9 i4 A* t4 c- class Life{
' u+ J, w' e' n+ `; d - function __construct(){
[/ w4 [9 E& P' g7 R. U - echo 'dog life!';
B. X/ r9 w8 s4 | d - }- D, ^3 c( Y/ N+ t: o7 J/ ^
- }
( Z6 j( ?4 F1 |, @ - class Dog{! v) P) A! F% |8 p* e' t* S
- function __construct(){
7 B) m V( a. j" u# {% Z) x a* K& ~ - echo 'dog in dog!';% ?5 S k, } f: Z) m& V- Y/ J5 i
- }4 v7 E3 U7 s5 ^: @0 ] j ~
- }/ u% @* x0 Z7 _1 i* b! T
- + D/ L& l0 B+ J1 i$ v
- namespace animal\cat;
6 @( k. [$ y& j2 G
1 d8 [4 I. y7 j- // class Dog{
+ `# B1 n% S+ x4 u - // function __construct(){2 r) f- Z, F; T$ Z5 C* N
- // echo 'dog in cat!';+ G2 ]! S2 I; s4 _8 L6 u
- // }) g# H+ n3 T' R4 ^# G6 D% y
- // }' a, H- Y3 m/ c ~ M
- class Life{
, n0 k5 j' m4 N$ n; ]1 n( ^2 v& \ - function __construct(){
) e% @$ c/ D4 g. l! @ - echo 'cat life!';) W4 n* } F4 _: C: k; o; I
- }
; M. _4 e* ]' b( E! i - }
8 X" {, |1 f" m: u3 ~& V" `7 f: ^ - 7 x9 W: r; a% h0 c7 `( W8 E
- use animal\dog; + z% B: [# c& t+ X6 v
- new dog\Dog();
复制代码 B" t* f7 { \. p7 a* l) ]
如上,使用了 % B+ q+ S. d+ d; ]
cat 通过上面代码,我想使用use的目的效果(缩短命名空间名称)就很明显了。
6 k; O& ]" H0 w! E0 x( O简单总结一下: namespace就是划分领域的作用,代表这些东西是属于某个命名空间下的。 use就是起小名的作用,不论写起来还是说起来都可以省不少事儿。 % P. C. r7 Y$ p2 l" T! x# f/ O
, `$ J! B' q% d6 U8 o
* \. @8 p8 ^* t+ R( o
* S! |! j' R# y0 J4 h- X0 ?. D1 Q# W- N" k; h# s) k1 z
|