|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
; {9 a( x% h# |& Q! V 1.命名空间2 I! h: Y2 @8 ~6 p Z4 L
命名空间是什么?
- j4 G' x V- g3 P6 ` 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。4 Q( H) b/ d1 s. D) R. ?, D
2).命名空间始终应该在<?php标签的下面一行。
! R$ j2 `* p- ]1 a, S 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。2 J) w1 G% q( J, _" N/ ]
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
A q3 B6 X9 e; s$ d: }' b 为什么需要命名空间?
6 H) g5 D- F9 p! a3 H; `* N 1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。1 a" \, v, L2 C% e
声明命名空间9 J4 l3 A, d( \6 o7 v) H3 w# `
1).顶层命名空间经常用于设定顶层厂商名。
4 G$ n. i+ E8 {( I/ ~& ?+ g A 2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。. A, b; E3 D0 y8 G! `+ c
导入和别名& f5 B7 C5 @$ _: o1 ~2 r
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。. g/ l0 a# g6 P0 y: }1 a& X6 t6 `$ O
2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。8 R* ]& E; V" q% n y
从PHP5.6开始我们可以导入函数和常量。; U7 ]; k4 i' A) M% [
<?phpuse func Namespace\functionName;4 k# D8 H7 R" K# ^7 f
functionName();
6 C- V. h. m0 H, Z6 A. N 也可以导入常量,
0 h1 `: H0 \/ f! G3 M use constant Namespace\CONS_NAME;& [. V9 r/ T* p: o; u, K9 f, |+ a
echo CONS_NAME;7 y: [, N/ J1 I) p% d
函数和常量的别名与类名的创建方式一样。: ^1 a/ w4 a4 b. n/ d
最佳实践
/ T `9 G% W$ | 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
0 d( l& S* x! b/ I! P; I 2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
+ O$ m# V( ^) D- [5 m+ C: ? 自动加载# R* k: O/ ^, N* G, X% w: L
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。8 k9 |+ W! y6 N1 |% r- d' D+ R; J
2.使用接口
0 C$ C4 N, V% }# S1 u 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
4 _; H* j/ w. e, V+ C" ]9 q 3.性状
: m) T. I+ G# t) y. C/ l 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
7 n2 T9 `0 k1 F 2).性状使得两个无关的类可以使用相同属性和方法。! F# A: i6 A# w7 `) d4 `8 g- H" R
3).PHP解释器会把性状复制粘贴到类的定义体中。8 G. {* r/ \+ U2 t
4.创建生成器
, N# r1 r' W; B- y) ?, `7 l/ V/ ` 1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
- |! I- N$ x$ c+ d1 S <?phpfunction myGenerator() {0 [" _9 W+ ~# v$ C% q( L. D$ t
yield 'value1';
+ O: s. G: L$ z: ^/ ~$ b9 N1 o! B yield 'value2';' J$ O. H+ v8 _1 t
}. X5 p ?6 E% z- j
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:! u3 j. ^5 A3 U# o
<?phpforeach (myGenerator() as $yieldedValue) {
" n3 @$ s1 l. P6 D- Y! T8 _# B" [ echo $yieldedValue, PHP_EOL;
: U' n' i7 @3 @! G& k }
# X3 e9 X% Y/ I# T, o 以上例子会输出# n/ I6 c3 Q2 R9 u' n+ v/ Q4 I
value1
$ ~* e! t3 b+ t/ P3 i9 r value2* {1 j: h* S4 h2 b# `. w( M" y
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
! c2 D$ T" u" L* z! d function makeRange($length) {" S/ Q z# x& q( k5 q2 _6 i
$dataset = [];
! `! X: [( h" |+ K3 n) k: Y for ($i=0; $i < $length; $i++) {6 S. Z5 i# v! Z
$dataset[] = $i;# s2 G* _. r+ D0 O6 C
}
0 J) ~# K% k) ~/ L return $dataset;
; J0 R! ?) B$ q5 v }
) o X8 x+ j* i; ^- E& B$ {+ ]8 a $customRange = makeRange(1000000);foreach ($customeRange as $i) {
. ?: w, H6 C( ~7 u2 N$ ?: w3 C8 v echo $i, PHP_EOL;; l9 }* a& p' w( q+ \* U7 ^
}
, s; J( H7 ~# H( T 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
8 x. f, T: ]3 z& ]5 I3 E function makeRange($length) {6 p' k. R* ^1 H7 ]9 x* w- D
for ($i = 0; $i < $length; $i++) {- ], C0 a- l% E( I
yield $i;( b2 l) T7 \. y5 \2 A E; I
}
' |9 D; o' ]) v/ w7 H; B$ y }
, N8 [2 M: \" k! j+ j& Q3 g foreach(makeRange(1000000) as $i) {% G0 d1 O$ Z5 s8 m$ }8 e: O
echo $i, PHP_EOL;
. F& O7 [/ f0 X ] [1 j. u }
* B5 t) y |! t1 i D 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
9 O* s- Z+ t* n+ E9 } function getRows($file) {( Q; Z9 M9 a0 Y
$handle = fopen($file, 'rb');% {7 M( I( f% ^1 s3 y1 A3 H" F
if ($handle === false) {3 H6 y* Y* w7 z8 |9 g2 H
throw new Exception();
$ O3 z9 _- p% x( Q* i }
M8 d) A4 ~4 A( } //feof()函数检测是否到达文件末尾% o( }; {4 f5 ?) c- a( |
while (feof($handle) === false) {! U5 T) K/ R. F& a) e
//fgetcsv()一次读取csv文件的一行5 Q' m4 U( W; A0 T
yield fgetcsv($handle);
% O0 w7 @" ]5 v( _3 T; P }
) x- t+ n6 E0 [* a fclose($handle)
, \: f+ p O) e4 B }6 h. P/ z- W b; U+ P& d) U% K
foreach (getRows('data.csv') as $row) {- p% F+ h% Z% C8 {& I" \: C
print_r($row);
' x+ f1 P" `/ C" ?9 y0 E* X5 S }
6 Q! @$ Q( x: G' n; M# ~ 3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
$ n! U& x9 y$ r4 u! Z' p/ G6 c
1 I5 D2 M) F/ I; R/ F$ F5 v4 A8 r4 x! A
来源:稀土掘金 |
|