|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。3 s$ e. e! O e
1.命名空间
' t0 e7 u& W# u) X3 ~# x7 ]* ? 命名空间是什么?& x% `! ^+ i1 @( |; w/ y& G
1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
6 O( q( B' `5 c; n" X 2).命名空间始终应该在<?php标签的下面一行。
- W( R! S: l$ O6 w 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。% j+ R- c7 |/ ~4 \3 ~; K! W+ @. T
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
. \2 l; `9 G: Y1 ]7 y5 O$ ^3 [ 为什么需要命名空间?
& Z9 u; B3 }- W$ a$ I1 u; B* J 1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。 B6 ^, Z' Y9 M- s
声明命名空间
6 o5 p7 r$ h4 r. F7 X, U# K0 N$ c 1).顶层命名空间经常用于设定顶层厂商名。
; s* N' t) X1 M; D x* y 2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
. W8 m' k' X+ G5 o 导入和别名1 s7 G4 f0 P7 w- G4 p
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
/ o" f/ E' C# @$ D 2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
0 I( o/ W+ q. l9 s4 K 从PHP5.6开始我们可以导入函数和常量。" u# i. M1 ?: A4 d
<?phpuse func Namespace\functionName;
, X8 n. i H+ d$ g4 p functionName();" v7 S% y0 p- \9 |4 {$ ^! l, s1 Q
也可以导入常量,& i( G2 ^8 Z& r3 Q$ ^
use constant Namespace\CONS_NAME;
' L3 |) [* Y# h0 q2 \8 D echo CONS_NAME;8 h0 I7 u6 }$ o! m7 R
函数和常量的别名与类名的创建方式一样。) M1 | i7 y" X' }% A6 z- Y/ B
最佳实践
# C F( @9 G, ` 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
' N$ x# o, ]( s# ^& l- k 2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
6 M+ B1 q/ ~$ n1 g( G 自动加载; N& |' o/ Y$ z8 V$ Y2 Z2 e- ]& b8 k1 n2 y
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
! w9 b4 \8 ?( Z3 E8 j7 a6 t+ h- W 2.使用接口
( R% |" p2 Z4 l 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
8 s3 G8 i" \8 ~( i# D" Q; A. j 3.性状
) z4 d7 M5 {- }- V+ s$ ^6 O 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
. k9 _- k/ C3 I 2).性状使得两个无关的类可以使用相同属性和方法。4 r) C H& [3 l1 B( D
3).PHP解释器会把性状复制粘贴到类的定义体中。
' m; e/ }/ `8 l& _9 |& e 4.创建生成器
, n) b3 U" ~ b5 d2 f 1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
+ m- O5 z3 b% W- v# p8 b& b <?phpfunction myGenerator() {
% S4 b& q) w, A yield 'value1';- j( k W+ g) P+ v
yield 'value2';4 d' x& b9 P6 b) N
}, U5 q/ O4 |( F
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
- \1 c) Z6 X( l; D <?phpforeach (myGenerator() as $yieldedValue) {! z0 D4 C3 p4 h" n
echo $yieldedValue, PHP_EOL;
* V" F& J" o1 }0 D+ Y7 E' [ }. L3 u ]* }! \! S% k+ @7 C- F" ]
以上例子会输出
3 m/ ^8 m! L/ q value1
5 k9 _" f t$ W a) o3 ^3 t value2
# ^6 \& P1 c9 {& }% l 2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
0 ^0 f# @$ \2 D, U6 o( O/ ` function makeRange($length) {) A/ V/ Z1 q5 | Q
$dataset = [];) O( ~) g( ]/ @( Q0 @
for ($i=0; $i < $length; $i++) {' z1 c: ?) Y- k9 L8 X
$dataset[] = $i;) `* G+ j) N3 V$ s
}
8 Y+ ]; d I1 r3 Z% f" r return $dataset;( n/ f5 `. p& C1 a; I
}
# ]* P% U# S _6 ?9 c) E $customRange = makeRange(1000000);foreach ($customeRange as $i) {
; R$ K; D$ t: z9 \ echo $i, PHP_EOL;! c. g9 v3 `) f# C$ ]6 z
}
C; F# T) }5 y6 a 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。" c% r4 [% n G3 W# w
function makeRange($length) {
% P. H) Z; V7 F for ($i = 0; $i < $length; $i++) {7 V v2 m: R/ j. u0 U. |
yield $i;& N7 \1 \6 |9 u b6 D8 z
}
8 F) H1 i4 f( x0 L3 j }. L" q$ V- W) {2 S
foreach(makeRange(1000000) as $i) {1 |3 V4 G, a0 y: {
echo $i, PHP_EOL;
; H! V& Q3 a6 a }; g' K) j0 }/ B* q3 H
在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。2 ]! l- C1 f) Y9 x, G1 N/ R
function getRows($file) {" ]+ {% ^& ?# ~( V; |0 @* b
$handle = fopen($file, 'rb');
9 O* b; z( N! { if ($handle === false) {
/ r, \( S( `( t W4 c throw new Exception();
0 b) ]4 b) W, v }' b( @6 H* u* L6 D% i) g. i
//feof()函数检测是否到达文件末尾! a0 W% |" i) d# I6 a0 M
while (feof($handle) === false) {- q* \; H0 g2 i0 G, m- ^+ v( N
//fgetcsv()一次读取csv文件的一行" b9 f; x$ I) ]" y% @& {
yield fgetcsv($handle);
2 ^3 n: d" b. ^4 \. e }* O. t. h/ ]& O. _7 U7 N, i/ z
fclose($handle) m; d5 k$ }/ j! ^* K
}: I1 L. p3 t! V3 H' |
foreach (getRows('data.csv') as $row) {% D* i- i* d! _1 m" H3 w+ l0 @# x
print_r($row);6 Q# }" @, K9 v6 _. C% b) a: x4 K q
}
9 x. }6 g; c9 b+ M! ~( Y/ L7 N 3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。' l7 W l. z- { Q
" n$ Q) @0 ^6 i8 g2 l- z
+ E8 `# J5 D* R. a4 F) A
来源:稀土掘金 |
|