|
以下皆为本人自我理解内容,如有失误之处,请多多包涵。
- A, j% y" O/ n+ Z; A文章大纲: 使用namespace的目的 namespace的使用方法 使用use的目的 use的使用方法 ' L* A9 o0 n2 w% m* H: }7 a
6 k' ^, k3 F! S% u2 u使用namespace的目的:团队合作项目时,避免与团队其它成员新建的类发生冲突;个人负责项目时,避免前后新建的类发生冲突;
4 _3 m2 }. z* G* w, E2 u+ ^- q据个人理解,用到所需要的类时,需要先require或include引入,所以会发生类重定义的错误的前提是:两个相同命名的类都有被引入。目前有些php框架会自动加载(即include)所有新建的model类,所以为了避免你新建的model类和项目框架原生的核心类发生重名冲突,采用了namespace。(想了想,与团队成员新建的类产生冲突应该通过沟通避免,即使事发后也应该重新调整类名即时维护,避免后期造成因为对类的理解混淆而带来维护上的复杂度提高)
6 k& b' @% X6 ?1 ?% o) u/ J结合使用方法来进一步理解它的使用目的吧。
9 |9 u6 m$ I+ z# \: g
7 f) ] ?( ]5 k( L5 @namespace的使用方法:为了进行测试,我将创建3个文件:1.php和name.php(此文件用来执行测试),后面将不再说明,请自行注意代码的变化。 1.namespace后命名的定义不区分大小写- namespace one;
0 q- P% B a+ o; ^ - namespace One;
! p6 u8 \ a8 ]& Q/ Y! B( g4 Q/ I - namespace ONE;
复制代码
3 d, E2 O6 H5 d7 j2 M* v如上写法都可以,选择一种作为自己的规范即可。(后面代码我采用第一种进行测试哈)
. K, a' M( |. N$ |7 N4 d* y& s2. 没有定义命名空间,就理解为使用顶级命名空间。new类时,可以在类前加上反斜杠\,也可以不加。- //1.php % |9 X2 B" V: J9 R) N" T4 E+ m
- class Person{
t$ y. k* R6 D+ _ - function __construct(){# M, @) n+ {: s& y& z" W- Q
- echo 'I am one!';, }# K( v9 V; G8 u: u
- }7 @) ~2 H6 u: p4 u+ q
- }
复制代码- //name.php
# }+ z1 ^! m5 T9 W; h% f) Y! ` - require_once './1.php';& m6 ?# F& K- X- v0 g4 Z [/ i
- % I) a/ Z- w; ?3 J9 J$ o. k
- new Person(); //输出 I am one!;
, y0 j5 ]0 G6 J2 { - new \Person(); //输出 I am one!;
复制代码
+ y" ?% z( ^5 U8 ^% y$ w3. new类时,带上命名空间时,之间一定用反斜杠字符,而不是顺斜杠。记忆方法:按找%中斜杠的顺序理解为顺斜杠。(有时说反斜杠,自己都不知道是哪种方向,以前按自左向右上升方向这种方向记忆,现在感觉这个太不靠谱了)
- //name.php
5 f y' ~- O- X! y - require_once './1.php';5 b1 B: H7 |' H8 u% e
- new /Person(); // 代码报错:Parse error: syntax error, unexpected '/'
复制代码
5 g7 Z: `; i) w0 h4.类在指定命名空间下, new类时,一定要带上指定的命名空间。没有带上指定的命名空间,按照第2点,php就会从顶级命名空间里找这个类。切记:这里不能按照顶级命名空间包含一切其它的命名空间来理解。而应该将顶级命名空间完完全全与其他命名空间区分开。 - //1.php ' r/ O! M3 e7 i2 \4 c3 f7 I
- namespace one;' j2 a% N" b. v: c
- class Person{2 K' C( b; H% P+ A; J0 R+ ?% {
- function __construct(){
: e4 Y. _& P9 m: ]' c1 q1 k4 P* X4 d/ J - echo 'I am one!';/ d- _, u. s+ J- g3 S: J
- }1 D0 d+ M# L) p( I9 a- k
- }
复制代码- //name.php( q- O4 u; X# V# c# @
- require_once './1.php';
2 g2 E* k: r0 M0 e# \) O3 z; l - new \one\Person(); //输出 I am one!;
9 X% a+ m% a/ h; j7 f& S - new \Person(); //代码报错:Fatal error: Class 'Person' not found
复制代码
c: f+ V) e* e7 N( J7 `) D# t可以举个这个通俗例子来理解:带上指定命名空间代表某人的苹果(在他手里),顶级命名空间代表苹果箱里的苹果(在箱子里)。现在要找某人的苹果,就将某人的命名空间带上,否则就会从箱子里找某人的苹果,结果当然是找不到。 7 O; N( I4 J8 R1 V& A6 p8 {
5.命名空间声明后的代码便属于这个命名空间,即使有include或require也不影响(重点是对后半句的理解,具体看代码)。
" L0 z5 s( A$ f. B9 s- //1.php
1 ~+ G, | I" q1 I - namespace one;
- J U ~( w8 ~" f2 n0 Q! C - class Person{
: s: Y8 U# e; @ - function __construct(){
9 q/ n; l8 m' B8 Q0 d1 g+ O - echo 'I am one!';
- m6 A3 S4 T' U) Y; K4 W - }
$ g; W& }6 z+ K1 s5 y- }% a - }
复制代码- //name.php* \, L$ E! U- d; M& Y5 F
- namespace test;
$ |: a& P# w9 E! ? - require './1.php';
/ y2 K, Y5 ^6 {7 ]3 ^6 }2 t - new \one\Person(); //输出 I am one!;
n, d# P! \8 _" D/ C - new Person(); //这里结果会是什么呢,猜猜看
/ c F- B9 `) Q" ?8 \1 | h0 E1 Z - 最后一行结果报错:
# K- o9 C+ T0 l- B \0 M& c2 J - Fatal error: Class 'test\Person' not found
复制代码 ' M. _. P, `, m( t8 i
) Z! V' a5 M) R' H. W6 W首先,这里与第2点比较一下:
第2点,我说,没有命名空间时,new类时,有没有反斜杠意义一样。 在这里,有了命名空间,有和没有反斜杠的意义就不一样了。 最后一行换成 v+ l1 t4 t/ a8 A6 F2 R& R2 Z" p6 j
结果报错: - Fatal error: Class 'Person' not found
复制代码 1 Q/ {: _) u( x2 `8 K
接着,就说说当前这点。 我们可以发现,最后一行代码对应的命名空间为test,并没有受到require文件里的命名空间的影响。 进一步加强验证,我修改了name.php文件如下: - //name.php% K3 [" X2 p/ [# D
- namespace test;
" Q& ?& C" y% r' L' B% X - require './1.php'; & L' E8 ^& V m' `, S" t1 b
- 2 I% t6 m5 Y) Q* u
- class Person{% n2 D( M+ \: t8 m: T: m7 @8 ]6 B
- function __construct(){# x+ h+ M0 o& V2 Z& e) S
- echo 'I am test!';
* @ J! S2 _; X8 \& p- N7 T& H4 C - }
8 s+ [. H9 P* d4 o, C! o7 U5 D - }# P! A& a9 z( C
- e; M0 p! B! k- new \one\Person(); //输出 I am one!;
3 q: A0 N6 `2 k$ M0 ~ - new Person(); //这里结果会是什么,自己猜猜看
复制代码
: V2 e$ E1 C6 V$ D最后,这个例子刷新了我对require的认识了。 按照我以前对require的理解:PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部分。所以我常常就简单的理解为替换,只不过把抽离出来的代码再放回原处而已。然后我试了将1.php文件内容放到name.php里: - //name.php
, q5 A% e* C1 b& A - namespace test;
, t7 T/ G! D4 k! D S& L - namespace one;
/ S; t8 b6 ?; z! s0 i' c4 d. I - class Person{
; b9 ~6 w! I- s: t! T - function __construct(){
) e3 } ^* s+ m F9 j - echo 'I am one!';2 U* W9 r6 B S6 ]. t8 x% S
- }
7 J! @1 S* {1 u# N- k4 V - }5 y0 D# Q, ]9 e5 i- y3 E: Y% n: p
- 9 J% w7 g, {( l& H, g
- class Person{6 A6 A, q l- D5 s/ |; f: b3 X1 s
- function __construct(){
( ]. Q, `% Z' |: a" }8 g i - echo 'I am test!';
$ O I% ^$ m z) g8 ^0 A. S+ q - }
7 t$ |# e+ n8 }$ `' {: F - }
复制代码 : p/ e, s. y5 `" |! H6 l
无需new类,该文件就会报错: - Fatal error: Cannot redeclare class one\Person
复制代码
3 n: B3 R& M+ y5 }% q" C看来简单的把require理解为替换,在这里行不通。
1 ^1 V4 _; s+ @" J H6.namespace里不包含类名称,即使存在与类名称同名的部分,那也不代表类。new类时,还是得将这部分带上。
+ b( D9 F4 i3 k4 |( _1 |- //name.php
# ]% Z( x# W8 _$ m5 \ - 5 a0 B( v) {1 r' C: o. W: \
- namespace test\person;
x8 E% c* T5 g$ F' E5 y$ u e# P
1 e7 h7 A* f z3 d2 Z# J- class Person{( ~8 f8 Z7 Q5 ^
- function __construct(){
% _4 l4 n6 P( y9 ?- s9 L5 o8 x w% v - echo 'I am test!';' D1 W& g$ B0 Q* u2 R8 R& i
- }
: g9 O+ }! M5 k5 r1 i/ @7 v$ n E9 t+ |' Y - }
( J. ?+ X3 r# A' e - new \test\person\Person(); //命名空间里person无法代表类名
复制代码 4 y% }! a. E6 M5 l$ {& |, W
不过这样纯粹是画蛇添足,直接干脆点,namespace里不要带类名称就好。 5 N/ c/ Z0 e2 \6 _( {6 j
7.一个php文件中可以存在多个命名空间,第一个命名空间前不能有任何代码。只说第一个命名空间前不能有任何代码,之后的命名空间之前可以有代码。这个自行测试即可。 - //name.php3 Z& R" L+ h- F4 v7 @0 P- s
- 3 j, K( v% j1 Q& F0 g3 r
- namespace test;
, o' n6 o3 D& ?* l( x - echo 'zhai14';) M% P' |" x+ U5 ~) o4 _2 Q
- namespace zhai;" \( a1 f: k" y* C8 L
- require './1.php';
复制代码 : M* e, U9 \( q* {
php命名空间namespace告一段落了,接下来说说use的用途。 使用use的目的:在命名空间字符串过长时,使用use可以相应的缩短命名空间。
2 w$ Z: F* [- `- iuse的使用方法:1.new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。
3 I, c; `4 ]! I0 A' |- //name.php3 i& {, A: z! U* v/ l
4 U# }( l+ m5 h7 w- namespace animal\dog;1 L# a; e- x# E1 G( g [$ W/ [
) o7 W* L; v h9 j) |; @- class Life{: o R* G4 ?- K
- function __construct(){
* b1 |! J% J+ k3 d7 Y3 H2 y - echo 'dog life!';
- I7 O4 t- N. f7 g! U3 \/ L - }
+ b1 n3 G7 i" Y" ?( c - }2 |! O9 X9 V* Z D
- 9 H8 }9 t, Z2 c8 h# P9 k2 q
- namespace animal\cat;% T0 q: ]3 T x% N: `9 j6 q
5 x- `% L7 b Q5 A# h- class Life{1 T/ H% P8 |& o/ C
- function __construct(){
( d, ?) b0 ~) U5 R& x - echo 'cat life!';
8 n9 {1 ^3 a! B2 Q( h0 o/ e+ |) g - }
7 F8 I0 v, I1 s& i7 b+ x2 q- f - }9 V ~0 n/ I1 Q) T
3 O- I* N3 X; \" k% z! c; ?! G- new Life(); //按照代码执行顺序,这里默认animal\cat这个命名空间; T }6 t+ Y a
- new \animal\dog\Life(); //A/ a8 e" o1 B; `% z# C2 }$ u/ `: F9 ~
- $ `$ N1 K# a& N$ Q
- use animal\dog; //a8 f' L" e/ c. o4 w- u+ S: N
- new dog\Life(); //B( K0 l( q. o. l/ i$ N
1 i- u3 ^* k6 U: H3 Z+ h0 C: j* r* E, _$ R- use animal\dog as d; //b
1 a# l: K- p8 e8 M - new d\Life();
复制代码 # f2 h) o% H' z' p9 D
通过A、B行代码比较,需要注意: 使用use后,new类时,最前面没有反斜杠。 没使用use时,命名空间最前面有反斜杠 h' T- g, U$ M9 }) L4 o
通过a、b行代码比较,可以理解: use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的:
5 A0 z3 M) J6 F相当于 - Y3 t' L. t' n. J5 ^$ ~$ G" L/ }
2.namespace后面不建议加类名,但use后可以。
3 M" O& T6 X9 G: R- //name.php
0 j+ z* Y S! f& A" ? _
) O/ F( E1 [8 K9 S- namespace animal\dog;
3 H A) |7 z! U7 f, J - : ?2 `1 U r; |- w4 [3 l
- class Life{
5 y+ e3 G6 ^. P/ }+ b3 B u4 F - function __construct(){
) B0 D4 O. ~. k* i& H& d - echo 'dog life!';
* m7 r1 ]$ f; l6 v5 k6 o% @ - }
& a( {( e5 {0 m1 L1 r# u - }
, s5 x) ]4 ?3 t& V1 M6 s9 g - 9 H4 z0 ~8 t6 f5 d; ^
- namespace animal\cat;$ a/ K( O4 O" t5 U2 U
- / g4 ]" @5 I, t3 o4 y& y3 j; ?
- class Life{
) c6 @( u u3 h/ n0 N& Z. b$ P$ J8 L - function __construct(){
4 W4 S0 G! W: S/ @. j! D4 a9 U - echo 'cat life!';! p# q8 B% \( C4 M, u6 t$ k
- }$ |4 X. E) b4 d k$ U! P# r) ^
- }* t) K8 V' M' B2 j A0 k
$ J/ ^/ L. q- G5 B2 s- use animal\dog\Life as dog; ( E- {3 G; {' M1 z
- new dog();
复制代码 6 w6 {9 C! _# X
如上所示,use后加上类名后,就相当于把类改了个名称:由Life改为dog了。 上面不用as dog就会报错: - Fatal error: Cannot use animal\dog\Life as Life because the name is already in use
复制代码 & T0 F$ r0 o" @9 K: G
因为cat下也有个一样名称的Life类。 可以理解为,使用use后,这个昵称对应的类只能归当前命名空间占有,其它命名空间下不允许存在该类。 - //name.php
/ D9 \0 ]8 ]3 B& S6 U9 {1 |
8 G( Q+ s5 N& I4 d) A# Q. j0 @- namespace animal\dog;9 b8 m& k$ h j8 H- T# O; n
- ! A- z. l$ K2 Q1 v( ~
- class Life{
0 M$ k# E. K" S D. C8 I+ [ - function __construct(){$ d/ \& e1 c' m' D. f
- echo 'dog life!';% H' z" N2 y- x& N
- }
3 S% x4 C6 \! G, {4 Q - }
3 ~0 S$ B( A2 v - class Dog{5 ?8 R; T& l* H5 B% ^) }! ~
- function __construct(){4 @' o) f n4 k* j
- echo 'dog in dog!'; z( g; D/ w; s) @- l3 O3 l
- }
: F( b2 P9 n J, V1 u2 M - }
% J) y, W' s" s0 [: ~8 C- g
! Z K$ M# q0 p1 \+ \7 T- namespace animal\cat;3 D3 U$ W% L( J* p) ?3 `
- r I1 Q- h3 E" L0 q7 `8 ?8 T- // class Dog{$ H2 o. w" K; G T- w
- // function __construct(){
, l5 J' p0 K* ?8 S - // echo 'dog in cat!';
" B0 r7 i) W1 G - // }
" }% u! G7 S( i) l% v% D/ g - // }
: a0 `/ g# v0 a, U- [ - class Life{
' D6 Z4 A/ _5 {! O! G - function __construct(){
+ }% h3 I7 E& O: `0 j - echo 'cat life!';
\! V+ B, ]0 A - }) `" T7 a- f, s
- }1 s1 G$ b2 m# b8 O- j* m4 _
/ ] ]7 n; X+ {- use animal\dog;
$ U: u+ h, l# ?# a$ f: y" ] - new dog\Dog();
复制代码
; z: Z6 c( d. [7 O5 Q( ]' o b如上,使用了 , ~8 B8 t3 O p8 J4 P+ C; K D9 h2 Q
cat 通过上面代码,我想使用use的目的效果(缩短命名空间名称)就很明显了。
: w: f' ^' z8 @. X. _( t, V简单总结一下: namespace就是划分领域的作用,代表这些东西是属于某个命名空间下的。 use就是起小名的作用,不论写起来还是说起来都可以省不少事儿。 4 v7 o/ y5 g6 m+ [+ m) c
- E. a/ U6 L# ]- |2 b' B4 _. q
+ U2 ]# k! r: t
Y/ P8 d& K/ O: L |