|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。1 t* q6 ?. I8 B+ S6 b4 o
1.命名空间
: d! u% R, Z7 _ 命名空间是什么?1 u! f! ~# h6 } |( g% M/ I
1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
I# v2 w: {0 r- c& N 2).命名空间始终应该在<?php标签的下面一行。
9 T* s. z% J; \: b# M 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
5 ?$ ?$ i( N+ W8 t1 J9 i 4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
# I6 }' l' g0 Z' Q 为什么需要命名空间?
5 K; w9 ]5 c% t% [ 1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。% n$ _* r# z l5 S2 r. d! Y
声明命名空间
7 ?3 o- q+ |- ]5 I9 U 1).顶层命名空间经常用于设定顶层厂商名。1 r! T( X! p s. O5 A/ H4 w
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
6 V# Q5 E2 {1 t, d: O* s 导入和别名
2 N+ p- n0 h" z* Q" H 1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。; R! U4 K; ^0 \7 w4 C
2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。) }% T6 o1 u; Q0 G
从PHP5.6开始我们可以导入函数和常量。; g' K" E- ?: l
<?phpuse func Namespace\functionName;
4 ]& P @! Z% p2 T2 P6 b9 l functionName();
# u9 Q1 G+ |( r0 |6 B 也可以导入常量,
+ C# c$ j2 L! f3 n. O8 C: V6 v2 J1 I+ m$ M use constant Namespace\CONS_NAME;
2 X( I; y6 X; w$ v% v echo CONS_NAME;
. V% F6 @, S( H) K |5 ^ 函数和常量的别名与类名的创建方式一样。
x- @4 _/ Z5 ` 最佳实践
! k+ J# u4 @: S) j% r7 q6 Y 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
' b7 W6 } u6 G( U0 L- F) Q, z& q 2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
# B: E6 J. F! m; n4 y. ^% U' d 自动加载
. E; ~0 |/ p. L# m j- i 1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。0 a! W2 t$ l; q, D( q
2.使用接口
2 w( S) g7 r' U N/ V) T5 n( D 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
/ N" D+ i4 W& G; P. r+ B+ H 3.性状
: L1 i' S7 O K& \ 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。: t! r8 @" d6 z* j$ g( i: F2 Y
2).性状使得两个无关的类可以使用相同属性和方法。
* D6 c X) J% J& k! z4 O2 d 3).PHP解释器会把性状复制粘贴到类的定义体中。" _: t' A- r7 K7 G# U
4.创建生成器
1 u1 u) {0 t. B9 ]. ~6 ?- I 1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:+ P$ H6 O: \( L2 ]; F
<?phpfunction myGenerator() { ^! W7 X" x8 o. ?* _
yield 'value1';
. E X1 X$ G# e6 z yield 'value2';
7 k; I2 m ^% l/ _+ N! Z5 [, t6 F }5 R p( Q: {1 C( ~& {
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:- b3 U5 y4 H! C4 G6 t
<?phpforeach (myGenerator() as $yieldedValue) {: J: w$ }) Y2 W b$ \. q7 Z- V t
echo $yieldedValue, PHP_EOL;6 }- m* m+ I9 {) _/ Y* z/ z8 j9 j
}
6 o3 N. e. A9 E# J8 H 以上例子会输出
) o/ ^0 Q- Z$ O. Y value1
* ?4 i- j3 w3 j+ p) k+ S# D, B value26 J" y) ]/ F9 j I, M3 Q
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)9 w6 [6 @. o7 y2 F3 `8 X2 n
function makeRange($length) {* J: [" i+ v" j1 f/ l4 \
$dataset = [];- O; v$ Y h5 H. \) ~
for ($i=0; $i < $length; $i++) {4 G2 X$ s0 t. w0 e4 `
$dataset[] = $i;
7 a% g- Z3 Y+ l @, b5 u8 z }+ _7 ^8 ^6 K& i% a- A
return $dataset;
' ^ F& v1 W0 o4 v7 X$ x! C9 O }' I" Y9 a0 {% p- ` i
$customRange = makeRange(1000000);foreach ($customeRange as $i) {5 G( z* z& n, Q* T& _4 a& G) O9 b6 Y
echo $i, PHP_EOL;8 [* P6 a% i$ Z/ U n9 @
}
- v7 f9 L+ Z2 ~) T/ S; d+ C0 Q7 g; R) C 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
2 l- G! R) q' @$ s function makeRange($length) {
/ ]. S- A% S. g- { for ($i = 0; $i < $length; $i++) {
* E8 a" {% w h yield $i;- | b5 {. u* w+ P* w
}
8 A% f# p0 E1 D- W6 {, P9 W }3 T" G4 k7 ]( P3 Y: |5 @
foreach(makeRange(1000000) as $i) {5 L* D- ^/ l; k+ R! ^- M7 s
echo $i, PHP_EOL;# n G7 J( Y/ @! |1 h
}
* W: [* \0 S/ m 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
: J- v8 W1 F! r9 |" b5 | function getRows($file) {- ?: s" n; I" n/ s( h
$handle = fopen($file, 'rb');1 M% ?/ U& ]3 ~
if ($handle === false) {+ J3 t9 U. t; v7 ]& v1 o
throw new Exception();$ D( ^2 q1 F& L( U
}
3 R- ~% d! d* ]' |1 f4 s, {7 }+ z //feof()函数检测是否到达文件末尾
' L4 q0 S4 H! U6 l while (feof($handle) === false) {
6 [& G# h% `' o0 m) v3 K5 l, k/ ~ //fgetcsv()一次读取csv文件的一行
3 C5 ]7 ?, m2 E& U' Z yield fgetcsv($handle);2 G) |" C$ N* P3 C6 D
}
) l4 _& y* l' R2 g; Y fclose($handle)
3 h+ B9 p# k/ G* a% w' x. T+ a }
8 ?. l8 p* l$ H foreach (getRows('data.csv') as $row) {$ v1 o( P0 b- e
print_r($row);6 k: @( X7 Y+ N5 k' _
}8 w1 o9 g. i) \+ z! H3 j
3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。" o& \6 B* y1 Y r- \$ @# ?
/ K; N" u2 F' `2 B. ^' R/ P8 B7 Z5 Y7 f: n f, V9 O ^" a* s
来源:稀土掘金 |
|