|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
1 Y0 }7 I! g0 ]# v6 B' M 1.命名空间
$ s4 Q$ u' n* M, K) o t! f2 X# l c 命名空间是什么?
9 x5 G- m+ {9 U' [8 h1 }# m 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
8 ^! z7 G* u) t. L ?! n2 @6 d 2).命名空间始终应该在<?php标签的下面一行。. Z9 M, n% x8 v( p
3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。0 |& J2 o, K/ l' @5 D: u
4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。4 _: J# Z! ~! g. Y
为什么需要命名空间?, Y. E: l/ }; b3 {4 W
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
1 O) n9 q* l2 b' Q1 i 声明命名空间
2 P8 \9 `) O/ L6 a$ h% q4 A 1).顶层命名空间经常用于设定顶层厂商名。
# ~5 g( e* [" v/ P* p- I6 i) A 2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。% i7 T T% t/ w t
导入和别名
. u! L# n0 F$ G$ M 1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。! k1 O0 c& m" v% t1 }: m' m6 G
2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
* p _+ X) G; v- g 从PHP5.6开始我们可以导入函数和常量。
' A8 k9 L0 r; _: d7 U" w1 ? <?phpuse func Namespace\functionName;
7 L U- z! m/ {1 I' ^/ m& z: O) P2 y functionName();
~" Z; n3 {7 i 也可以导入常量,1 p4 S! F h! s- ^
use constant Namespace\CONS_NAME;% K8 O2 N5 ?' f9 B0 b3 H/ Z- m3 l
echo CONS_NAME;
, F4 z5 {9 e M& @, l. C& ~( T) z 函数和常量的别名与类名的创建方式一样。$ H- h4 N6 N A+ \9 s+ X
最佳实践6 F \; s6 d' q' Q& {: y
1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。# x: R" z5 C8 l0 e
2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
% M% M8 {3 v5 H1 r0 v A8 c* ~4 z2 E 自动加载
% ~/ h! I5 U |! o 1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。6 a! j+ g6 ]/ Q- c, d
2.使用接口
9 m0 ]) N2 l- o( o 1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
+ k# [1 ?4 ~% l& s3 N i3 C7 Y" S2 z 3.性状# `9 |9 ]/ r- r0 b0 `- V8 O
1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。9 Y7 a+ H" L( l9 H
2).性状使得两个无关的类可以使用相同属性和方法。
) a: `" k, @/ Q$ T4 y) T& }) B& Z 3).PHP解释器会把性状复制粘贴到类的定义体中。
. u1 {+ F- z1 `7 i1 j. V& G/ L 4.创建生成器6 M- \; X, M+ k# R+ c
1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
' p- @- w4 d& { <?phpfunction myGenerator() {! i3 [& B: N5 e# \- }) d
yield 'value1';8 X! U6 g! p( i9 ^3 L- H9 \
yield 'value2';
2 R }0 H/ m- T. g- a9 ? }
' S! H& K M4 `+ E4 z$ s 调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:: s$ S+ I0 ~7 q2 Z
<?phpforeach (myGenerator() as $yieldedValue) {8 A2 E, H6 b g* N" L: A( f
echo $yieldedValue, PHP_EOL;. T0 r& h$ t7 ]3 t7 \3 b8 y, D ~
}
( C+ s2 y1 H2 P 以上例子会输出/ M$ f2 C5 |# e9 ^; A
value1
! }# T: Y7 D. a, d" Z* c4 U value2* V3 W O3 F- `' {% o0 Q
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)2 f5 h3 x3 @) s( e% {
function makeRange($length) {. B! w; a: S; ^0 {$ v
$dataset = [];8 N: o* Y* W4 k0 M' v, n
for ($i=0; $i < $length; $i++) {
( z: O' w! i7 g $dataset[] = $i;: T1 h+ A; w. [( l+ o
}0 \) g* |6 P+ l4 n, e
return $dataset;: J- d/ p, d* C+ k2 U. r; |+ J5 ?
}7 {6 \8 ^1 y& E8 L* a
$customRange = makeRange(1000000);foreach ($customeRange as $i) {: @$ j' l5 W4 Y
echo $i, PHP_EOL;+ g& I, \% ^, ]2 L& G1 n h
}
2 T9 s- ?' T% }. L# s% b7 L 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。! g, f4 t. B* G$ w
function makeRange($length) {
0 L6 C6 p D% h$ X: a2 V9 p for ($i = 0; $i < $length; $i++) {
: W4 B5 H( G2 J. Q: y0 x. ~3 \ yield $i;
4 \1 ^1 Q* d. ^: P. a }
# b: X& x& j+ |9 f" h! G }
U5 a2 M l6 P4 `$ x foreach(makeRange(1000000) as $i) {
% \6 r+ ~ o) w5 |: G4 n$ x echo $i, PHP_EOL;
. U0 s8 P3 V, e0 l6 h4 n: e }
, N! ^3 o' } C, j0 {% `5 n+ y1 W# T 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
R+ T5 s S' B9 e* P) t function getRows($file) {
: a! T3 v6 ^2 I1 j# M9 j- ` $handle = fopen($file, 'rb');
9 j" r- @& P O) N6 m if ($handle === false) { S4 g: j! X s1 ~: O
throw new Exception();
/ H& o/ m. T; P( D. ? }8 p1 q; _4 y+ Y4 l# w
//feof()函数检测是否到达文件末尾
q' T9 V" r2 Z2 t# _ while (feof($handle) === false) {4 `* a. w# @$ ~# D$ Q* m
//fgetcsv()一次读取csv文件的一行 }; h) ~) r, ]; X
yield fgetcsv($handle);
4 B- o* {6 y* |+ u: J }
) x# D1 I; Q6 e$ F fclose($handle)
: o9 ]' o; ~; {# m' Y }5 p! b. ?' [" m# U# i
foreach (getRows('data.csv') as $row) {; d& W* n( Z0 k/ J
print_r($row);
' d: S/ h0 h d& s }
% u+ X3 g2 W: \5 h2 q: ]% p1 [ 3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
% v+ ?4 s. w8 ?$ I1 L
8 _2 b l+ o5 h3 Q
. z7 g8 Q( @ K. l* m7 Q; A来源:稀土掘金 |
|