|
以下皆为本人自我理解内容,如有失误之处,请多多包涵。
4 B, U( c/ x* V+ |, ^5 h8 [$ Y文章大纲: 使用namespace的目的 namespace的使用方法 使用use的目的 use的使用方法
7 S2 E, E4 h* Y( b
. V. v9 W C7 I( G' p使用namespace的目的:团队合作项目时,避免与团队其它成员新建的类发生冲突;个人负责项目时,避免前后新建的类发生冲突;
% j% H a% v/ w+ w& K5 E据个人理解,用到所需要的类时,需要先require或include引入,所以会发生类重定义的错误的前提是:两个相同命名的类都有被引入。目前有些php框架会自动加载(即include)所有新建的model类,所以为了避免你新建的model类和项目框架原生的核心类发生重名冲突,采用了namespace。(想了想,与团队成员新建的类产生冲突应该通过沟通避免,即使事发后也应该重新调整类名即时维护,避免后期造成因为对类的理解混淆而带来维护上的复杂度提高)
- t' i. @& d5 S结合使用方法来进一步理解它的使用目的吧。 5 q. P1 D! ?& \0 `: U" c
" Q$ u% e# x, V$ U3 n" U( anamespace的使用方法:为了进行测试,我将创建3个文件:1.php和name.php(此文件用来执行测试),后面将不再说明,请自行注意代码的变化。 1.namespace后命名的定义不区分大小写- namespace one;
& `/ Y: {+ v5 I( x' A3 N- | - namespace One;
8 O! K" w, T, V! c" q" P1 K+ c: \4 E - namespace ONE;
复制代码
, o- ^2 V6 ~) J如上写法都可以,选择一种作为自己的规范即可。(后面代码我采用第一种进行测试哈) - u; |' M7 Y, S" x5 J3 K8 o* s$ V- T
2. 没有定义命名空间,就理解为使用顶级命名空间。new类时,可以在类前加上反斜杠\,也可以不加。- //1.php
# e7 y* q( v- { - class Person{1 s1 c- |- {; \0 u1 a. }
- function __construct(){; c \) I4 z i6 a: N& o
- echo 'I am one!';
0 ]9 J/ J' Z( }# } - }
N! e; y; E7 {- ~# P* v - }
复制代码- //name.php- @8 F! g7 o* M+ ~' `. x! y* p9 h
- require_once './1.php';
\& P% J/ |; ^+ B- ?0 G - 3 K8 W& G6 P2 O' N) s8 q( e! [' T
- new Person(); //输出 I am one!;
1 I3 v& E1 P" r' c( M - new \Person(); //输出 I am one!;
复制代码
" o5 Z) D v3 Q! p7 e' @3. new类时,带上命名空间时,之间一定用反斜杠字符,而不是顺斜杠。记忆方法:按找%中斜杠的顺序理解为顺斜杠。(有时说反斜杠,自己都不知道是哪种方向,以前按自左向右上升方向这种方向记忆,现在感觉这个太不靠谱了)
- //name.php& U: _ z0 t$ ^8 A: p
- require_once './1.php';
6 d0 O3 r( @& j - new /Person(); // 代码报错:Parse error: syntax error, unexpected '/'
复制代码 ( U0 f! E' U, B4 V% @
4.类在指定命名空间下, new类时,一定要带上指定的命名空间。没有带上指定的命名空间,按照第2点,php就会从顶级命名空间里找这个类。切记:这里不能按照顶级命名空间包含一切其它的命名空间来理解。而应该将顶级命名空间完完全全与其他命名空间区分开。 - //1.php
& A! p0 }1 _ { e; L0 h6 h- W# t - namespace one;/ s& n1 S) \7 N' g) f* c3 I
- class Person{
6 S5 A+ ?) M# Z; f - function __construct(){% O O+ [( V! ]4 r
- echo 'I am one!';
) P6 F' X1 @6 r3 J+ C, Y - }
; g! [; W. E# Q3 W - }
复制代码- //name.php- e! ~" s5 \0 h. M: Y5 g
- require_once './1.php';
1 c Q7 P; o* |% t+ d9 \ - new \one\Person(); //输出 I am one!;! M+ a' ] F* [$ o
- new \Person(); //代码报错:Fatal error: Class 'Person' not found
复制代码
4 F6 b1 z6 O7 q& p可以举个这个通俗例子来理解:带上指定命名空间代表某人的苹果(在他手里),顶级命名空间代表苹果箱里的苹果(在箱子里)。现在要找某人的苹果,就将某人的命名空间带上,否则就会从箱子里找某人的苹果,结果当然是找不到。 - K* z$ R' x- u# }$ }* F, F; I& _
5.命名空间声明后的代码便属于这个命名空间,即使有include或require也不影响(重点是对后半句的理解,具体看代码)。
' }+ f N2 d. h$ z# |: {/ s- //1.php
. `4 i5 x* b" P; K0 r4 ` - namespace one;( U' K0 F4 W! G
- class Person{% F3 x+ _) t, K3 A
- function __construct(){
3 t9 P( O8 z! T- q0 V' b - echo 'I am one!';
* ^! v$ y1 e8 Y9 M* } - }2 \7 L& A7 D# t1 h1 W/ R
- }
复制代码- //name.php* w1 J. m- X1 m' L( n# D
- namespace test;# ?2 W& Q+ S0 U0 p- e
- require './1.php'; / g+ v, m# X& s& i4 k! J3 @: l
- new \one\Person(); //输出 I am one!;
; B6 w# `: |) [9 z# L9 A4 e5 c - new Person(); //这里结果会是什么呢,猜猜看4 }8 R1 X. B9 d( J
- 最后一行结果报错:
6 Y3 t0 t) i- \* w* Z& ~ - Fatal error: Class 'test\Person' not found
复制代码
$ i% H" T8 j% p8 @9 a& S8 d7 z0 M. | v9 N+ h# G" V' q: e* E
首先,这里与第2点比较一下: 第2点,我说,没有命名空间时,new类时,有没有反斜杠意义一样。 在这里,有了命名空间,有和没有反斜杠的意义就不一样了。 最后一行换成
: r) o4 t! e+ Z. H# \2 u结果报错: - Fatal error: Class 'Person' not found
复制代码 % w* G4 K' G# y- G3 ^7 ]/ s
接着,就说说当前这点。 我们可以发现,最后一行代码对应的命名空间为test,并没有受到require文件里的命名空间的影响。 进一步加强验证,我修改了name.php文件如下: - //name.php5 r& a; T9 l; L% m1 D- b
- namespace test;
, o* h( D$ K7 }- a - require './1.php';
, _' R% J3 I) j
- V2 ^5 L8 W+ ^6 d- class Person{
! {) h K7 e/ p( v% R4 R* i - function __construct(){
: ?: X7 N+ l0 D4 B* @( S( G - echo 'I am test!';9 p# S$ X9 a+ m! _. ~
- }
8 y9 w5 \3 L) z9 u! }' P4 v/ F! E - }& j2 Y, O( g9 d' Y" H+ N. z
- 8 d1 z& d% |% Z3 W. x( Y0 Z1 G# {
- new \one\Person(); //输出 I am one!;1 }$ E2 Z5 f- E
- new Person(); //这里结果会是什么,自己猜猜看
复制代码
- A2 j+ C- m7 J: \5 a8 |最后,这个例子刷新了我对require的认识了。 按照我以前对require的理解:PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部分。所以我常常就简单的理解为替换,只不过把抽离出来的代码再放回原处而已。然后我试了将1.php文件内容放到name.php里: - //name.php
& c4 K* {) G3 w - namespace test;% _9 K x2 z4 _8 T
- namespace one;
' G; ^& u1 z% g) | - class Person{+ P* M* _) ^7 y' ^% x* X4 n
- function __construct(){$ A5 }: y+ |( V$ o) D( G& w1 ^
- echo 'I am one!';
: z! t0 E" q2 Z3 M - }
/ C% \3 p) b, S# w0 `, Y - }
- D9 ~" R: K- x4 D! I, r/ b
, Y1 g" K$ I" a+ p- class Person{
0 J' Y* A! O% i$ f& H - function __construct(){
| X* p0 S9 X" K9 I$ m. { - echo 'I am test!';0 \. b( q2 [. P" E8 T9 r T
- }% M7 t) o* w2 ~8 X
- }
复制代码 . [( m4 K4 h& i% S# \
无需new类,该文件就会报错: - Fatal error: Cannot redeclare class one\Person
复制代码
& a2 _6 \* ^, P8 [# N看来简单的把require理解为替换,在这里行不通。 & D7 B' ]6 s5 `7 M2 A% K
6.namespace里不包含类名称,即使存在与类名称同名的部分,那也不代表类。new类时,还是得将这部分带上。
0 w5 P2 q- ~) V# S- //name.php7 _+ o9 {% [7 B+ i& o' H
- $ }0 J, n$ ^1 ?' e$ U2 ?
- namespace test\person;6 G: g9 y, p, a5 p
8 `) A8 B9 y; {; T V% H$ {- class Person{- c5 w( \, F; c
- function __construct(){
1 c* a, T# z! [6 G9 A8 e- x - echo 'I am test!';3 b; a6 o- x& n- L- C2 { [, H4 ~
- }" P# V9 ?0 T2 _" o$ e( X
- }0 a% l& v' m1 g: o2 x# A' r
- new \test\person\Person(); //命名空间里person无法代表类名
复制代码
0 T9 s0 u0 d! x- z. i2 A- p# ~不过这样纯粹是画蛇添足,直接干脆点,namespace里不要带类名称就好。 0 u- F, q7 z& C( C1 Q2 r
7.一个php文件中可以存在多个命名空间,第一个命名空间前不能有任何代码。只说第一个命名空间前不能有任何代码,之后的命名空间之前可以有代码。这个自行测试即可。 - //name.php8 B0 k4 P+ L' O# c' i4 O, ]7 q
, u p5 P# s! }1 T- namespace test;. |+ d* S" a- [7 A& S
- echo 'zhai14';0 M" l+ k5 l# J3 v2 P' h, `7 O
- namespace zhai;. Q% L5 w7 N0 h* J7 i
- require './1.php';
复制代码 + v9 Y4 Z6 C* ^* t
php命名空间namespace告一段落了,接下来说说use的用途。 使用use的目的:在命名空间字符串过长时,使用use可以相应的缩短命名空间。 # t0 V+ ?5 h9 |! h+ j8 g
use的使用方法:1.new类时,最前面无需用反斜杠。此外,use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。1 P, t3 x! n) m; l% z: j! U
- //name.php
! h: ` H8 o) ~/ ?
7 k$ n: e& h7 p- namespace animal\dog;! o& `" q. O! m5 @3 n
1 S5 Z. L+ u' ]- class Life{
7 o- D9 W/ l6 \ - function __construct(){
9 {) D6 E( n3 [% n# _4 @% ^: [ - echo 'dog life!';
r, f4 X2 e q" _ - }
4 K; d1 S3 m0 h) ?% E: p+ u - }& S8 f# {1 v( e, s
- - D; i+ y8 M: f2 r- U) X
- namespace animal\cat;
% K' v- [, J4 ~" P1 L
1 ]) C) }. L' Y- class Life{9 h a- N. A6 J$ h
- function __construct(){
! `7 v1 `( @1 u - echo 'cat life!';
# C; L. s( g% h: j9 o% W - }
7 u& V, w7 r) }. z& a - }$ p+ f2 ~* |2 |& H* Q& L# [5 ^) X
- & E( K7 Z3 x1 H" s# ?
- new Life(); //按照代码执行顺序,这里默认animal\cat这个命名空间. @# y9 C! U% n- _
- new \animal\dog\Life(); //A* Q) z2 s! @$ P3 w
: ?! S, r7 x* @- use animal\dog; //a# K; p5 |# e8 ^, Z% M7 `2 {$ V
- new dog\Life(); //B
0 t* U/ J2 o+ r. c, Q( r2 D# R - - G) C1 y) G/ r) F0 e
- use animal\dog as d; //b, B( V) N4 i0 b
- new d\Life();
复制代码 0 j% x* z: d6 I& P- j3 @6 T1 Y
通过A、B行代码比较,需要注意: 使用use后,new类时,最前面没有反斜杠。 没使用use时,命名空间最前面有反斜杠 0 |. q% F4 M& w. y f ?
通过a、b行代码比较,可以理解: use后没有as时,缩短的命名空间默认为最后一个反斜杠后的内容。如上的:
6 k5 h% |& H$ Q2 c1 o/ u, P- @! g相当于 5 w/ j% \0 {! [2 |
2.namespace后面不建议加类名,但use后可以。
$ R% |+ v1 ~) y2 ?( ~/ m' D- //name.php9 L7 i% h& ~8 U! t5 M
3 k7 I# x& D2 N: B) z5 V: h. W2 S9 O- namespace animal\dog;
# |+ X! R% M5 I9 b; r/ X- L ^ - : D! i. N% |- O
- class Life{0 G, a: w% @6 Q2 u
- function __construct(){# o5 d$ R( K# l2 }$ `4 r, I
- echo 'dog life!';
. Y2 u# B. B9 r4 A) p: E - }
$ d9 v. i4 i$ s! U. z, X# N - }
1 q4 b. V# v; P
3 [# l/ w: M1 x$ ]$ |- namespace animal\cat;
0 w2 P$ k$ V' N7 Y. i' A - 9 F5 a/ y' D, Q! V/ s
- class Life{
2 e' P4 c K5 C0 C- P! ` - function __construct(){
. l4 Z: m- k3 }' S$ I& u% @- M - echo 'cat life!';- E$ B- L/ C+ e' y6 [. U
- }, R6 p- m! T. T* q z
- }
/ ?6 k) _ z/ k3 a3 Y - 8 z2 w, E/ F4 i( y+ W
- use animal\dog\Life as dog; # r+ A4 y V7 f% G/ M
- new dog();
复制代码
- k# E f m" s/ `) x1 H0 r如上所示,use后加上类名后,就相当于把类改了个名称:由Life改为dog了。 上面不用as dog就会报错: - Fatal error: Cannot use animal\dog\Life as Life because the name is already in use
复制代码
# z# w/ u6 E/ p: c+ F* C E' z2 k/ w因为cat下也有个一样名称的Life类。 可以理解为,使用use后,这个昵称对应的类只能归当前命名空间占有,其它命名空间下不允许存在该类。 - //name.php
# ]4 E8 {' V: y- D - " I3 ]# d' W+ [7 O3 B/ r) L
- namespace animal\dog;
# l: A; a. h) u, p/ _8 T# }# a; g
3 {: e2 T. P; N |- w4 j1 M% ]- class Life{9 Y6 I( d6 p* z! P2 Q% v
- function __construct(){
8 X) e' G( p* J$ h - echo 'dog life!';# t# K( n; Q! l* E9 s7 N
- }
5 ?3 c4 W# o8 a( s* p2 r8 h9 j7 \ - }
7 H' l4 x; W' h" K# a - class Dog{
% q( x$ ~& ~2 M: d - function __construct(){
5 `9 W- X3 b8 B$ w, J; B - echo 'dog in dog!';1 b# [: q) ^# s/ h% x& b3 p
- }1 q# p, H: i% Y% \
- }: D X$ z& e! t. Y8 n% F
4 F' y8 q! a6 F- n- namespace animal\cat;
$ T* v1 @# }3 s' j( \( K
3 ^: D! m* }' l3 A4 `0 a) g/ C- // class Dog{
* J4 Q; M, X' ~" S - // function __construct(){. ^0 }& o+ ]0 k& \% K1 g2 D
- // echo 'dog in cat!';
/ r$ g/ N- W; P3 k - // }
" r* U( n' u8 H: O" D; _7 j# c - // }
: M! O9 `6 _, k4 r7 X6 S - class Life{
, M% _' C: \9 k8 o7 {: [, e0 Q5 R - function __construct(){
& V: f; _ n5 f" E7 Y# k - echo 'cat life!';
+ g# C1 \- ^( T+ O# s0 ?* Y - }
' q8 V% z- d% o2 P+ h - }
4 `8 f P( A }- |
& h5 u+ u4 h( w" g" n' g8 ?) m- use animal\dog;
. K: |9 c* s& Q |3 r - new dog\Dog();
复制代码 ) \0 i5 I9 i6 ^! e
如上,使用了
4 W& F- D- t) Z! ?' B2 e" `5 ncat 通过上面代码,我想使用use的目的效果(缩短命名空间名称)就很明显了。
) P ~3 F) y& ?简单总结一下: namespace就是划分领域的作用,代表这些东西是属于某个命名空间下的。 use就是起小名的作用,不论写起来还是说起来都可以省不少事儿。 4 `" X* H6 ~: M$ b9 q
6 r$ V( e2 o5 f
% b g6 C8 e& A
' U0 L/ _4 W" A' ]' e: W8 A! x
! F' J0 X% |( a, M. y( N& n |