|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
. I- }: B' |; @, L 1.命名空间
! w: `! {' D/ H# y; w 命名空间是什么?
7 x! R$ k; g$ C 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。( m: R# m/ M! `: k, ~- X2 ~0 n
2).命名空间始终应该在<?php标签的下面一行。6 ^ f3 J1 x2 q- }$ _8 x
3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。; K4 a5 X3 @/ ]0 Q0 [! `5 B+ `
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。: k( y" w4 y( G) H K( m! J& v8 S
为什么需要命名空间?2 G# Y( P/ \6 \( I1 A4 l8 M* Y
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
* V1 \9 O3 [% Y" Z9 G0 L8 H) X2 k 声明命名空间
2 {8 b, `- C, j6 q5 v 1).顶层命名空间经常用于设定顶层厂商名。5 N0 U# L! A7 s1 F: `) j( V D
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
; ?1 N# s- m2 X# D0 i 导入和别名* ^$ i/ s6 T) y! P" Q
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
% m5 ]2 g& i3 t* z 2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。% d3 I# J4 T" m- G
从PHP5.6开始我们可以导入函数和常量。* K% T, I8 E- X$ R
<?phpuse func Namespace\functionName;
$ b, r! j e5 C/ ` E functionName();& w1 x) K" n3 j! O3 b5 D8 ]( C7 r
也可以导入常量,
9 U1 x& T" E' }% R1 n, R use constant Namespace\CONS_NAME;
0 M( V# R2 K; t$ h3 r9 y6 k echo CONS_NAME;
, Z- x+ }. H' z* N- j0 @- _7 ~ 函数和常量的别名与类名的创建方式一样。
8 y6 K/ Q2 m' R( l 最佳实践
) X7 N8 }7 c* T/ s7 X" G* i* }% k 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。6 H& m; w/ p7 s P q3 t
2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。% F7 l3 c- G, \
自动加载1 Q6 w9 J: D! F. \1 ^
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
9 S$ A$ A! ~6 g' j ?# c1 v* u 2.使用接口
: d5 d% z' Y% x' v9 _" a" T 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
" U; Y% R4 D; V* r$ i 3.性状
# w, n- ?7 M1 ? 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。8 p+ U( R" Y2 f5 s7 Q
2).性状使得两个无关的类可以使用相同属性和方法。9 o3 g0 G/ j, I: N* v
3).PHP解释器会把性状复制粘贴到类的定义体中。; m3 v( i. m. W% R9 t
4.创建生成器
. ]+ ]# p: c2 s 1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
& R- c2 f! O e0 r- N% n$ U <?phpfunction myGenerator() {7 S# h+ f; U, P }1 r2 _1 K1 H% }
yield 'value1';0 M" c! e) n8 X! |: X
yield 'value2';
3 k Y, f: |- |+ l! I, `# ]' l }6 V3 [& o8 A- L0 D) f% G9 s8 P2 d- {
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
/ }/ ^* V$ }4 J" Y3 s4 q& c <?phpforeach (myGenerator() as $yieldedValue) { ^9 }$ ]/ @9 v# W1 o0 K( L
echo $yieldedValue, PHP_EOL;
+ p+ ?5 h5 T% E }
* L1 {1 B% F0 |6 p; E. f" m7 i, l 以上例子会输出
9 b( \* H" ?0 y) c# ` value1 Y: k* y! J% o
value2
8 ^" |- D. v, [/ Q0 Q 2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
& V" i; H" ~" W: d8 e" n function makeRange($length) {9 n5 g* p( y& i9 G# x% } X2 S* d
$dataset = [];9 w" o6 V' l9 _5 r
for ($i=0; $i < $length; $i++) {
" S( A3 l' j' Z$ S/ ` $dataset[] = $i;! B/ Z6 u$ D; ~ Z7 l3 t
}
' b& Y# N4 Y% r# { F8 r, o; T9 K return $dataset;) O1 I+ G7 b/ T
}
$ I) b, c" s' O' _, g $customRange = makeRange(1000000);foreach ($customeRange as $i) {2 I* {$ Y8 L" y n8 v
echo $i, PHP_EOL;
4 ]! }4 `; ]# b) x2 I) X }
' o( ~2 m% F4 A. ?5 q 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
- Y, t, ?3 o, P" }* l8 F, m function makeRange($length) {
1 ~% h, P! ~ R4 l: c for ($i = 0; $i < $length; $i++) {
, ?! ~" b& l) ~ yield $i;
, t* [; e& @3 ^( ], c9 i' i: w }) n( W- u- t: p, k: j. ] V* q
}9 {5 ^5 @8 a* L) B0 l* @, \
foreach(makeRange(1000000) as $i) {1 Q6 F7 O* Z) i6 c# `
echo $i, PHP_EOL;
8 n" L2 H# D7 s/ \2 l, { }# {9 x" [& j B9 W& N; B
在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
5 ~. Z8 S) a7 l! O# @ function getRows($file) {
, h9 f. M+ e; d8 m- A8 K $handle = fopen($file, 'rb');
, H! S0 G* {7 j4 d0 @' R3 p) v if ($handle === false) {3 a4 u+ I# |' C+ ^
throw new Exception();! Z4 }( T, J% j
}, K- l. h- u- J8 g: c4 f
//feof()函数检测是否到达文件末尾4 u8 l+ }* F% r
while (feof($handle) === false) {) Y. v; R4 z* }
//fgetcsv()一次读取csv文件的一行) B- f3 k ~ c5 r) g+ |' b3 | K
yield fgetcsv($handle);
D8 P* L" t& B; u; q# y }( E! s' o" A' l
fclose($handle)" [) M2 c H7 e4 ~4 i0 Y
}+ c, }: q4 I( y' n7 }2 x. c
foreach (getRows('data.csv') as $row) {0 \3 W6 L$ [9 e8 K
print_r($row);' r/ [' ^2 v& T7 {) @% f! |! {' e
}2 x% y K) _6 P4 B1 @$ |
3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。: S* x2 C0 n/ d/ q
4 z; Q. o% L+ T$ c: r
% ~( V1 p& {* s! c6 U; d$ G来源:稀土掘金 |
|