|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
8 V( T5 d5 G' [1 o2 S \* f 1.命名空间' k E" O# G4 G2 } N; s2 N
命名空间是什么?
! s1 ^4 q2 Q) X+ Y 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
+ L: q. n$ p1 Q, c9 ], W" G 2).命名空间始终应该在<?php标签的下面一行。$ `. O- n9 N; p' p, {2 E) z
3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。( M) a& |% [5 j: x" J- a9 S
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
% Q. v3 b! ]8 h* K. l" d9 x 为什么需要命名空间?' [% h) Y f# v* `4 ?! V9 t
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。1 U, g7 H9 F- T0 i
声明命名空间
4 M2 y* A0 |* | 1).顶层命名空间经常用于设定顶层厂商名。. u: w' g5 h7 ^) e4 ~
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。3 U( Y% Y1 R. v8 }( A
导入和别名0 E2 H. M9 E$ R7 {( `
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
2 a* Z( K/ o ~ O8 ^4 \2 D 2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
0 a* V* |* f2 y5 b& I4 N 从PHP5.6开始我们可以导入函数和常量。9 |9 v! b& m" k6 L- I
<?phpuse func Namespace\functionName;8 B% W) v! _" y: d( W0 c
functionName();! \- A! i7 y2 M2 @7 c/ O
也可以导入常量,
4 k6 e3 s% q/ u8 c7 a; V use constant Namespace\CONS_NAME;
) [) s7 v+ o3 B echo CONS_NAME;" r( f/ q# d- n8 p2 A* T2 X
函数和常量的别名与类名的创建方式一样。
9 \4 N0 D9 ^8 I, v1 C/ Q 最佳实践: F2 V( [7 E- @1 j8 g
1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
+ ?4 I" k3 z; M G* S' |4 r 2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
# d4 i# t) N. _( |- ? 自动加载" Y' g9 K* z* I: a# D( ?$ T8 N
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
" }! @) j3 r6 a% V% d 2.使用接口; G4 b, {+ x$ {) z* k5 s3 C) d
1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
& i& z! i1 Q) H, Y* B6 Y& W3 `* _( L 3.性状3 S) Y7 T6 j% A! A0 P* d' l3 Y4 s
1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
6 K: B0 X5 y) @3 r) t 2).性状使得两个无关的类可以使用相同属性和方法。: H( a: ]% [0 r( x3 y7 k# r" b) }
3).PHP解释器会把性状复制粘贴到类的定义体中。
: U s% y5 ~5 r: L) R; M6 p4 d 4.创建生成器. @: U; @- `, N: L" J
1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
% f' ^# y2 p- b7 t) k <?phpfunction myGenerator() {5 P' _: o0 Q$ t: H9 q9 y% B
yield 'value1';* f' I% Y# _1 [1 c7 ]( x
yield 'value2';
: H; X% b1 j5 [5 } }
& Z% w p5 c- e7 W5 q 调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
3 p9 m2 | x/ R( R: T' O8 H <?phpforeach (myGenerator() as $yieldedValue) {& A& C/ J& t# y9 w# M5 L" l0 _
echo $yieldedValue, PHP_EOL;
& i" K/ |2 N! U, C! F' o3 j. I- N }! S( u( u# B3 d2 O$ B
以上例子会输出
Q& B3 O3 g& T4 c3 P! j value1" \, w2 }, m# E8 t; Q2 X
value28 ^0 t% L* K- F0 f
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式). |( \& M5 q: O( a
function makeRange($length) {4 S( R" ~' G1 T, y7 U! a+ l1 m
$dataset = [];
- ^" k3 B9 T4 l for ($i=0; $i < $length; $i++) {! D: N$ T: Y9 ?2 x! I7 `2 E
$dataset[] = $i;
# ^2 W& `2 ?- ?5 n. L9 X/ P2 } }, F# a$ c8 [1 }: E# g# K
return $dataset;
7 J& o! V. g. k% S8 i5 O3 y/ c } N8 i+ {- c6 |
$customRange = makeRange(1000000);foreach ($customeRange as $i) {- n. B' e1 O/ N* R# \
echo $i, PHP_EOL;6 H& n/ A7 F7 V1 I% ?# b; Q7 N
}
5 H0 E# Z. O9 p 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
, G* n- Y D# \( R1 P7 x$ s* I function makeRange($length) {' v) N9 q) u3 s
for ($i = 0; $i < $length; $i++) {
6 Z! g3 `/ E4 u& s# m8 ]* n yield $i;
+ p" A A b/ i9 M; A3 P9 L1 \ }/ Q9 r% f- W, G6 A( S
}
. m5 Y9 S) @, G Q! e" p( S foreach(makeRange(1000000) as $i) {' S0 m: N- h: ^! m* O0 r4 K
echo $i, PHP_EOL;# D" i, b! o# ?$ F
}& h \& D, S5 V% [/ Z+ K) E" z( k
在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。* v: L. S. a( ], c5 z( g
function getRows($file) {0 Y. C+ f" v* Z: Y$ `' C
$handle = fopen($file, 'rb');
0 U0 `0 x& Z8 b, s" I5 i' Z if ($handle === false) {
" e7 Y( U% u, L& x throw new Exception();$ c" p" O: n. F% \
}0 t8 F: m, D; L! |
//feof()函数检测是否到达文件末尾
: Y1 e, \: q. [8 Z) V3 _3 \% b% g while (feof($handle) === false) {. K; i" N$ W/ c3 t8 C
//fgetcsv()一次读取csv文件的一行
1 w$ T8 Q! H0 S% o9 J' H3 Z/ M yield fgetcsv($handle);! d: j, t- y, ? V6 O
}
' ?( N8 L, {- x& p6 ~9 a fclose($handle)
$ v2 h9 A: S( Q' s3 l4 { }
' g8 b0 w+ k0 y9 `& ^7 |- u& z$ N foreach (getRows('data.csv') as $row) {
/ m- ~2 { Z, |9 r3 u print_r($row);
# K0 [7 w( Z5 k& Z2 U; q }
8 _+ Q% _4 O- J) F4 r 3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
. r& D- C& c- |* F: X2 s: X' e; t( N
& h9 M. u4 S9 |" _6 G9 {来源:稀土掘金 |
|