|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。( ~. A( @/ p. {1 ^
1.命名空间
6 s: f; I: r9 V0 i: {6 r 命名空间是什么?
6 t1 c- P- c- V m- A- _ 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
d8 }1 G! t& K& k; e% n( `* L 2).命名空间始终应该在<?php标签的下面一行。) N" D8 I) \8 c8 F7 h8 h7 r q
3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。, }# k* }& Q& I0 z
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
& g8 }: F" |2 O$ W 为什么需要命名空间?' O8 ]' y# T: d
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。* Y+ D7 Q* T5 e! I/ d
声明命名空间
' }& b% `% v: b- k* z 1).顶层命名空间经常用于设定顶层厂商名。
: t9 V, j3 H2 w# I/ I& I, m- E 2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
* H- q& l' B' G. L9 [. \ 导入和别名8 a: o0 x* I' w G
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
$ j3 J! m6 Y8 [8 K# r6 x 2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
! C/ |( |/ J7 t 从PHP5.6开始我们可以导入函数和常量。, j% I( Z; @% t7 _: w
<?phpuse func Namespace\functionName;
5 h- e& C& \# |7 { functionName();
' ^0 I5 }+ ?, z+ E" Q, S( L 也可以导入常量,
: y! {/ \: F+ u( V: Y6 I% T( F use constant Namespace\CONS_NAME;
6 Q+ @! Z" j. k& W1 F echo CONS_NAME;
$ f: I/ l5 j( H% C& U0 ^; ?# b 函数和常量的别名与类名的创建方式一样。
+ k: l6 }: A8 h7 x9 \ 最佳实践
& h( L9 `( L1 G) F3 w$ Y 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。, S5 {8 q) U' \1 x, t" Q2 g
2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
8 [3 N& K5 n; f5 J7 e 自动加载
& ^/ }; p2 {1 l" x- d, K1 d 1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
8 v% B% \8 r& z* A4 V 2.使用接口
c& _7 r. h/ [ 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
" c# B; o# r* z1 M7 u 3.性状% H% l, O+ D# k6 J- v
1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
6 S$ C' w- T7 m. O% H; ^ 2).性状使得两个无关的类可以使用相同属性和方法。, y/ H1 z: |8 W* Z7 A# e
3).PHP解释器会把性状复制粘贴到类的定义体中。/ o$ R. }) N9 b; h; N. l& `
4.创建生成器! o7 E, {) X6 ^. } t" O
1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:1 z* }* r' s, T; U
<?phpfunction myGenerator() {; V5 T/ x* |+ T) N
yield 'value1';
; b/ w# S# O% {9 Y/ b) @ yield 'value2';
, d4 \* h- E$ y. R6 j- y' A }8 j4 ~: K- d' T/ z
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:! r7 S$ B) ?$ q# a4 w& r, ~
<?phpforeach (myGenerator() as $yieldedValue) { d3 q7 k6 A2 n
echo $yieldedValue, PHP_EOL;6 i7 c2 d. g6 j6 G6 t
}
$ }" H6 l' m/ I0 Y 以上例子会输出
, I0 O( K$ \* v value17 i. A4 ^* O% ]. {0 j0 u2 q
value2+ c# |( K5 o: E( F; p( R
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
+ ~7 @! H+ R/ c" ^4 H5 l0 ` function makeRange($length) {6 \" K/ n- n" o' L
$dataset = [];
# I/ X4 M$ f( U) h' G; K% x0 j for ($i=0; $i < $length; $i++) {5 i) k: Z5 m9 ~( o8 T8 P* q
$dataset[] = $i;2 s% `4 Z' g3 C; j8 {3 d+ q/ g
}
- D; J! I# m t: q return $dataset;
2 r. A) U ~0 O/ ^/ r }- [0 l9 S" d) P
$customRange = makeRange(1000000);foreach ($customeRange as $i) {
: l Q3 f1 n m5 C; _5 U! J echo $i, PHP_EOL;
( j: R) ~& G$ @( ]% q0 n }
( R1 a# y2 z$ X: V$ H* F" L 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
o" ?4 O0 U2 A function makeRange($length) {* K, N$ q/ I- b% }$ o3 o2 [
for ($i = 0; $i < $length; $i++) {
% ~7 ?+ ~ k/ }* d* w- X& x3 o% o5 c yield $i;
* P' E+ @+ b1 i) C6 A }
- O0 k1 l- S8 y* H) o }
0 x5 x6 R9 \3 J7 Y3 G6 `2 w: P9 j+ I- K foreach(makeRange(1000000) as $i) {
" n) `0 H2 A; I8 P! E echo $i, PHP_EOL;; E2 ?% I9 Y1 g" t( n5 [3 U
}
. r& z8 B8 {: G L+ s( S' C 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。# Z' T: T8 s# e$ e- R
function getRows($file) {' o3 S, Y! {6 g0 ~& Q3 g- K, Q
$handle = fopen($file, 'rb');
6 G# @" J" G4 S1 B, L0 N4 j. [ if ($handle === false) {1 g- u: V3 d( e! h; V/ E
throw new Exception();
4 B8 y: C- `( K. n( o6 O3 @) l }" @9 O6 k/ ? r7 q; o, U
//feof()函数检测是否到达文件末尾7 O& o; h2 U2 D* V
while (feof($handle) === false) {. u6 J1 p6 b" k
//fgetcsv()一次读取csv文件的一行
9 l, w$ E4 ~$ I yield fgetcsv($handle);
& x4 r' ]3 A3 m6 R* C( ^ }: R, M" _6 r! i, Z3 p1 I" ]& i
fclose($handle)" E1 G4 t$ O9 V7 s- _" ?; f
}, M+ }# J. O% R# Z
foreach (getRows('data.csv') as $row) {
z) _; Q* g7 \) ~ print_r($row);2 w. S+ |6 D7 |4 B" Z: \
}* d, M) x% ]" h- E8 q' h( _
3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。7 A a1 A( u S4 a
5 i5 a' a0 m% r2 E7 M5 P/ c, D/ t
6 o0 W3 J' u7 ?. X1 s7 @, y
来源:稀土掘金 |
|