|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
, V2 q7 V: |- h2 v 1.命名空间
' u( S; R; K! z' G% D. K" u 命名空间是什么?- v3 s' m- R6 d/ P% A
1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
& } h6 N% K7 j# K 2).命名空间始终应该在<?php标签的下面一行。
0 d4 k) e8 X1 v) \( z 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
1 l# F# Z% q& b& l% b 4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。( s- g- b) \7 W0 v; |
为什么需要命名空间?4 g8 X( u/ ^/ [0 i1 B: _ V8 t% l
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
) T7 c+ W" X5 G; Z+ b. `2 K9 l 声明命名空间
9 x6 p# \" a: m! g! v 1).顶层命名空间经常用于设定顶层厂商名。
* P; h" ]& s( Z1 K! U 2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
7 K7 Y6 B1 v6 p" q% z" K# C2 d 导入和别名
8 W; B4 l& E. \; l 1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。; w& Y$ l3 R) z
2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
6 N. y7 K# Q) h# y 从PHP5.6开始我们可以导入函数和常量。. l: S* K5 }) H; ^' |# N
<?phpuse func Namespace\functionName;
2 O! C& R4 N" j9 h; W4 T; C) s2 a functionName();( L/ R# X$ d/ x, {
也可以导入常量,# N& |3 l. K, d$ O B
use constant Namespace\CONS_NAME;
$ W+ K8 a+ H6 V! [; C! I6 g/ d echo CONS_NAME;8 O7 z4 ]1 ?& X( p
函数和常量的别名与类名的创建方式一样。
# }/ m# B4 j( H8 I$ h! j 最佳实践
( s6 R7 I3 e3 ?: Z- r( j 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
& B8 D |+ Q, J* F7 I, u2 l. ~ 2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。; D, b* _3 s/ ?0 k6 g
自动加载6 U" M% y( p% x X
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
! Q. g$ m& r% j0 f1 a6 Z( z/ Z 2.使用接口
! ]$ V3 F: O# W7 d 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。# k" q' \' m* {* ?, I& i4 p! j/ g
3.性状
' O! }3 Q8 C+ I5 K 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。- @. b) t/ w$ Q& d9 H
2).性状使得两个无关的类可以使用相同属性和方法。
5 C4 K' _8 K1 a A1 h% k- @0 j6 ~3 Q 3).PHP解释器会把性状复制粘贴到类的定义体中。' o: Z- [ e5 w% \2 T
4.创建生成器 Z; K7 T* P/ s2 s4 ~
1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
- y( Z4 [' R% R5 u <?phpfunction myGenerator() { J7 m5 C+ b8 v0 J4 i* b
yield 'value1';
) k' }' z/ m$ [2 Z yield 'value2';
4 N0 i$ O; x3 D. w- C$ M8 Z" [- z }
7 o( J8 M+ R& p( Q( p. T 调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
, z* ]( m' C7 ^& `& o" C <?phpforeach (myGenerator() as $yieldedValue) {5 ~+ q1 f* O. |4 ]
echo $yieldedValue, PHP_EOL;7 Q) A6 \3 M5 ^+ W% p
}
, W1 y1 [) c+ Q, \; G6 @ 以上例子会输出
( l# w0 S9 }# k0 w9 h/ [2 ? value1
, `4 r& s. Q4 ] C5 L/ v1 a. ^& a value2
1 \% L% Z3 @ m2 m& H: r% S! D/ h* l 2).生成器是如何节约内存的?生成一个范围内的数值(错误方式) f2 \7 m# V+ g7 X. h6 ^
function makeRange($length) {/ Q, [: \( e9 i1 s* |7 j+ ~- e' K: I
$dataset = [];8 @! ~2 d* I; m# U1 c& }+ [
for ($i=0; $i < $length; $i++) {
4 W; q5 c; M" j; J $dataset[] = $i;4 Y2 h% K. {4 W6 e# r
}
; }1 ?$ W1 v0 m& f6 P return $dataset;. G' _) R' C# S. x) N4 \( {. s
}/ `9 N. I" c6 g7 ^- ~ K: r
$customRange = makeRange(1000000);foreach ($customeRange as $i) {9 i6 R6 S( w- z4 r( J$ r# P
echo $i, PHP_EOL;! X7 X1 c3 g5 A8 G, a. k5 \1 k/ v
}
5 ], n! }0 t0 u2 C# P7 { 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
% [: a9 H0 @5 f1 i* M( R Z function makeRange($length) {
" D0 c4 ^3 K% t for ($i = 0; $i < $length; $i++) {2 S! O% Z# p9 Q( [8 v" E4 |
yield $i;7 l! L6 O" U4 {5 G$ |+ e! c5 p
}
3 D& {+ ^7 n0 G+ L7 v: A M* y' _8 b }
' c; @" J# w0 h foreach(makeRange(1000000) as $i) {, c1 L5 M i/ x
echo $i, PHP_EOL;
5 y7 R6 G; K: Y+ y' ]: N, V }. c- d' Y3 ^; u
在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。6 L. f9 N' a) `. S @1 a
function getRows($file) {. p4 }) }. L% B- X9 K6 n# E! [; k4 J
$handle = fopen($file, 'rb');
% X; T; R9 h: _ if ($handle === false) {
( ~# F& v N& r( z$ C throw new Exception();
2 i5 p/ G. {4 R: ?, ? }& g3 R0 [' z3 E, Q7 d
//feof()函数检测是否到达文件末尾8 R/ Y8 u3 e$ n6 ?
while (feof($handle) === false) {
C0 J* S, @4 `7 ~# @& B/ z5 o, s //fgetcsv()一次读取csv文件的一行
d: m" w1 l- c" i2 ^! [ yield fgetcsv($handle);
[6 |% z+ {: n& U. ?4 P- F/ q& ? }1 z" A. V4 o6 T' T
fclose($handle)
: o) x- b/ q1 [6 Y7 g G }- b1 j t* k4 b( `; L
foreach (getRows('data.csv') as $row) {
( G' A$ C" X; d( p. @ print_r($row);' W0 w# Q7 A& i _- B5 S+ z3 ^
}
0 |3 M0 B6 _' @3 w7 A 3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。* V4 B8 _9 j5 k I0 G/ h, W
) P3 a+ b$ N3 `) g2 j
% W" B7 w# X% N8 j- P来源:稀土掘金 |
|