|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。2 E& k2 F6 p$ p6 o' D' R8 R
1.命名空间1 t& @$ F0 C% [- A% |5 Y# G# j
命名空间是什么?
- D$ u& @6 I+ e2 W, U1 m& F- I 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
0 k+ ^7 O, w, L Q4 G+ v- t 2).命名空间始终应该在<?php标签的下面一行。
1 v- ?( |: L5 A. \' M, r2 l 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。! I" D' J5 O2 K4 B
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
4 t% l) j2 D8 r$ T- ^ 为什么需要命名空间?% S5 D! H I7 T
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
. L% N3 p5 p5 \* r0 g# ?8 J! x' ~ 声明命名空间
' t! B1 W: \0 w9 V; l+ @) y: A 1).顶层命名空间经常用于设定顶层厂商名。8 Q; F. s3 F# t
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。4 s+ l( d2 z( O; O5 y: x! m
导入和别名" b1 d/ W" R% g \5 ?
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
) x2 c4 y0 {! ^# u0 X4 B 2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。1 c7 r! D" D2 Z7 K7 U' W3 Z
从PHP5.6开始我们可以导入函数和常量。7 y, }# w t2 Y% e( b( k
<?phpuse func Namespace\functionName;
: O1 z' S3 v7 S7 \ n! Y" ?. J functionName();
# W2 ]6 E& [8 ^8 a* g4 |- E 也可以导入常量,
7 P7 T+ c" w, ?6 r3 J use constant Namespace\CONS_NAME;4 Y0 ~0 K: n& K- f! G i1 C
echo CONS_NAME;! [2 L2 F0 f( }# m
函数和常量的别名与类名的创建方式一样。
, M( m% y1 f' z( n/ u' s+ Y 最佳实践; {0 ?: L; J4 u" Z( N* F
1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
! s* c. q$ G) n$ R 2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
. L+ J% r6 \. V" w& m' ^9 k3 X 自动加载
: H3 }3 e, S1 i: }# l3 } 1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
. e6 s/ I4 r# j! A' Z2 }$ b7 e. X 2.使用接口2 K% M5 J; }4 _- L$ Z: P! w
1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。5 G" b; @. c; i A N$ _
3.性状
, a5 Y4 }5 J& s5 b; f- T 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
. m8 a6 e) T% a% [# b# h 2).性状使得两个无关的类可以使用相同属性和方法。7 |1 F' ` E6 z# W8 g) h
3).PHP解释器会把性状复制粘贴到类的定义体中。
# _/ A4 ~6 U: Q 4.创建生成器
2 x- w9 H. D' F/ _ 1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:0 J1 F0 R& _# `5 |* T
<?phpfunction myGenerator() {- _( v r0 E$ t! A6 _$ C
yield 'value1';, H% ~$ }7 _) A& ^
yield 'value2';3 C: r a9 C$ ?7 _- N
}- S5 M7 b% q: ^9 ^
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:1 v4 s' V( w4 g" u4 C$ W
<?phpforeach (myGenerator() as $yieldedValue) {1 \" t# C- ] Z& F
echo $yieldedValue, PHP_EOL;
5 r/ F( ?) F M& R9 g( l0 q _ }
4 h: _# T2 O0 Z# n# O$ D 以上例子会输出
; R% q( b$ m. x value17 ]& Q2 n! o+ e5 O
value26 I5 @1 C w* e" H" M
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
7 ?4 {% N( ~5 B2 q' p; v function makeRange($length) {
, d0 U* R: B, @ $dataset = [];
/ T4 N9 j3 y: [& t: }! e6 s* l for ($i=0; $i < $length; $i++) {- b8 k/ t) r/ E- W7 w9 q9 C! @
$dataset[] = $i;* J0 w! ?0 _$ s1 L
}
- n! b. t' D' w return $dataset;
+ ]; b+ R! U0 V% a5 Q q+ z- W }
: w5 G% F! Y: x5 m $customRange = makeRange(1000000);foreach ($customeRange as $i) {
. t' d4 v5 ]8 k) o( X% ]/ q) n" \9 h echo $i, PHP_EOL;. \5 y$ w* G5 }
}
: w7 n M& [& ]/ b 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
' h6 }$ E2 Y: ~% h1 M" O- c function makeRange($length) {# W" L* y- e& c& _9 ^
for ($i = 0; $i < $length; $i++) {
! S3 u1 r* D6 N4 U0 k yield $i;- m# p2 C9 m# Z0 \" U# ^6 h8 B
}
) n$ u7 v9 P. ]( I6 {0 @5 U }
3 g1 }+ g6 Y4 Q foreach(makeRange(1000000) as $i) {
; f6 P: Z2 p8 `! B echo $i, PHP_EOL;. v+ Y* N. u+ @9 Q4 q' A' m' r9 w
}
l' j1 C% q# x+ h" S' F 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
% ^% {* G6 z* ^+ D function getRows($file) {% U0 X0 l7 ?6 E% K& N% Y& M
$handle = fopen($file, 'rb');2 u# C; G+ s( F8 U' y
if ($handle === false) {
9 C: U9 \8 B' q& r+ Z throw new Exception();
' U3 F' W5 g$ f$ c/ B }
0 r$ h( }3 f2 l$ S' T. X8 G6 o: I //feof()函数检测是否到达文件末尾6 O7 W3 A; ~ X
while (feof($handle) === false) {7 H: J% p4 x; C ^. q: G
//fgetcsv()一次读取csv文件的一行* t) o' D" n5 ~
yield fgetcsv($handle);5 Z$ g! x* S" p e' {- B, l
}: X5 Q( m1 j5 V; K F2 W
fclose($handle)
9 V# f7 h4 E% E9 t8 D }
w9 }( k# d; A4 q foreach (getRows('data.csv') as $row) {
+ p6 [7 e3 w! e, l; H print_r($row);, D% M7 v" q! w1 M: ?: A
}& C3 f' Q( c7 V. i( R
3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
% ^" [5 G1 M# a- G" ~2 o6 d& K1 i% D$ @
/ _& K9 X9 A/ I+ h B& Y
来源:稀土掘金 |
|