以下皆为本人自我理解内容,如有失误之处,请多多包涵。 7 A3 H% n9 y6 r" ]4 O8 L, P
文章大纲: 使用namespace的目的 namespace的使用方法 使用use的目的 use的使用方法 r; f2 j2 t& H/ R; }( t
- f5 e! _9 K: Q. g, ]9 x, ]' U使用namespace的目的:团队合作项目时,避免与团队其它成员新建的类发生冲突;个人负责项目时,避免前后新建的类发生冲突; ) i: b1 A. P8 N8 Q0 q! t: g3 I
据个人理解,用到所需要的类时,需要先require或include引入,所以会发生类重定义的错误的前提是:两个相同命名的类都有被引入。目前有些php框架会自动加载(即include)所有新建的model类,所以为了避免你新建的model类和项目框架原生的核心类发生重名冲突,采用了namespace。(想了想,与团队成员新建的类产生冲突应该通过沟通避免,即使事发后也应该重新调整类名即时维护,避免后期造成因为对类的理解混淆而带来维护上的复杂度提高)
4 h& R7 s$ _3 K% r结合使用方法来进一步理解它的使用目的吧。 ) ]4 s4 Z! `& ]9 X
" [$ _& W ^2 R- n, d: H- C* Knamespace的使用方法:为了进行测试,我将创建3个文件:1.php和name.php(此文件用来执行测试),后面将不再说明,请自行注意代码的变化。 1.namespace后命名的定义不区分大小写- namespace one;
( d" r) v: I! q% i4 o& t - namespace One;
) o3 F+ e8 b( t4 ~0 _0 X! \ - namespace ONE;
复制代码
+ A# d' ]: X/ `4 n4 p, V/ t如上写法都可以,选择一种作为自己的规范即可。(后面代码我采用第一种进行测试哈)
( h$ k1 e% J4 T Z+ @- Y+ S2. 没有定义命名空间,就理解为使用顶级命名空间。new类时,可以在类前加上反斜杠\,也可以不加。- //1.php ) k( F; p! K9 v l- p; ^
- class Person{
7 b% P: V! u& F, S8 l- a - function __construct(){
, m" r* T. O' K1 n$ i# g - echo 'I am one!';
/ m+ ?# m$ k4 N5 A, p5 u* V - }
& r+ ^9 b, ?: I; g* |" C) X0 r - }
复制代码- //name.php- A# R( g( K+ k
- require_once './1.php';/ G9 O4 M& @0 T+ _
- 1 ^, l8 {8 {2 z; [
- new Person(); //输出 I am one!;$ I# p% A9 |! m# | {
- new \Person(); //输出 I am one!;
复制代码 9 y' T% Q+ c, L: k; \0 E/ ]" G
3. new类时,带上命名空间时,之间一定用反斜杠字符,而不是顺斜杠。记忆方法:按找%中斜杠的顺序理解为顺斜杠。(有时说反斜杠,自己都不知道是哪种方向,以前按自左向右上升方向这种方向记忆,现在感觉这个太不靠谱了)
- //name.php7 w# z- g- s0 G% w, e; P- Z
- require_once './1.php';6 h8 q) U; c6 H/ w: q
- new /Person(); // 代码报错:Parse error: syntax error, unexpected '/'
复制代码
* t! Z v5 P9 ]& p* s4.类在指定命名空间下, new类时,一定要带上指定的命名空间。没有带上指定的命名空间,按照第2点,php就会从顶级命名空间里找这个类。切记:这里不能按照顶级命名空间包含一切其它的命名空间来理解。而应该将顶级命名空间完完全全与其他命名空间区分开。 - //1.php % p# ~, |1 W6 P/ r$ ?
- namespace one;
3 L$ s/ K) v6 e) n g" [ - class Person{
3 M/ ?( s8 C+ M8 \& O) s - function __construct(){7 V! J6 Y3 @% p4 Q9 I- l8 h6 ?
- echo 'I am one!';8 N F- ~3 N0 Y1 r. X( F: p! B
- }2 ]$ k- D" S3 y$ K! T) B1 h# {
- }
复制代码- //name.php2 _9 t! S% k. G
- require_once './1.php';
9 o# r* N& V" I7 l' Y - new \one\Person(); //输出 I am one!;$ i4 P0 @ @% C) ~
- new \Person(); //代码报错:Fatal error: Class 'Person' not found
复制代码
7 t% T' U3 V0 D% l9 C! }) q- y7 y8 i可以举个这个通俗例子来理解:带上指定命名空间代表某人的苹果(在他手里),顶级命名空间代表苹果箱里的苹果(在箱子里)。现在要找某人的苹果,就将某人的命名空间带上,否则就会从箱子里找某人的苹果,结果当然是找不到。
7 Y1 ]% S; c; ~* M. `5 g5.命名空间声明后的代码便属于这个命名空间,即使有include或require也不影响(重点是对后半句的理解,具体看代码)。
. z& O! C" D2 o5 y4 x F2 P- //1.php
3 z- m7 a# P2 F: m4 a - namespace one;
' y3 j$ _" V+ j) \6 l5 w! X - class Person{' ?+ N; A9 d8 ^; ]8 E0 P- p0 M3 i
- function __construct(){
. `$ N' L& p3 @ - echo 'I am one!';0 a/ G; j. Y. ]" R. H8 E% U7 E
- }
3 P3 Z+ P0 o0 [ - }
复制代码- //name.php6 ?6 l' J: E% P) s
- namespace test;
, E# i h& m. X/ r! H5 ~( f - require './1.php'; ' I: ], [" F' E' \6 y1 S
- new \one\Person(); //输出 I am one!;2 ]% |. L5 o! y `
- new Person(); //这里结果会是什么呢,猜猜看: B: }( D1 {4 F3 g
- 最后一行结果报错:3 o$ ^! m4 Y9 z
- Fatal error: Class 'test\Person' not found
复制代码
! `" q0 }5 C) C* P6 G) P$ d8 G
* q4 f0 {- `$ W3 m4 h$ _1 T1 Y首先,这里与第2点比较一下:
第2点,我说,没有命名空间时,new类时,有没有反斜杠意义一样。 在这里,有了命名空间,有和没有反斜杠的意义就不一样了。 最后一行换成
- F0 ]4 i" |# l- t" O2 r- l结果报错: - Fatal error: Class 'Person' not found
复制代码
. `4 i9 c+ Z: o- x0 x& O接着,就说说当前这点。 我们可以发现,最后一行代码对应的命名空间为test,并没有受到require文件里的命名空间的影响。 进一步加强验证,我修改了name.php文件如下: - //name.php
: h5 N. @$ p( ^! G# \! ^ - namespace test;
7 Y8 l6 B# F0 V! i+ I5 ^ - require './1.php';
4 q" }$ N% u2 q1 V - ; V/ m; m$ o" _0 l, t, r
- class Person{
+ ]+ |5 a/ H6 c5 I" c' ?( X - function __construct(){% l) [) W0 j& U) u
- echo 'I am test!';! {% ^5 t1 w4 ~9 r i
- }& a3 J& u. m* |6 p
- }+ H8 U# K' S' g: t' p4 w. u0 |
8 d+ s# `, A1 f( H6 e- new \one\Person(); //输出 I am one!;0 W6 a4 x6 t A8 e
- new Person(); //这里结果会是什么,自己猜猜看
复制代码
) ^, m& H( j! {% T: z% _! q t3 r最后,这个例子刷新了我对require的认识了。 按照我以前对require的理解:PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部分。所以我常常就简单的理解为替换,只不过把抽离出来的代码再放回原处而已。然后我试了将1.php文件内容放到name.php里: - //name.php0 ?" a2 H$ E" b) ^/ L+ K) {0 A
- namespace test;
) _, J3 p0 q! D {# | - namespace one;2 z* d Y% E) X. o! S2 R
- class Person{3 W; }0 M- m1 N5 ^; T
- function __construct(){, U- c' G8 W% ~; T
- echo 'I am one!';1 {! l& G, P; L% c7 l3 X. v
- }
7 X& L ~, N% A E5 P' A W. _ - }
' `9 _1 U0 p, h, [9 c
n. `4 F5 D7 m' \- class Person{
5 r3 }$ f Y9 h; ?2 ]0 ? - function __construct(){0 w) Z" C2 f2 z6 \2 z
- echo 'I am test!';
0 d' P2 S% ?: C* a - }! \% T. c3 I# d. |1 f( t
- }
复制代码
3 N3 A$ |- ^" J* ^+ Q$ S无需new类,该文件就会报错: - Fatal error: Cannot redeclare class one\Person
复制代码
$ I# t J( U: _" U7 L' S看来简单的把require理解为替换,在这里行不通。
: i6 e' X1 J6 j. P8 _6.namespace里不包含类名称,即使存在与类名称同名的部分,那也不代表类。new类时,还是得将这部分带上。
* U) K4 X) Q. U! i: i- //name.php
- }! \6 b! L& x# T+ J6 o( p/ z! E1 J0 p
/ q ~" B2 Z! i- namespace test\person;! j7 \& S* E0 i0 I
- $ p# ~) \$ D8 X5 x. }* @
- class Person{& `6 @! K( h% R
- function __construct(){
* y8 ^: J. f$ Z9 Q* V2 @ - echo 'I am test!';% P0 b. z' |- o0 ~( C, G
- }" }% B N3 l1 @
- }
/ t- A, d7 |: w* a& c* X/ l - new \test\person\Person(); //命名空间里person无法代表类名
复制代码
; n; n1 D& @3 p% n: o2 P4 [不过这样纯粹是画蛇添足,直接干脆点,namespace里不要带类名称就好。
6 Q- G$ g& Z8 N2 {7.一个php文件中可以存在多个命名空间,第一个命名空间前不能有任何代码。只说第一个命名空间前不能有任何代码,之后的命名空间之前可以有代码。这个自行测试即可。 - //name.php
# c) X7 ` s8 s# S% z8 z - ; h1 T: a4 m7 b9 l- ]3 P7 `
- namespace test;# X! k2 q% L( R- L3 O0 f0 ?- Q
- echo 'zhai14';
# w7 c1 O) T/ Y - namespace zhai;" B9 p K c- t
- require './1.php';
复制代码 # I2 r+ F6 P1 f# s
php命名空间namespace告一段落了,接下来说说use的用途。 使用use的目的:在命名空间字符串过长时,使用use可以相应的缩短命名空间。 4 H& \ N7 k! B
use的使用方法:1.new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。
' ]- \$ h) z& c( A; V- //name.php. U# \+ |, B, D& B! K- ~. N
- 8 z4 L; }( t; J1 X
- namespace animal\dog;1 J& {8 N& Y7 ^: c
$ r$ M, ]" B) H8 k$ [: h- class Life{
) c' f, ?5 y1 B - function __construct(){
9 B1 D# A: K- y6 |* P - echo 'dog life!';4 l3 e1 Y- I7 l+ T$ _+ p
- } Q2 m$ C' U4 r6 u
- }
5 S B+ f+ m1 g0 S
. T; C! f5 C. B) g, ?& B6 _) J3 ]- namespace animal\cat;
$ L4 E* v* P* Q1 u$ ] - ) ^- d- D# U+ M$ u" W. b, J& t
- class Life{3 A$ A' |6 O: Q/ j. l, u; q' i
- function __construct(){3 x' C3 ]/ {0 Y- I) ^; L5 |" t
- echo 'cat life!';
. s1 h: A/ a/ j; M; Q) i - }
& q- I- @. O- f% D# @6 c - }
$ Y+ ?- P- o0 C$ b( @
; z' C( ?* P6 R7 m& C- new Life(); //按照代码执行顺序,这里默认animal\cat这个命名空间, v$ ~( a: _# e: @/ b; C" `
- new \animal\dog\Life(); //A% N! U$ S/ b) c5 Z, ?+ ^
# S! F8 I3 H( p g8 u8 T- use animal\dog; //a
6 N3 T* b$ g1 p( s1 e8 s: n - new dog\Life(); //B
& F) s6 W- H! {2 k i& u - + I5 O# g+ i! V, V! M) C2 W
- use animal\dog as d; //b- G( m6 Z) ?+ d
- new d\Life();
复制代码
% q' A4 L' h2 `" w" b' W4 d; S0 ^1 l通过A、B行代码比较,需要注意: 使用use后,new类时,最前面没有反斜杠。 没使用use时,命名空间最前面有反斜杠
' f( O$ b6 Z4 d; }! M; L. e通过a、b行代码比较,可以理解: use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的: ' [, X2 T$ r. X$ I' [! ?
相当于 , K: N2 g$ r/ N# _) H H" O
2.namespace后面不建议加类名,但use后可以。8 V! j3 G% ~7 W$ w
- //name.php
9 B+ {; S' a' u ]; ?4 W
_, n' P1 B. `' I- namespace animal\dog;+ C/ |0 G: Y, s% U1 v
- * f! G/ Q. ^' m; ?; ^5 M1 t, q
- class Life{
2 h, K! _( o$ [ ~ - function __construct(){
8 q, o9 O; t# p. ]$ v- m5 q) q - echo 'dog life!';
& L' I: V! w# w! j: m0 L - }
! h! t& R1 S k - }$ k; ~8 Z3 \4 L" \# z- |( {" f0 ~/ x
- ( r) n6 M% u" F/ [
- namespace animal\cat;
4 Q( c d/ T9 p$ k) W8 p: b4 z
5 O/ P! S1 [, ~' `- class Life{
& P8 S _1 O1 w2 _7 i - function __construct(){) ]7 }; r2 g" Z$ F; `
- echo 'cat life!';
: @0 T2 @" Y$ y% ]* ~, Q - }
0 {1 ^- d! ^6 f$ m0 f' T - }) l c1 a3 i7 s5 q
- 8 i; r; Z8 ~& F
- use animal\dog\Life as dog;
# H! ]% Z+ W; v" J- [3 u - new dog();
复制代码 6 e# L" B: l2 \" g2 S8 s
如上所示,use后加上类名后,就相当于把类改了个名称:由Life改为dog了。 上面不用as dog就会报错: - Fatal error: Cannot use animal\dog\Life as Life because the name is already in use
复制代码 ( Q& c3 n9 R1 f! ~6 O5 B) s2 I
因为cat下也有个一样名称的Life类。 可以理解为,使用use后,这个昵称对应的类只能归当前命名空间占有,其它命名空间下不允许存在该类。 - //name.php0 s% I }5 g3 [; X
- , l4 @/ G& w! _* r
- namespace animal\dog;4 V! N4 Z) ]7 j( y F# h
- ) D' `3 k, H. O* ~- E5 S2 v. A9 e
- class Life{
! U: D4 K7 ~' _7 I/ k - function __construct(){ ~. K* ^4 ^1 U0 F3 s
- echo 'dog life!';
/ ]) A \8 H$ S0 ^ - }4 m# K) W" q! F. m
- }
. E4 H- a( f. v9 \* [4 R - class Dog{
+ r8 w1 Q1 d3 f O- n( `2 c+ q - function __construct(){
$ Q. g) q1 q [5 B" a+ S2 R2 d - echo 'dog in dog!';4 _' B2 K4 R# d9 S+ p" S. x1 y/ `
- }
0 ?1 A: \1 p, b3 N0 F - }
0 [: Y% d9 @( {: F M$ |+ u - 6 ]& o2 L4 M+ s" K( _/ [8 l
- namespace animal\cat;0 H5 @! Y6 e- E/ H
- 5 I# G6 u' \% l5 s* X4 l" A
- // class Dog{! G- g% |3 t& c2 b; s H
- // function __construct(){9 Q2 W1 r' B/ e' i' j
- // echo 'dog in cat!';
- o* d6 J* N( H" F- [) z9 l - // }
/ w5 ?9 X% ] Z - // }
- g. Z+ s9 ^2 K+ [0 P, h7 k - class Life{5 i3 o/ Z% w8 H( Z
- function __construct(){) f- [* m8 Y" l1 M: E' a4 X1 m" Z# n
- echo 'cat life!';
3 U0 Y+ i/ B: H" s" q/ ^% } - }
% u3 x2 ~ q. j, v( W* L& R' g - }
. ]9 G" m8 C2 V+ l# w
8 J& L+ E! {% v! t- O- use animal\dog;
& h( ?, \7 ?! Z& B H, u' N2 }# `! s/ \ - new dog\Dog();
复制代码
! c4 K# P) E4 P- Q- K. I" p如上,使用了
7 m4 {" S- M1 N) k tcat 通过上面代码,我想使用use的目的效果(缩短命名空间名称)就很明显了。
$ d# B7 H) }) S2 P; `简单总结一下: namespace就是划分领域的作用,代表这些东西是属于某个命名空间下的。 use就是起小名的作用,不论写起来还是说起来都可以省不少事儿。
( D( w+ K3 {0 p1 r
7 q' G9 l8 _$ t7 w0 k
6 U& ]! Y+ S+ n: z- L
( F, R4 |! i( {: z9 @9 d' Q# O7 K0 E5 o, B) w
|