|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
( ]% h$ K7 |" P) ^5 U. N 1.命名空间
3 q. C2 @8 a# [) T 命名空间是什么?
# F+ E# D4 p# \" i2 V/ D 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。 W! I4 K1 A. W! U- K9 b
2).命名空间始终应该在<?php标签的下面一行。
" d) c; Q: X0 q& ^# O8 p 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
8 z8 y, j* R( V) e9 Z/ ] 4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
) j; ~* q* |) I+ e6 z 为什么需要命名空间?. R O U$ ^. y0 d! {
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。 d4 o0 N2 a( c& c4 w' }
声明命名空间
1 c+ k+ [/ t' ?2 y/ z4 k9 L 1).顶层命名空间经常用于设定顶层厂商名。1 J& `5 Q7 u/ g
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。( n e% p9 ~. i9 J2 [
导入和别名
1 S- `3 D. X; o' t 1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。, w- X, |% ~( s4 R* C, I2 _1 C
2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
! j2 v" T! ?! U. Q, @ 从PHP5.6开始我们可以导入函数和常量。
+ b8 f1 J" T* W2 v k <?phpuse func Namespace\functionName;
8 c+ d9 d0 w0 Q' q$ p p5 D! w6 m8 m. n functionName();
' j9 E1 \: q8 @2 H 也可以导入常量,3 B+ Y' r6 z& ]( r+ l" O
use constant Namespace\CONS_NAME;# J5 Q. w0 {* y" k' z0 F
echo CONS_NAME;
0 K( B- @4 g4 ?' r+ _- u# y 函数和常量的别名与类名的创建方式一样。 @1 P0 c" m6 s' X3 _& G f
最佳实践2 b, e% K7 j& E& y# D' C0 g+ Y% k
1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。! P" \7 j' j# k# P4 r+ ?' D
2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
5 t4 `5 G6 K$ T1 }# C5 l% T 自动加载
! }6 T" V3 a7 E% ^7 _3 d3 \ 1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
+ |3 l+ ~" p& w 2.使用接口' ?/ A3 j# J* G. T
1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。, C* `. v6 q; {) M |/ @* {% W
3.性状' ?& w4 I$ D' U7 g1 J5 k
1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。9 U( x. e9 s* p& S
2).性状使得两个无关的类可以使用相同属性和方法。
# n( c: O! O+ b 3).PHP解释器会把性状复制粘贴到类的定义体中。
) H, W9 c" }3 Z- N5 p 4.创建生成器7 V Z3 }# |/ r. Y7 J. k' q
1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
% V x: C4 M7 t$ ?% m: a7 F <?phpfunction myGenerator() {8 L% ^/ A# q; N$ C2 @: U" A8 C9 M& N
yield 'value1';
- z9 O! d. v0 f! i {: ? e4 z yield 'value2';* l( [/ s' t: q4 |
}
* ]3 U4 T% ?# F! ? 调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
2 N1 J, Q! r6 ~% N <?phpforeach (myGenerator() as $yieldedValue) {
3 @ e! `8 t. Y8 @4 G echo $yieldedValue, PHP_EOL;
0 B3 t: j8 t: T1 b# J5 d3 i }- V2 L/ u1 b' E
以上例子会输出8 x T0 X2 m7 s9 ?
value1
: C2 H w2 s6 G Y& `+ n/ Q value2
0 e8 U+ a. {, V$ Z2 S 2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
; Q; U6 P+ C# X4 m+ t+ v function makeRange($length) {1 D# e# g. `& r, C6 b8 W
$dataset = [];* e: d' j% R7 M! l8 a
for ($i=0; $i < $length; $i++) {
3 j* r) k0 F1 L, M $dataset[] = $i;
. R/ t) H& K( J, v! C; } }& l& A; R# v& P
return $dataset;/ x, F% q d3 {5 o" l* h
}
& z. t7 t D- b; s3 c/ Z $customRange = makeRange(1000000);foreach ($customeRange as $i) {
) [; z( J8 T' l2 k( |( g echo $i, PHP_EOL;/ f4 ?6 [9 {% h4 f8 ?. P* x" U
}1 V' F7 q$ H( P+ J/ R) x+ v1 T) P$ |# g
预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。3 I# N$ M, l8 U# H
function makeRange($length) {8 M: F- _, d' W5 L
for ($i = 0; $i < $length; $i++) {
8 c) e$ p& J% R4 z3 ^% S+ h yield $i;# s/ q/ h8 P, G3 d% Q
}' x' O8 M b9 m8 n. h- Y: F, P
}
$ w1 H+ q: s$ X: s' q foreach(makeRange(1000000) as $i) {$ I* m- f+ [: ^0 Q! X7 ^6 H. F
echo $i, PHP_EOL;
8 k K7 `+ R; P1 k" ] }
2 d$ S6 ` ~& K C: B& ~, v 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
$ x, ]" k/ I" g% C# I function getRows($file) {, r& c- O5 f: b, J1 M
$handle = fopen($file, 'rb');
! \# T+ l) F. Q9 q6 ` if ($handle === false) {/ L Q6 I) m0 y5 U! U4 p2 U. ~
throw new Exception();' F R' C6 Q5 J( J5 \0 S
}. f( S; B. _- U3 A
//feof()函数检测是否到达文件末尾
: S4 a# b, m/ n# ] while (feof($handle) === false) {
; r# N' c% H' K$ A- f6 { //fgetcsv()一次读取csv文件的一行/ I1 M4 p; P8 m5 r9 s( {9 j
yield fgetcsv($handle);
# t" L9 ~7 c0 O3 `, z M6 L, w }. I+ x9 O8 Y& d5 R
fclose($handle)
6 c- s1 @ J _" Q9 y }
/ d3 U- c; W6 y0 _1 t foreach (getRows('data.csv') as $row) {. Q7 J' A1 `7 \1 x& O2 K' \
print_r($row);+ X7 |* }2 y3 K3 m
}
8 y( Q$ g# T. G% v) g7 a' I 3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。 i$ t _' M7 E! j: Z
7 E: f6 w! V' K
4 _* E `7 n& D( I% Q* J7 X来源:稀土掘金 |
|