|
以下皆为本人自我理解内容,如有失误之处,请多多包涵。
) R2 n* G* O: q5 m9 o文章大纲: 使用namespace的目的 namespace的使用方法 使用use的目的 use的使用方法 1 C1 a- g. ]) V$ F; @, s$ J
D% d4 E/ E+ [5 s1 e4 n( W: b使用namespace的目的:团队合作项目时,避免与团队其它成员新建的类发生冲突;个人负责项目时,避免前后新建的类发生冲突; 9 h6 n& z F8 `: X: J3 m* ]! g7 D
据个人理解,用到所需要的类时,需要先require或include引入,所以会发生类重定义的错误的前提是:两个相同命名的类都有被引入。目前有些php框架会自动加载(即include)所有新建的model类,所以为了避免你新建的model类和项目框架原生的核心类发生重名冲突,采用了namespace。(想了想,与团队成员新建的类产生冲突应该通过沟通避免,即使事发后也应该重新调整类名即时维护,避免后期造成因为对类的理解混淆而带来维护上的复杂度提高)
3 t/ h# `) Q; a6 H+ f7 O- T结合使用方法来进一步理解它的使用目的吧。 : U2 K# ?; O' S7 b# w
8 \4 a7 ^# h! o8 s6 v3 Q. t8 nnamespace的使用方法:为了进行测试,我将创建3个文件:1.php和name.php(此文件用来执行测试),后面将不再说明,请自行注意代码的变化。 1.namespace后命名的定义不区分大小写- namespace one;
! s, H) S4 `- o+ {. p - namespace One;0 W' Z8 `: {. T- t& I* k- h" |9 y& |) w
- namespace ONE;
复制代码 6 e% p! E3 f e7 W( E2 B
如上写法都可以,选择一种作为自己的规范即可。(后面代码我采用第一种进行测试哈)
" ~+ ~6 n$ W6 g3 W( m/ N, `1 y2. 没有定义命名空间,就理解为使用顶级命名空间。new类时,可以在类前加上反斜杠\,也可以不加。- //1.php
) w: d2 S; q0 f+ P. d* @+ v - class Person{
5 a: \3 |. C" W% g0 f1 h - function __construct(){
* \* h# n2 I! T( J - echo 'I am one!';
5 x0 l5 X' m; M0 `7 t - }
. e/ O) m0 t" Y @3 n7 N - }
复制代码- //name.php
$ x# Y L ^3 E4 O - require_once './1.php';
1 P; {* ]& D! { - ) s* Q) g" b& g' q9 N" w" [
- new Person(); //输出 I am one!;
, b: o5 Q% G2 |& Q1 f9 ?. H - new \Person(); //输出 I am one!;
复制代码
# {' e( v& O( I+ S2 y3. new类时,带上命名空间时,之间一定用反斜杠字符,而不是顺斜杠。记忆方法:按找%中斜杠的顺序理解为顺斜杠。(有时说反斜杠,自己都不知道是哪种方向,以前按自左向右上升方向这种方向记忆,现在感觉这个太不靠谱了)
- //name.php
2 R- Y7 G+ y+ O9 ~/ G; B - require_once './1.php';2 q$ i3 |4 _, e z# @
- new /Person(); // 代码报错:Parse error: syntax error, unexpected '/'
复制代码
7 j& j: c6 X2 m" k4.类在指定命名空间下, new类时,一定要带上指定的命名空间。没有带上指定的命名空间,按照第2点,php就会从顶级命名空间里找这个类。切记:这里不能按照顶级命名空间包含一切其它的命名空间来理解。而应该将顶级命名空间完完全全与其他命名空间区分开。 - //1.php 3 }6 \) m) V5 s% T6 U6 J
- namespace one;! }+ z/ {8 E5 A; G
- class Person{
4 U1 ^$ V. p- ^ | - function __construct(){
8 J* z% L7 g: H, a- K; P: z8 y - echo 'I am one!';
9 ]9 l2 |& L) |$ M1 S% Y( [$ u) e - }
; L! j9 p3 D( }+ i - }
复制代码- //name.php
, B. Q1 d- `0 I6 \' ~( L - require_once './1.php';
6 ~) f* U9 r. t9 ^( |. o1 L: @. h - new \one\Person(); //输出 I am one!;, w3 E! T/ h1 i8 b
- new \Person(); //代码报错:Fatal error: Class 'Person' not found
复制代码 - _3 g+ ^8 F, G3 d' v% M1 s
可以举个这个通俗例子来理解:带上指定命名空间代表某人的苹果(在他手里),顶级命名空间代表苹果箱里的苹果(在箱子里)。现在要找某人的苹果,就将某人的命名空间带上,否则就会从箱子里找某人的苹果,结果当然是找不到。
! G) K- N* q6 a. h5 h- i5.命名空间声明后的代码便属于这个命名空间,即使有include或require也不影响(重点是对后半句的理解,具体看代码)。
5 d2 |( ~" m* P, ^# o8 }- //1.php - L6 j4 ~: Q6 q7 C! q
- namespace one;
& v f% X9 h* J- c3 |7 o. L9 ~ - class Person{
: J1 W \; Z/ T t5 w - function __construct(){
" z; e$ ?0 \( k# n3 S! Q7 o0 R) l - echo 'I am one!';
' a: Y8 v% `! _+ h( E - }
, }5 T3 e( ]& ? - }
复制代码- //name.php
, Y K4 ^6 Y6 W$ ?! I8 W - namespace test;
6 Q2 u' a: F6 e5 z0 q - require './1.php'; 4 E/ S. E" I) \; z
- new \one\Person(); //输出 I am one!;
r0 S" z& L4 d% y9 F - new Person(); //这里结果会是什么呢,猜猜看1 V8 t+ M0 @1 {; {% h& r
- 最后一行结果报错:4 q6 G1 P- R3 ]7 D3 e/ x) i
- Fatal error: Class 'test\Person' not found
复制代码
- _! p) [* _9 ] t# o) T
% v0 i! r6 {1 ]& x! @) r! I1 x首先,这里与第2点比较一下:
第2点,我说,没有命名空间时,new类时,有没有反斜杠意义一样。 在这里,有了命名空间,有和没有反斜杠的意义就不一样了。 最后一行换成 + j0 w+ k2 [! |! c4 D* a
结果报错: - Fatal error: Class 'Person' not found
复制代码 # D, t( s6 ?3 t5 z" a
接着,就说说当前这点。 我们可以发现,最后一行代码对应的命名空间为test,并没有受到require文件里的命名空间的影响。 进一步加强验证,我修改了name.php文件如下: - //name.php8 G* V6 T c. g2 j% p. v4 n
- namespace test;/ o/ T9 }1 r# b" z% M7 U9 C8 J
- require './1.php'; 5 \/ G* f7 l3 {4 Y4 V0 Y, u2 i
- : p/ @. f% }* J
- class Person{: S% q8 N$ j. q2 V
- function __construct(){
9 n( n( u O* d2 |, e - echo 'I am test!';
9 `6 t* ] |: v+ E& ^* V8 x+ i2 ]/ c" d - }" I4 Q6 B& A: Z" D
- }+ z- X, P2 z0 P$ r9 x- \
) @& C: R0 ^, L/ o- new \one\Person(); //输出 I am one!;
r' ^6 n9 B+ Y# U$ W: R, w" T - new Person(); //这里结果会是什么,自己猜猜看
复制代码 * J; c* A: o1 e% b9 _9 e1 W6 G
最后,这个例子刷新了我对require的认识了。 按照我以前对require的理解:PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部分。所以我常常就简单的理解为替换,只不过把抽离出来的代码再放回原处而已。然后我试了将1.php文件内容放到name.php里: - //name.php
3 F/ X2 X0 v7 R+ c( U - namespace test;% p/ R S% l/ w9 f
- namespace one;" g1 O% {/ R: L7 J7 |
- class Person{
! ~# P' P' ?& U - function __construct(){
5 @3 [6 R7 L" ~- V# H" p+ J. u - echo 'I am one!';
; R9 K! K1 U; b" i8 E% i) d - }2 l7 C R& K" ~$ ^
- }3 d: s0 }/ H. X: H [' L
- # A& y; p4 @2 ^6 m! v9 U, a
- class Person{: |' E$ Z, I- h3 W
- function __construct(){
# d$ [5 k9 z# E# ]4 g2 z4 J; ? - echo 'I am test!';
1 x* ?$ k0 t, b. E3 u - }$ H5 N& K5 L1 Y0 y
- }
复制代码
: G( r ]) w( w+ D无需new类,该文件就会报错: - Fatal error: Cannot redeclare class one\Person
复制代码 4 I: R$ U0 L. M Y6 y
看来简单的把require理解为替换,在这里行不通。 ; `" J! A& h- [- a+ o9 g" y9 D/ B
6.namespace里不包含类名称,即使存在与类名称同名的部分,那也不代表类。new类时,还是得将这部分带上。, B2 q8 p2 q4 u5 {( y1 Z0 i* ^6 M6 ^3 q
- //name.php
5 v# }* \& x1 V( T5 Q v - ( P- p( T- l- \3 n' _5 L
- namespace test\person;
m6 C: w3 Z5 g0 u6 g) d! E# x - ! @4 U( ^& C& Q& H; f
- class Person{
( \. f4 [* h, x: d# W. Z6 s* _& f - function __construct(){
e2 c( w+ ~2 S0 {" G9 m - echo 'I am test!';' I" Y4 V D1 V* A {
- }; [0 E8 B' v- `; c. }
- }
( e+ ~1 A6 P; O3 J% M - new \test\person\Person(); //命名空间里person无法代表类名
复制代码
8 Q" q+ f. c# W, u* r不过这样纯粹是画蛇添足,直接干脆点,namespace里不要带类名称就好。
" t& l0 a8 r+ N" f0 ^& V7.一个php文件中可以存在多个命名空间,第一个命名空间前不能有任何代码。只说第一个命名空间前不能有任何代码,之后的命名空间之前可以有代码。这个自行测试即可。 - //name.php
( f) c4 i" U1 I% ` - 8 l5 m. {; R- n& S$ _" i; D
- namespace test;
- v$ e/ |( B# H6 X3 O - echo 'zhai14';
' g( E1 T8 v+ X - namespace zhai;
% `3 k- t, \. G - require './1.php';
复制代码
& l. t- m" @7 hphp命名空间namespace告一段落了,接下来说说use的用途。 使用use的目的:在命名空间字符串过长时,使用use可以相应的缩短命名空间。 9 C2 m7 v6 ?' V M. k( Z5 ^
use的使用方法:1.new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。9 `- h" r B$ M6 K' i% M5 d
- //name.php0 P" w3 z: @- p, z* `+ J/ I8 G- {0 \
- ( ~; ?6 G# c6 C' d& L
- namespace animal\dog;
" M/ p+ M8 O" S8 o3 e
9 [- o8 R- E9 ]9 R9 ?4 u- class Life{
o2 F5 a2 {, d, J K - function __construct(){$ @3 }9 h1 }/ G4 u. W
- echo 'dog life!';% c0 b. Y3 ?8 V2 O. \1 T4 j, a1 [
- }9 S; s: Q! m& p& U1 e
- }! m/ ?* \5 ^9 P8 z' V0 Q
- 4 M4 ? w6 }' g) h7 u
- namespace animal\cat;0 a! h1 z+ V' n# H8 z' ]/ a9 ~' [
0 p$ R' ? }& ^+ ^6 |! m* _- class Life{
9 c# J- \/ [5 D+ a- D2 c* p - function __construct(){! T- y. k2 f' w' D/ S* W& F
- echo 'cat life!';; `$ ?8 ^; `$ W: j1 }4 q& h
- }* M, ?/ u) I+ ?6 k0 R; S$ n2 B
- }2 N! b( U2 {3 C% [
- ' V( j% }/ c# y$ j7 I
- new Life(); //按照代码执行顺序,这里默认animal\cat这个命名空间
* h' f; \% J! t( d: W8 { - new \animal\dog\Life(); //A+ a. U; t8 G5 i' Z" g5 a
- 3 _( `: R; B6 |
- use animal\dog; //a* e6 q }8 I5 o3 f5 [ B- u
- new dog\Life(); //B
8 _( Z$ D) M; o' l5 n - ) j& l: v1 u X+ S: ?( s
- use animal\dog as d; //b) D9 [& B, m' l2 l% o
- new d\Life();
复制代码 7 V, _ ]. L; T* f0 P \
通过A、B行代码比较,需要注意: 使用use后,new类时,最前面没有反斜杠。 没使用use时,命名空间最前面有反斜杠
# H5 O+ `5 L. M通过a、b行代码比较,可以理解: use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的:
3 p+ O1 y! e# M1 R* u q相当于 ( x5 ^+ j4 f6 Z9 S R
2.namespace后面不建议加类名,但use后可以。
* b' O* e+ [# e" A- //name.php
6 R7 ]& D3 q) ]. s - 7 _; h: {' e/ c8 t
- namespace animal\dog;
2 P6 R! V5 O, V5 i% |' \' F - , N- K, T2 Z, z: o3 b: ^/ G
- class Life{. b) L& k& _$ |2 b
- function __construct(){
( F5 I: u8 f0 U* t - echo 'dog life!';; n; F7 n& K+ m" x( g. ?
- }
9 `" Y0 _; i X& O$ K/ d - }
. \7 j( a4 F! }* f- y, Y5 l - + e0 n: P& m3 t6 ~
- namespace animal\cat;# h7 T' R: d6 ?# ^- |) F; ]
- 2 Q4 ~$ P/ T0 |8 m
- class Life{
0 I8 V, \5 e, y! }9 v% s - function __construct(){
6 x+ h6 J. `- s% M1 I6 g, l j - echo 'cat life!';5 v* E" u* Q1 C \3 k
- } d! Z$ K$ ^: }* M0 J. {* [4 E
- }
9 c: b/ r- B+ ?. r - / D$ q* p0 i3 q4 ~
- use animal\dog\Life as dog;
# z5 X, g0 e& A7 Q Y2 I - new dog();
复制代码 , k4 e0 b* V( m9 a9 l" V6 M
如上所示,use后加上类名后,就相当于把类改了个名称:由Life改为dog了。 上面不用as dog就会报错: - Fatal error: Cannot use animal\dog\Life as Life because the name is already in use
复制代码 0 B$ {8 h% |8 [% |
因为cat下也有个一样名称的Life类。 可以理解为,使用use后,这个昵称对应的类只能归当前命名空间占有,其它命名空间下不允许存在该类。 - //name.php6 U$ U+ m+ i- C" ?2 b2 U$ k
- D) F3 {2 p6 |% S& _" z- namespace animal\dog;
4 Q; a' h& v; [$ e: p
# R. b3 \# k& y ?: l/ P" I- class Life{
: F S0 q0 G. J7 i8 m - function __construct(){1 w0 K" j5 [6 v/ K, k! x7 k
- echo 'dog life!';' U( p. g, g" O9 `& z: W* u5 U
- }1 T4 P6 N! l7 C/ i F" J; B" l
- }
7 J" b( D% y9 Y' q( t - class Dog{
( }6 X. M: W! s/ H0 n - function __construct(){& u, D7 v( T% F! a# W3 J; P! M& I
- echo 'dog in dog!';3 ? z+ n* r' Y. a
- }
! `/ N- `- J5 y0 c' n4 F - }- ^! R6 k3 t9 w; ]: L; Y
" A3 H* r; P4 R0 a- namespace animal\cat;6 `; T( _ X6 p$ J! X! \8 {
- o1 \ Z2 P4 a* V, R6 P
- // class Dog{9 I6 R! e5 _, p& [+ \0 }- w
- // function __construct(){
' S0 k! g/ v [- t. n3 ^! J7 p - // echo 'dog in cat!';
' y& p$ h! G* _( s6 T1 `: c - // }
4 L1 E3 x1 i' U0 U: Z" h9 ? - // }
/ p1 P2 c% u n+ C - class Life{
' y( O3 V9 c/ u- Z+ j$ U+ N - function __construct(){
, Y' ]- |& R9 F% Z - echo 'cat life!';* Y4 V( h" e4 C7 O: A
- }0 U; j$ A, @. s/ C
- }
: X$ F+ ~" v# S7 H! n - 7 x4 d1 O* t; j6 |1 j3 k( q) u/ D& I
- use animal\dog;
' _/ V3 @6 x) u4 v) J - new dog\Dog();
复制代码
4 U3 ~% S6 d# O( `% f6 }如上,使用了 & i7 G2 A5 `( {7 Q! R& J
cat 通过上面代码,我想使用use的目的效果(缩短命名空间名称)就很明显了。
: |4 Z/ Y/ y, c: d简单总结一下: namespace就是划分领域的作用,代表这些东西是属于某个命名空间下的。 use就是起小名的作用,不论写起来还是说起来都可以省不少事儿。
k' Y8 e% m8 [, |8 E- S8 _- l1 Z2 y2 \
% L. B$ [( Q' _) d, N+ _1 K
+ g. }! G$ J8 h7 |3 n, a8 G4 e5 Y& U5 X! Y4 t, D0 g* d
|