|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
3 `! z1 z# w$ k. S% N, d9 O( e 1.命名空间
% k9 C6 ]7 j' j7 m 命名空间是什么?
$ z( s9 v# b7 e: y) O 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
1 M9 a+ ~+ A1 ^6 x 2).命名空间始终应该在<?php标签的下面一行。4 x- K( g Q x8 E. ^) p7 O1 e
3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
0 N0 }7 E$ @$ E- C+ r: s& X# `, D 4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
8 {$ i6 H9 ?1 U6 c: d0 | 为什么需要命名空间?
$ }2 z( b1 w2 F2 s0 c0 E9 ` 1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
$ W$ ?+ g) @% h- H- D6 x9 O+ O, @ 声明命名空间
% K7 k4 C& D B; v; ~ 1).顶层命名空间经常用于设定顶层厂商名。
+ H& t2 [- B/ m7 e* z 2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
4 H1 ^3 H8 {, ?" r+ m 导入和别名
8 {9 |; a& x- h$ C 1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。$ W2 h% b% |$ b. l+ L
2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
+ N; l) D0 {, y6 b' c/ n 从PHP5.6开始我们可以导入函数和常量。9 W7 e6 E7 l( Y( g5 w
<?phpuse func Namespace\functionName;
& w: o( R( ]" a/ I6 v' T functionName();
+ e: ]5 z' n; J- a9 B) @1 L; V 也可以导入常量,
: f4 d+ `2 N3 w, m use constant Namespace\CONS_NAME;% B$ C# @4 |0 X8 d _) k/ } ?4 M
echo CONS_NAME;/ t( X% ~- t* {
函数和常量的别名与类名的创建方式一样。
9 M4 G) I6 E/ F/ h8 @. P9 s L* Z 最佳实践
# U* Q1 @- S9 P) Z: z6 } 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。1 s4 ?; e6 V, m; J& e& q4 a8 c& W
2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
! z& _/ I9 |4 g/ }3 a, K6 y 自动加载5 _& K x, p+ j0 ~$ i+ ^
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
- j) P7 b& S j2 T 2.使用接口
4 {9 l; T. M- k) K3 z) |4 E3 }8 A 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。) D& P; ?# j- _# R6 j+ ]* I0 h
3.性状" o5 j8 ]$ ?# f4 F
1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
0 [" K @& e" }" z9 x( B 2).性状使得两个无关的类可以使用相同属性和方法。
4 N& u1 F+ b& [# y9 y 3).PHP解释器会把性状复制粘贴到类的定义体中。
/ O, m, u2 q/ i- H( S 4.创建生成器' @: y- \7 C1 `. V
1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:5 {' ^# o5 D: y2 c; ]" O- x
<?phpfunction myGenerator() { T; k) F( z6 P5 R9 v( z+ K" r
yield 'value1';
4 E* o" q8 P9 w) U yield 'value2';
+ k8 H; R/ E. K5 V! l4 `% X1 G }/ e: w+ V; |" [/ x6 T* G/ z; _- z
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
5 w7 y1 L* b$ q+ _ <?phpforeach (myGenerator() as $yieldedValue) {. f' Z: z$ t6 q' k; U
echo $yieldedValue, PHP_EOL;9 h0 ~' W' E [) U' Q7 A" \2 y
}
% a# ^$ r5 u) v* y$ T' X 以上例子会输出
+ H0 s+ t) h: | value1
+ F5 Q" _: Q/ I5 `( N- T value2% Y% b9 L" w2 B+ [5 Q1 a
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
# a9 N; S w3 D6 `! n function makeRange($length) {: \: `- g7 f% t/ z. B
$dataset = [];
+ }& R s; l) s0 M5 d for ($i=0; $i < $length; $i++) {9 u- J* k7 V( V4 S
$dataset[] = $i;
6 @6 k, v% A5 o. E- E8 X. p }/ v! a( `6 h4 l- g, p+ x8 p& y
return $dataset;" w7 d% a+ }# s9 t7 }
}
+ r8 ?3 Y* G4 u9 r; M$ } $customRange = makeRange(1000000);foreach ($customeRange as $i) {' o! ^2 f9 a0 [. ~' V$ w. j. W5 X) ]* d
echo $i, PHP_EOL;& J5 ^" U F& W
}
6 b; J( p2 D! G7 b' Z% V 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
; m3 k8 b. P5 ~8 E% w0 t function makeRange($length) {+ t+ l9 s! G0 t1 h% E- Z) [3 Z* X
for ($i = 0; $i < $length; $i++) {
4 H& B; W. U9 q; P L yield $i;
4 d; h* W) u5 }$ U$ ~ }
5 B- B/ G& h, Z; T. v0 t }
1 ` k" ]; k: W9 F1 S+ p foreach(makeRange(1000000) as $i) {
, U: M: v- Z$ {3 p echo $i, PHP_EOL;
) w1 e- x, q4 D! [; n7 _# J }( l+ f- K" l( Y2 k# R3 J! b. P. Y
在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。+ {6 f7 x9 p' G' ^; k; m
function getRows($file) {7 R$ w! [% I1 U- l- O- A$ `
$handle = fopen($file, 'rb');4 `) J a; r6 S# C; _% K; ]& e
if ($handle === false) {
. w/ X/ q9 C4 C5 F: a throw new Exception();- q1 m0 x ]' l6 j
}* j4 ~( X: s; x- r, F% I1 d
//feof()函数检测是否到达文件末尾
|3 Z& _ |7 C, g. l( b2 @ while (feof($handle) === false) {
! r; ?* S7 `5 P5 V* g. J8 P, H //fgetcsv()一次读取csv文件的一行
* R, f/ l2 z# `! L! W; k! ?! z yield fgetcsv($handle);+ }8 g, }8 A8 S7 R. K8 ~+ b
}- ^. Y1 L# R0 y$ F
fclose($handle)+ J+ _4 I, V# u( m8 Q
}& m/ n' X' `/ t" Y4 N; e- G# T6 ?2 n- V
foreach (getRows('data.csv') as $row) {
8 e0 k4 x% l8 m' P print_r($row);
. V7 j1 l/ r1 r4 i, F6 s. i6 u }; Y2 W5 N; N( A+ V
3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
+ h E: b0 @6 o( h- u1 k5 j3 H4 U9 @ Z0 s" o; V
% N2 L) V/ b7 w F% \来源:稀土掘金 |
|