|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
( |& V# [* f5 _) H! i: }" v0 [ 1.命名空间
2 m) D- H) i3 J8 c, A- b 命名空间是什么?
/ u6 M) ~8 @ w8 L9 J, D4 G 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
- z1 N- {% U9 f/ o" ]0 h3 ~: I 2).命名空间始终应该在<?php标签的下面一行。2 s# }/ L" }$ V. _6 Q: W# k
3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。0 X; D- Y5 R4 Z- G5 Q2 l
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
2 a1 @. w! Y1 I! Q8 U1 J 为什么需要命名空间?6 x4 r- D6 @0 p( j6 z* H- z
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
9 p% e8 t2 e% o7 r 声明命名空间+ A4 p) ]# K6 g3 N; r
1).顶层命名空间经常用于设定顶层厂商名。& G# Z, B8 I f8 q' Q1 D- S
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。/ V7 G. T1 H' x$ J% \! M
导入和别名1 ~5 Z* [& q* o0 a. I' L
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。/ H: E' y8 V' C ~0 ]
2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
9 u! g0 @0 j C8 ?9 U 从PHP5.6开始我们可以导入函数和常量。+ K0 `8 b$ z, B
<?phpuse func Namespace\functionName;
3 B! a# J/ q9 n9 ~. I( e) f% w) f functionName();$ `8 Q. j) w2 K# E5 P+ Y" @* t& t
也可以导入常量,
! o; H" k6 L2 G* j" |3 M" W use constant Namespace\CONS_NAME;
* d& I& [! H# v/ j echo CONS_NAME;7 F+ U V, o) Q3 `1 s
函数和常量的别名与类名的创建方式一样。
, `& {" ^. ^9 J6 E7 f 最佳实践
0 a* k" M1 Y$ }( M6 `2 { 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
: o+ ?: \3 l$ N 2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
# }# R1 |( F {, v 自动加载% W( r( F1 ~& n4 t2 D7 T l! ^
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
. `, m. z# O+ k+ `; s, S8 l 2.使用接口
9 T o7 j/ ^. E; O9 n; n 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
4 a' f6 i; d$ G& R- _( }9 w' F 3.性状
& H0 k7 _/ ?9 a4 v 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。5 M; m* p0 H: P$ f: C
2).性状使得两个无关的类可以使用相同属性和方法。3 `* K' L5 x8 t1 A+ p
3).PHP解释器会把性状复制粘贴到类的定义体中。
! a5 ?# {0 [8 i9 f& o 4.创建生成器
- H% }% ?9 x# W' s. \& g 1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
1 ~( r3 I9 U0 l8 X# @. b5 S <?phpfunction myGenerator() {. r3 r4 r+ }4 B e6 e
yield 'value1';9 l' p; n- S, {7 r. C4 H5 k: O
yield 'value2';3 n" ^7 ~1 v) X- K! N
}
) m$ Z# Z' `3 d% b8 K; B2 B' M( u 调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
# D# [4 c( m3 ]$ G" W <?phpforeach (myGenerator() as $yieldedValue) {
# W5 F' p3 P! `7 v) h2 k! C echo $yieldedValue, PHP_EOL;
% q6 @' x& ]" d }
5 d9 s+ O$ f8 n/ p 以上例子会输出
! F+ ?; L+ A" H" {5 J: n value1
* W3 H1 c* @: }+ J2 @& W# [& U value2) z5 k4 P7 v! B I0 t( A& \% \6 i
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)2 a! N5 p2 @' M' H
function makeRange($length) {
9 }4 U( }) K. W% L# l, Y8 \) S3 g $dataset = [];
5 C3 E* C8 n; y! y% d6 _+ c4 ^2 ~ for ($i=0; $i < $length; $i++) {
7 t! S4 T, y7 `4 o. U! b $dataset[] = $i;
* u- Q! _) }1 ?! v. O( i9 U }# S3 r# c o, b; u7 w
return $dataset;* w0 P& @6 P/ S+ y* G
}) j+ P! _1 }! C
$customRange = makeRange(1000000);foreach ($customeRange as $i) {
4 N# O& L- V) O( ?6 \) T echo $i, PHP_EOL;; k6 |' w! M' K9 o7 f5 O
}
' s9 h2 `/ K* V8 t! `2 \) @ 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
9 X. {% p: g5 C. G0 [) ?& B- b: i, H function makeRange($length) {. M' e$ P7 I3 Q% C
for ($i = 0; $i < $length; $i++) {
. {* W6 Z! p$ T% n yield $i;. e& x) C1 u2 r& V. H
}
4 s/ i6 X6 j* }. l# n, g8 n }
\ K: H1 i" l. f8 Y- O: s6 J, u foreach(makeRange(1000000) as $i) {% T2 N0 i, v. ]6 S$ ~* j
echo $i, PHP_EOL;0 h4 I' Y+ u' u! w; {/ M3 v* ?/ P+ j
}
7 I4 Q) g+ l4 r$ s4 _ 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
/ N* k2 d9 h5 h! m function getRows($file) {
' T6 L5 N; m% b; K2 Y X $handle = fopen($file, 'rb');
+ V; n$ S$ t1 {9 O7 ^" J" u if ($handle === false) {( E, n7 p+ U* U" c5 N
throw new Exception();
; m2 Q9 J1 @1 w8 e- Q }
: d% P' ]' F$ V" l/ y //feof()函数检测是否到达文件末尾4 \# b6 q1 a5 Y. G$ k( W, \
while (feof($handle) === false) {
, x) T; j/ b4 F- l* j //fgetcsv()一次读取csv文件的一行3 I6 a# C: T' N+ Y2 ~3 f( C
yield fgetcsv($handle);) t+ O( d9 h- ^4 v1 |% ]( z- u
}! _8 ], z# q! {; W" H
fclose($handle)- S1 @: |* L* J% [: b
}$ Y% K& i w/ u; v
foreach (getRows('data.csv') as $row) {
4 o7 H& E' s* y K! } print_r($row);* T. b+ \) y8 ]( }$ T
}, p! l4 Y7 n! j
3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
' R: n) a2 t- p: P6 y6 z- s, C! w/ ?4 H
. ?3 O5 u( G/ J4 r# ]
来源:稀土掘金 |
|