|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
% A: p2 ~$ b' e+ U0 @' c4 _ 1.命名空间
' k8 c5 p" m( { 命名空间是什么?
1 O6 }# F9 X, k+ f5 x0 c# r5 ` 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
7 G$ ?2 P' ]5 B+ v8 m 2).命名空间始终应该在<?php标签的下面一行。
. [& b7 k1 X. A$ H4 {$ O 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。2 G' Y6 F1 J/ J9 g. O/ X7 e
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。' ?% X" M! X5 s2 W T/ Z
为什么需要命名空间?' Z# R5 e& j8 S( l, S2 \
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
e: C5 y( t' `. _. [; m$ S 声明命名空间8 O! N, _" u9 y0 w* h8 a% d
1).顶层命名空间经常用于设定顶层厂商名。
4 E, t( O [/ P _3 _7 G2 S 2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。. U0 r' [2 c0 ^" o+ B
导入和别名
5 B0 n/ v& K% T3 ]; p 1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
8 {9 s( \ f$ U* M9 F3 i$ _7 N3 G8 M 2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。, p, Q e# ]4 h/ P
从PHP5.6开始我们可以导入函数和常量。9 }' x1 ^/ d+ n: K( U
<?phpuse func Namespace\functionName;
; a' ?5 c1 a/ X; P% A functionName();& D4 h0 C. I/ m
也可以导入常量,. n8 R" w; h5 J: v
use constant Namespace\CONS_NAME;
5 n: E) q2 X" N2 ^7 B echo CONS_NAME;
' W! B. Y6 ~& z* o 函数和常量的别名与类名的创建方式一样。, y N4 Z" m. W' ]7 P
最佳实践
) T$ {( z1 ]% W 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。/ ^2 X$ A* Z8 p, ]# j8 v: B( S
2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。4 Y I3 }* f0 Q$ q8 g
自动加载! R" [* B5 ~! i4 D/ H. b3 U
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。3 {! g* N- h1 H, ^- i+ G5 i- _ X
2.使用接口
_0 b' `1 x n+ C1 k 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
; H! e; U2 ]8 w$ s+ x 3.性状! Q$ H1 {/ d4 l# T; L. K4 w1 F& t
1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
7 D/ i. m) p/ M2 Q 2).性状使得两个无关的类可以使用相同属性和方法。0 z5 i# |( t* d* }
3).PHP解释器会把性状复制粘贴到类的定义体中。
. u" O0 b: e6 k+ p% j 4.创建生成器
3 g1 Q% F9 {) i" T( W2 C- z 1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
' Z/ F- B2 n3 L/ Q! q <?phpfunction myGenerator() {! C4 I( ^5 ?: l! F
yield 'value1';
: ^8 A j% o/ h* ~/ p2 j yield 'value2';
9 i) F+ H9 V1 Z }! {+ }' b2 ?9 O0 `/ X
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
) v5 F& |- J; {" U; b# ^( ]4 F; T1 L <?phpforeach (myGenerator() as $yieldedValue) {
* F& I- O* e- U8 a y, w echo $yieldedValue, PHP_EOL;
) e- B/ d! x7 e) [ }
* q( A! \: f \ P+ s3 N 以上例子会输出
( A5 s" _& G+ I L& T9 {4 [& v value1
/ T& P1 b3 \0 Y5 j4 c4 |! G9 b value2
; L9 @1 m ?$ A: v0 [. b 2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
) s: F/ P" P" z4 [1 u! {/ i5 p* c% w8 l function makeRange($length) {9 H" o) p" `& j6 m' I
$dataset = [];
/ t! l5 _4 R7 S1 b* V7 g for ($i=0; $i < $length; $i++) {$ K& A& y6 W9 A R: a g( U1 r
$dataset[] = $i;# n* x, M/ c. w# e" o* G
}; @) b0 N( X+ \
return $dataset;
m( Q- z6 [3 `3 W/ j7 g. n, R }1 `5 s% u' p) g% L* j/ u" x
$customRange = makeRange(1000000);foreach ($customeRange as $i) {
% P, o5 v: @2 }2 P( a/ b/ }( v* l echo $i, PHP_EOL;
' [& M% l; P! {9 n3 [& [' F) C' o$ {& G }7 b- \; n& y& o
预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。! Y9 U) l, ]5 C
function makeRange($length) {! A+ x$ D0 ?, v$ W; [
for ($i = 0; $i < $length; $i++) {
; v) f. N! A! v S# z' y/ K% l yield $i;
& @' h$ O" q* i' m4 y }
$ x/ E2 {0 h+ Z" h }5 U/ H5 e1 X( A) j
foreach(makeRange(1000000) as $i) {
& }* S+ d3 X1 o$ m M echo $i, PHP_EOL;8 R) d9 L6 Z- k7 {0 x/ T+ K; q9 l5 u
}# H8 K8 G* |, E! z. N; Z' ?
在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
+ v/ s1 W2 V6 Z) K! i1 s9 w function getRows($file) {
9 M& ^2 ^+ E, s c ^: @ $handle = fopen($file, 'rb');+ { p: T. x. B, w
if ($handle === false) {
/ f" B9 K( V+ y: S throw new Exception();
, k, x/ z) R3 C0 f L7 `' w+ u: U9 i3 C }
( R: i5 L0 \: k( M( A X1 C) d //feof()函数检测是否到达文件末尾8 B/ N* R B4 A! W
while (feof($handle) === false) {' a' u6 S3 A7 M! k2 p
//fgetcsv()一次读取csv文件的一行6 F3 s6 J: Z6 N. a' C5 a7 s
yield fgetcsv($handle);
x1 b% Z+ W( V- e# k, b: Q }1 g3 t9 G" R( T7 a2 X, `! d
fclose($handle)$ a& B/ C& S% J0 @2 |" S c6 P1 g
}2 Y7 j: w. X1 N b
foreach (getRows('data.csv') as $row) {
( W( W$ J6 H. D+ n7 u* w print_r($row);
0 q; s( T0 ~. C \; o& I }
; ^" y) p( P7 c$ g9 w2 m' k 3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
9 j" ?* s5 L% x$ Q
/ N& \7 O# ^- R% c: X3 {
: Q* J( y- q+ ]& Q3 A来源:稀土掘金 |
|