|
以下皆为本人自我理解内容,如有失误之处,请多多包涵。
' t8 K6 R) H( `文章大纲: 使用namespace的目的 namespace的使用方法 使用use的目的 use的使用方法
) X0 Y3 ^" g1 g2 l# M4 J2 G5 Q5 r% d
使用namespace的目的:团队合作项目时,避免与团队其它成员新建的类发生冲突;个人负责项目时,避免前后新建的类发生冲突;
, u+ D" V* ]# f$ u5 I据个人理解,用到所需要的类时,需要先require或include引入,所以会发生类重定义的错误的前提是:两个相同命名的类都有被引入。目前有些php框架会自动加载(即include)所有新建的model类,所以为了避免你新建的model类和项目框架原生的核心类发生重名冲突,采用了namespace。(想了想,与团队成员新建的类产生冲突应该通过沟通避免,即使事发后也应该重新调整类名即时维护,避免后期造成因为对类的理解混淆而带来维护上的复杂度提高) + w9 {8 [8 Z7 A" G0 P1 V
结合使用方法来进一步理解它的使用目的吧。 3 u }8 e8 A5 T( A! Z5 P1 @) z- u: r
: f( U. R" H6 r5 ~4 Y" F! Onamespace的使用方法:为了进行测试,我将创建3个文件:1.php和name.php(此文件用来执行测试),后面将不再说明,请自行注意代码的变化。 1.namespace后命名的定义不区分大小写- namespace one;
3 `* e3 b! K1 t& t. I$ V - namespace One;1 W0 S" D- K7 W( ?0 y2 N& p
- namespace ONE;
复制代码
1 c8 D/ @( H* v3 b如上写法都可以,选择一种作为自己的规范即可。(后面代码我采用第一种进行测试哈)
% G# _' W' G( i% K4 Z* ]0 v9 y# {2. 没有定义命名空间,就理解为使用顶级命名空间。new类时,可以在类前加上反斜杠\,也可以不加。- //1.php
+ D& X: D2 f& t - class Person{
" O0 x2 |# X2 k* Q! D - function __construct(){' |+ J& t& ^2 n) m x$ a$ `& B' ^
- echo 'I am one!';
+ |2 x) }2 y& R" |" {; u1 s: }" N - }
$ \% {7 t" S9 t" t - }
复制代码- //name.php0 c" C2 E% e7 U3 c6 D
- require_once './1.php';) D- P8 X8 L% b7 i0 J6 z
: l2 l6 i" r0 {$ J( l( V; W- new Person(); //输出 I am one!;, v+ R1 s: L% d# Z7 ?3 w& y
- new \Person(); //输出 I am one!;
复制代码
$ O. |3 ~. S, c5 Z" C1 q% o3. new类时,带上命名空间时,之间一定用反斜杠字符,而不是顺斜杠。记忆方法:按找%中斜杠的顺序理解为顺斜杠。(有时说反斜杠,自己都不知道是哪种方向,以前按自左向右上升方向这种方向记忆,现在感觉这个太不靠谱了)
- //name.php+ g* S+ P5 R! P4 h) p" E v# s2 J7 u
- require_once './1.php';
n1 y* R" y+ l/ m; V - new /Person(); // 代码报错:Parse error: syntax error, unexpected '/'
复制代码 $ ^+ m* R/ D0 y+ m8 j7 p# Y& I! h
4.类在指定命名空间下, new类时,一定要带上指定的命名空间。没有带上指定的命名空间,按照第2点,php就会从顶级命名空间里找这个类。切记:这里不能按照顶级命名空间包含一切其它的命名空间来理解。而应该将顶级命名空间完完全全与其他命名空间区分开。 - //1.php # p% ^2 u) e9 G5 S V: l% U5 }
- namespace one;
% j* E: X/ Q# p J% o - class Person{
9 T) s; ]) V& n1 G6 g7 {8 b - function __construct(){
: y, q* I5 x1 Z. e! r3 e - echo 'I am one!';+ y# ^2 z3 q+ Y% |/ a( t+ \
- }
$ E1 X3 @2 K) A, X6 }' w1 l - }
复制代码- //name.php
8 ?: }6 @8 y5 [) u, F - require_once './1.php';
( ]- G1 w! o# ~- P8 c% t - new \one\Person(); //输出 I am one!;! d! r! j4 E! Y- X& R
- new \Person(); //代码报错:Fatal error: Class 'Person' not found
复制代码
) F! z F: t1 \! q- K" |4 A1 ?可以举个这个通俗例子来理解:带上指定命名空间代表某人的苹果(在他手里),顶级命名空间代表苹果箱里的苹果(在箱子里)。现在要找某人的苹果,就将某人的命名空间带上,否则就会从箱子里找某人的苹果,结果当然是找不到。 8 L: i; M$ L6 h, p! Q
5.命名空间声明后的代码便属于这个命名空间,即使有include或require也不影响(重点是对后半句的理解,具体看代码)。
; e% |+ O, a+ Q' B. N0 E9 a- //1.php
- h6 t5 Y' n$ c& X - namespace one;
3 M) n/ B7 {9 t - class Person{
* [2 n0 x5 j! I. E - function __construct(){
% M; D& F/ s/ J! O5 C3 c) r+ ? - echo 'I am one!';( S5 e. S9 O( P" R- v; i# A9 f
- }! z5 U8 D8 _5 Q' c" @! G0 [
- }
复制代码- //name.php
4 ]7 ]8 n5 q2 O3 P9 O. s* [) Z; { - namespace test;
|# C$ T, n; I9 T- \ - require './1.php'; {$ I: _$ ]2 C% p; }1 p" D
- new \one\Person(); //输出 I am one!;
* q& l5 d5 \- T$ `7 x. F+ n - new Person(); //这里结果会是什么呢,猜猜看( l7 W; f# q: Y, L
- 最后一行结果报错:
5 W5 l1 \' \/ H/ q$ u- R - Fatal error: Class 'test\Person' not found
复制代码 $ l* _$ Y+ B" u' n, C: k
5 j* P; A& v2 {
首先,这里与第2点比较一下: 第2点,我说,没有命名空间时,new类时,有没有反斜杠意义一样。 在这里,有了命名空间,有和没有反斜杠的意义就不一样了。 最后一行换成 7 G) B2 B; ]6 t' t+ z4 |' a
结果报错: - Fatal error: Class 'Person' not found
复制代码
) M/ W* Q/ {" t- R t) V接着,就说说当前这点。 我们可以发现,最后一行代码对应的命名空间为test,并没有受到require文件里的命名空间的影响。 进一步加强验证,我修改了name.php文件如下: - //name.php6 X9 y0 h( s) _2 a/ Y7 Y/ M( F
- namespace test;3 y9 p" r F& f
- require './1.php'; 3 g# N$ u/ K6 D1 Q
! |; W; ^* m, Z- class Person{1 w$ }( O& ]" q& A! v9 a
- function __construct(){
$ C7 K& t& d# P( d% J1 X* Z - echo 'I am test!';+ v: z, v) Q N9 g* I& C( x
- } o6 i% z% ~9 L% k+ k$ \
- }
8 A% U5 a6 r+ }5 [8 I/ i2 W - 8 j5 @" ?5 D8 V j0 [% Z. N
- new \one\Person(); //输出 I am one!;, G1 k- f& P4 e, o) l1 q' S
- new Person(); //这里结果会是什么,自己猜猜看
复制代码 * G% L, j L/ X4 r
最后,这个例子刷新了我对require的认识了。 按照我以前对require的理解:PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部分。所以我常常就简单的理解为替换,只不过把抽离出来的代码再放回原处而已。然后我试了将1.php文件内容放到name.php里: - //name.php3 {0 i2 r! v- _6 }" |1 a
- namespace test;% u% W2 F, R! ~9 L! o
- namespace one;
8 z( f8 j* _" h J( j! ~1 d. g' C - class Person{
! @. }5 [/ ~5 J3 @- N - function __construct(){
/ d2 M$ ~$ l' D, s: r8 } - echo 'I am one!';
4 e9 V! y; ^6 f$ i - }
; E$ ]+ B! Q; C - }4 }( c2 @4 R; i1 U+ u+ h
- # R' R$ I* j" }" C
- class Person{
s% D" W1 f6 B. o0 Y: p - function __construct(){: P! @) r4 ?( f0 T5 Q; D4 m9 R- z5 e9 p
- echo 'I am test!';
- n1 \# Y* D6 I& S) n u) y - }
8 C2 `9 F! f5 t - }
复制代码
/ ~. l6 ]# e/ m9 J无需new类,该文件就会报错: - Fatal error: Cannot redeclare class one\Person
复制代码 ) N* i7 q( y V- y0 p) H
看来简单的把require理解为替换,在这里行不通。
) m. L' q9 c2 [+ T. ^6.namespace里不包含类名称,即使存在与类名称同名的部分,那也不代表类。new类时,还是得将这部分带上。- O/ _+ Z: Y+ I* a
- //name.php) O% W/ J9 {8 s! j% N$ z& U( n
& t' l+ B3 v- c, ^+ t- l2 o- namespace test\person;
: G [# \4 }+ M( a. |
D( t' H) H) J/ \4 w6 t) ^- class Person{" e* f* n$ _5 N
- function __construct(){1 L4 `" r- n* B5 k x, G# z
- echo 'I am test!';
' p1 T* K2 o# f$ A7 X& B - }
/ K7 m+ H2 P/ k! X - }
8 N! Q' ]! v: k( k7 h - new \test\person\Person(); //命名空间里person无法代表类名
复制代码
. _+ r7 L7 t. K不过这样纯粹是画蛇添足,直接干脆点,namespace里不要带类名称就好。 3 O q( D4 ?; O/ a
7.一个php文件中可以存在多个命名空间,第一个命名空间前不能有任何代码。只说第一个命名空间前不能有任何代码,之后的命名空间之前可以有代码。这个自行测试即可。 - //name.php- [4 a2 @- k( j; f& Y: d7 r
- : A3 [# U+ {" t8 U( x8 S3 `
- namespace test;
; H8 J& x1 i! n* r" L - echo 'zhai14';: ^8 p- @0 p" t8 ~! K1 V7 ]
- namespace zhai;* F5 Y& v# k6 B- Y
- require './1.php';
复制代码
6 n U6 l2 t* zphp命名空间namespace告一段落了,接下来说说use的用途。 使用use的目的:在命名空间字符串过长时,使用use可以相应的缩短命名空间。 + x9 [2 r* \5 s% J- s1 \7 B) k
use的使用方法:1.new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。
& A9 ^4 h& }( V- W( t- //name.php
g3 j* f0 ?5 g
1 i+ I# K. O3 ~/ U0 ^$ g- m- namespace animal\dog;
! N) F4 U8 `: s3 Z/ p8 U$ T - # S: J9 c c" G8 }' N
- class Life{3 S7 V& R" E2 Y3 h7 E' @
- function __construct(){1 Z" i. u9 z% T3 d# O* ?" T( [
- echo 'dog life!';
5 a8 M* d/ ~5 M q) z7 Y0 G - }. K, o m [, k1 M" p
- }
' n6 h2 g9 K$ _% p# C$ U% w
- F$ |" r+ n/ g% I' m, ?- namespace animal\cat;
% D; X+ }$ R, z/ U
) K4 g8 L8 m0 e1 W1 p1 e) V3 N+ w- class Life{: Y9 b# Y+ w2 s* M
- function __construct(){; V0 U0 I, d$ u j3 i
- echo 'cat life!';7 v) a8 l2 k" G( |2 c9 Y
- }
2 r* r/ W, x! p2 s+ a* e - }( }" m+ C2 T) ~! u( y
- ! u% R4 m, C, N. H [2 _! O
- new Life(); //按照代码执行顺序,这里默认animal\cat这个命名空间/ N5 y* j3 B0 y5 _1 Q
- new \animal\dog\Life(); //A& m6 E5 w9 y9 J
- 1 e( {: K* b- P* H: J5 }* e3 R( l6 ^
- use animal\dog; //a3 O' P* ^+ T' V7 @! j* ]# E
- new dog\Life(); //B
4 P/ A- `/ Z' D4 K3 {$ w# C
& x: |7 e' z4 b# {2 I: K- use animal\dog as d; //b5 s$ k* J5 L L) @4 l) G# Y6 `: D0 L
- new d\Life();
复制代码 5 [( D p+ n5 O3 P" y6 R
通过A、B行代码比较,需要注意: 使用use后,new类时,最前面没有反斜杠。 没使用use时,命名空间最前面有反斜杠
2 Z' W8 L; K5 C- n2 v通过a、b行代码比较,可以理解: use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的: ( P! U* N+ W5 ]1 R. ^0 N
相当于 . I4 a2 r" K) }) P/ p
2.namespace后面不建议加类名,但use后可以。
% G' {' |* e0 Y( g: h) s$ i- //name.php
) v8 g& t' E& i; D - ( A, }+ O( r r2 J4 R. y
- namespace animal\dog;) k; P! u& P! _ t4 X" ^" p
- . F* Y, m1 u4 ?. W* s$ m, [) A# t0 L
- class Life{
3 }* ~) P8 o- \* K - function __construct(){
- \. k$ n- j9 B7 o' [) R0 e X - echo 'dog life!';; d( `! y2 T- Y X* G8 K/ |
- }
7 c& j0 Q* n& C, X; ?, m* I - }
( w& ]( w6 ]: q - # ~0 |, }6 S$ e0 s4 v6 V( }
- namespace animal\cat;
$ ]0 _8 I4 U' a l1 e$ `( S
" Y" X2 ~8 Y y+ T/ ~- class Life{
6 \5 t4 x4 D e9 n* {/ f - function __construct(){
( I4 Y8 v; Z' C4 p% a/ N - echo 'cat life!';
& _% E5 t) @% [% {! N; V - }6 M' {, p$ f% G/ \ H4 H, ?6 B( M
- }
1 f7 O5 G* V1 x) q r/ N" m# g: v - 2 e* L% C4 V3 d; v# ^+ b: `# Q/ Z" J9 ]
- use animal\dog\Life as dog;
5 q, d" f2 ^$ J U- \1 j' G9 F - new dog();
复制代码 # A4 n2 p* N5 C
如上所示,use后加上类名后,就相当于把类改了个名称:由Life改为dog了。 上面不用as dog就会报错: - Fatal error: Cannot use animal\dog\Life as Life because the name is already in use
复制代码 7 L2 j; |5 V7 ~! q
因为cat下也有个一样名称的Life类。 可以理解为,使用use后,这个昵称对应的类只能归当前命名空间占有,其它命名空间下不允许存在该类。 - //name.php
6 q1 @ q4 n3 }% P, L
+ p" A# Z( ]- i* ~1 B- namespace animal\dog;
/ O A/ u$ S n) k; \! t' ? - $ v" S3 _# _0 q+ u) G* S/ f4 ?
- class Life{
# A! z& B5 z, W+ V7 I4 \ - function __construct(){
2 C+ ~9 M* t9 x2 ? M5 R( R+ g, G - echo 'dog life!';
4 Z" F o3 E l - }" S3 w8 r. {, H# M. a7 n! [9 `
- }. }9 C' D/ p( J7 Y
- class Dog{5 K; G6 k9 N- M+ L- V
- function __construct(){
6 v1 S% L' Y! s3 L - echo 'dog in dog!';
1 v+ Z% H; L# B4 } o - }
: V% U: f) D: Y, Z0 e0 N* h - }, n. t. X/ N5 ~; ^
- L8 V; U5 W0 W" D
- namespace animal\cat;
+ H0 S. B. K! i p* B6 a - ; L7 v- z3 \# J, q% R
- // class Dog{; `$ n& c8 @( b! S
- // function __construct(){
9 b4 M* l/ ]9 [. I) h - // echo 'dog in cat!';
3 b$ U+ m, k+ U$ X4 j m6 U - // }
9 U2 S- T- T7 c% g2 N: ?. n; f - // }' x6 w2 U9 {' Y' |
- class Life{
, Q) n9 _- e+ R2 Y B7 V - function __construct(){
8 t! P- T- B7 V5 H5 F, B - echo 'cat life!';
- l5 I" `8 M5 F3 p* @ - }; `0 e& |3 E5 P, w, g3 V
- }1 \* u1 I# T! m7 t0 A# F, s z
- $ Y% Y9 V! Y, C1 ?2 t
- use animal\dog;
; ? [/ n; Q. W* H v) o - new dog\Dog();
复制代码 9 F8 v1 }; p/ I+ t. E* ~- d
如上,使用了 Y$ H( i; b, g |8 f( k
cat 通过上面代码,我想使用use的目的效果(缩短命名空间名称)就很明显了。
+ @! W" R; Z) C+ f2 ?简单总结一下: namespace就是划分领域的作用,代表这些东西是属于某个命名空间下的。 use就是起小名的作用,不论写起来还是说起来都可以省不少事儿。
1 @4 w4 h/ @& [
- L; w$ S! G# F
q7 E' C- H# R. j C7 e3 n8 X
2 y# R0 h- j2 H5 g& _ z# c5 F P1 E
|