|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
9 T8 c, |0 A* ~1 k" f8 ^* O 1.命名空间
; e: K p2 p$ x2 [6 B/ }) ~/ b0 \ 命名空间是什么?
2 e$ s6 ]- B2 H2 v5 C( L7 G 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。) ?' A2 t7 v7 Q) {
2).命名空间始终应该在<?php标签的下面一行。
; o5 S7 b- E" Q. m# m7 r 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
$ O$ b6 _' u( j K2 S+ u 4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
' w- X1 H+ p& f: o7 e0 b- M: i 为什么需要命名空间?+ A; k# y/ ~+ R* g4 x9 B+ t7 c1 m
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
9 ~2 v1 m; b/ p+ T 声明命名空间/ n: a( w) o5 [4 R+ F ^ Q( y6 L
1).顶层命名空间经常用于设定顶层厂商名。: O1 O2 M5 [. Q B6 D) x! O1 E; U5 Y
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
8 w! V$ Y. X' Q4 k& ]5 K2 P 导入和别名: @2 L" O1 \% M5 }
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
8 r0 i( Z0 s* Q3 P9 k9 h 2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
- f; `/ ^ K& t K" |/ F' D. C 从PHP5.6开始我们可以导入函数和常量。% W! {" f$ ]8 R* y0 X
<?phpuse func Namespace\functionName;$ ^8 A& ^/ U/ r
functionName();
4 B# ?/ w" E* j: A+ L4 g. R 也可以导入常量,, k' B2 S# ~' S5 m, U0 }2 \
use constant Namespace\CONS_NAME;3 J) W1 T/ }) L3 s
echo CONS_NAME;
0 {8 e1 `; B% `+ b: Y 函数和常量的别名与类名的创建方式一样。
+ `4 @7 }' N+ G4 m 最佳实践 J! Q+ N4 R$ z1 r: H' r: N
1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。* K% W" a0 a1 T. x' |+ P, @
2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。' S. B4 w% G, ?
自动加载
, ]+ @/ q" ?+ _9 X( s: k, G 1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。$ X# c7 J; I( U( R( k$ Z( ~% F
2.使用接口 L( {% W6 }# i( [
1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
$ U& Y5 I1 N5 z6 b0 g! _ 3.性状: | c# X; c; [0 H% ^) y3 p
1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。, K) J6 I! ]; d. m: T8 ^
2).性状使得两个无关的类可以使用相同属性和方法。
% D4 T, M, s; V" d$ o4 | 3).PHP解释器会把性状复制粘贴到类的定义体中。
) G; B9 a, E3 P 4.创建生成器0 t4 I4 D4 _: L) e5 |$ t
1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
& L1 ^ u/ t) z5 Q! ?9 I, p! i+ T <?phpfunction myGenerator() {: v* J$ @8 O" E* C! D
yield 'value1';
* c; W: `/ z$ l0 |# v yield 'value2';+ K- D H, N5 V: V1 _6 v
}
) r- q" w8 G: Y 调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
: w1 {: X2 w3 t7 `) `1 Z1 a& G <?phpforeach (myGenerator() as $yieldedValue) {
; E$ u6 i& v+ P7 w% A echo $yieldedValue, PHP_EOL;. p5 L. r S( k9 X
}
& [# U( [+ }$ c 以上例子会输出 {/ i& z! ]% b' P! v
value1
( F9 H) u0 P1 R8 o$ b4 w2 J7 Z value2
" U& ~' d" O+ X! o% d/ Y& E 2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
. l! @7 `' B3 s1 h. n: V function makeRange($length) {' b5 ^1 y6 ]- }8 {$ H2 ~9 i
$dataset = [];
; K7 G" w1 Q: K3 Z# ] for ($i=0; $i < $length; $i++) {
7 S7 F( M8 i- P# { $dataset[] = $i;# V7 m5 r# }2 z- L# O, i# ^! c$ h; M
}4 L5 l3 F/ q- v
return $dataset;/ L1 ~0 _& f1 \# V; `4 X7 T" C
}* H" R# S* w9 h* O3 p. B
$customRange = makeRange(1000000);foreach ($customeRange as $i) {
- u. i7 u. t: h3 z0 ? echo $i, PHP_EOL;( g4 l# m& F7 D6 W+ p$ H
}$ l7 l2 ]4 k! C* q$ \8 B+ F% i5 O8 h5 j
预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。6 `6 g Q1 g4 y" r- _* D
function makeRange($length) {) ?; c* U, }; ]! J
for ($i = 0; $i < $length; $i++) {( C3 e& W* |: [
yield $i;, q9 X! l8 A: j; O& o1 \0 i
}
9 E) L2 m3 ^9 V/ f3 Q }
! b) m0 k @7 W8 L) {- o0 m; ~ foreach(makeRange(1000000) as $i) {3 p' ^ f( T* C* q- k+ X
echo $i, PHP_EOL;8 o" E9 F# D* O( |& {
}
k( ?# V; B+ |: E0 b 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
% H8 b! H0 R4 W" N8 j" @ function getRows($file) {
( n+ _7 E; ]& j) a $handle = fopen($file, 'rb');6 k* }/ u! F7 ^$ g% z- {: y' w# a
if ($handle === false) {
" e8 p% h. k5 S' N+ r throw new Exception();
& ]- P0 D4 B+ R, w+ T3 s( e# h2 V& E }
9 q, j; w; j& N7 K: a" O1 s //feof()函数检测是否到达文件末尾/ @6 O! }1 L* d" Z7 e9 v
while (feof($handle) === false) {
% ^8 w* F1 m! R/ E i //fgetcsv()一次读取csv文件的一行
0 L9 s( X1 l- w# c yield fgetcsv($handle);% ~+ z' w; o8 c+ |0 |
}
e) S9 H( k. k) J$ f6 [) G% L) L fclose($handle)2 w3 _5 o. u+ r9 `$ r, u G' v
}+ d' t1 v* c$ S2 d$ N$ u
foreach (getRows('data.csv') as $row) {& l% W) m7 N; ?0 y$ G# `" f( O
print_r($row);' F8 ?. v% G; h" }; G4 a) {' Z
}
1 i4 t- V$ V4 S X/ a! m 3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。/ A/ y1 E7 j: e2 T7 K
; r! ~1 u) C4 P8 d! z F7 b, t
: H, \8 r$ m N& O) t来源:稀土掘金 |
|