|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
; [& X# S# |# L! f 1.命名空间
5 U' E. c) }+ Y5 P1 t 命名空间是什么?. k; l/ s, D5 q& y1 D# x
1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。1 }- A- p0 q! @. _( v; I( T
2).命名空间始终应该在<?php标签的下面一行。
; ^' w r3 E) d: ` 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。9 V) f. P- L0 _' M. {1 ]
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
. `$ G" o/ Y' s8 _/ s 为什么需要命名空间?
& r$ @% m9 O& q9 a0 b0 G 1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
/ ?9 J( i ^6 c& e 声明命名空间2 n1 O- f; |; e* t
1).顶层命名空间经常用于设定顶层厂商名。- ~! h5 ]3 ?+ i8 R0 E( q. s. r
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
" \/ N5 U0 y- F7 G0 u$ y 导入和别名3 a6 y( ?( _2 j+ y# i, G
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
5 \* W, S6 ~6 ~# G# l% T, D 2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。4 a3 X+ X2 `$ L0 O( _, c/ D8 G
从PHP5.6开始我们可以导入函数和常量。6 @! m7 K' K, c1 \5 l8 d3 S. S7 s
<?phpuse func Namespace\functionName;
# [" h. v2 N% m3 @2 G' M functionName();
9 f- G: i( h. b5 U4 d# R& Y; V+ y0 ] 也可以导入常量,
5 u/ \" I4 l4 ^1 ~3 g j' |' k use constant Namespace\CONS_NAME;4 i9 R. Y- _2 H4 H
echo CONS_NAME;4 ^: ^3 i5 h* C" h6 Y. V
函数和常量的别名与类名的创建方式一样。& K3 Z+ z) N; m2 J+ j2 i' x
最佳实践
4 w$ U1 O9 o! m1 F 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
, F6 Y' y3 b' P' c 2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。% @- C6 L0 u; Y; L4 t
自动加载
, k1 N5 n/ `8 l- W5 J' W# P 1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
4 O( R! S6 j3 T 2.使用接口
' `3 ^) f" ]) ^ 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
8 Z8 @: u+ m3 p8 r6 Z/ F% e 3.性状
8 d% E4 h# a s0 Z' K7 T 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。$ I+ \8 o5 l; c3 w# n
2).性状使得两个无关的类可以使用相同属性和方法。
+ e# i8 S8 Z1 R. Q1 o) G 3).PHP解释器会把性状复制粘贴到类的定义体中。 s) E% f, g; D' H- i0 j* t% g7 s4 N
4.创建生成器( p+ H* y, m+ u2 X5 W
1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
. p% j6 B( T; M& H; X b <?phpfunction myGenerator() {3 W. Z: ~, t/ ]1 Z
yield 'value1';
8 e0 g9 |. R* b6 u( ] yield 'value2';% R% M4 k6 y& s0 J
}( g+ R4 g! ?7 L, Y. W8 [, H
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:3 ?6 h: n) W6 f
<?phpforeach (myGenerator() as $yieldedValue) { E6 R* I/ E* i+ }$ ^
echo $yieldedValue, PHP_EOL;
1 f# A* \5 |+ |6 s ~9 y% \9 q1 _, C }; k$ _" W: L9 c1 O
以上例子会输出
, {' Y) L! |& e value1
& T2 D1 C1 E8 N5 ~; A; T value2
- N8 a8 T6 u- N9 ^9 N 2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)0 n8 ]7 M) K6 O; g2 @" o( k
function makeRange($length) {
6 L; `% q0 @# m/ _ $dataset = [];
+ G7 r4 L+ {" P3 h for ($i=0; $i < $length; $i++) {: v$ q2 C# B0 c; c$ M% r
$dataset[] = $i;( U. N: M6 s9 Y- V' m
}
( X3 }' M) |# p. c6 _$ K* i return $dataset;! u) u! j/ @) ^4 o/ G
}
# `5 t" ^# k% I$ s+ w $customRange = makeRange(1000000);foreach ($customeRange as $i) {
- G, Q0 t! T9 W, \. F0 m echo $i, PHP_EOL;
4 y' b5 G$ H. I* w2 w }
0 B4 h, w) i3 V' Y) c8 o6 i; l# r! p 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
9 p; b; M8 ~2 H2 g* \ function makeRange($length) {
3 K. K3 W5 g# w0 {* U for ($i = 0; $i < $length; $i++) {' L. q+ g3 `, e r7 P8 i( I
yield $i;+ }: B+ g* a0 b% P6 e2 ]% ?
}, a o# [2 z1 U% {: d: Q& y2 d8 c
}- M& N3 r6 r" p1 w' z- L. J" s7 c
foreach(makeRange(1000000) as $i) {
7 a4 ~! h' Z* c$ X6 R echo $i, PHP_EOL;; h7 J3 C! Z+ F+ M! T4 {3 k$ b* p, ~
}
! f$ z1 d/ D6 e 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
, N' @% c; o( y3 g; M% f function getRows($file) {+ ~+ y; k0 ^1 z7 n
$handle = fopen($file, 'rb');
) T: {; e$ N7 ^ if ($handle === false) {8 Q! D* Q y4 p4 E
throw new Exception();
; }* {" h& L# i- q& N }/ Q; Z4 L, g% p( `6 D
//feof()函数检测是否到达文件末尾% B) [* ]0 f' l' F0 g1 \
while (feof($handle) === false) {8 C J1 V: e! d# T! a w
//fgetcsv()一次读取csv文件的一行
. Q2 e3 ]: `& j! a1 U yield fgetcsv($handle);
1 U0 G6 K$ t* S2 I6 o, B }2 C* X9 S" G3 A) A- g- G
fclose($handle)9 R+ x( | W. `
}
5 c9 P, k% B# g5 [' N foreach (getRows('data.csv') as $row) {3 y5 W* H0 T) l( d
print_r($row);% @! ? H1 a/ o, ?$ M' R! m
}; g* \1 r% K2 Y; q) w) t6 Z
3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
. x) {$ s4 w4 Q1 Q
5 X# w2 T" T& Z: Z
+ S: Z2 @2 Z6 Q) `% E6 t- }来源:稀土掘金 |
|