|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
6 }* d+ L/ p/ I' l n 1.命名空间0 @( ^1 V* ?. Y! }5 t" o9 O
命名空间是什么?2 M: n6 Z, s% j
1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
& G3 @% s1 Q8 M 2).命名空间始终应该在<?php标签的下面一行。
+ Q9 q1 }. v! I `5 H9 c' l9 V 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
0 y+ ?% \6 L: `0 j( V9 A9 p 4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。' f1 V) I0 w7 e S& z0 ~' P+ t' g3 @
为什么需要命名空间?1 @/ f0 ^8 Q; e# A" x; a
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
( d. ~. G+ a% B 声明命名空间$ g. y9 C1 p+ ?+ r
1).顶层命名空间经常用于设定顶层厂商名。- O+ x7 a& b, [8 D$ L
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
) j8 v& D: O- b, E: ]& J! m 导入和别名: K' k4 d" f' ?+ b1 L
1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。2 }& }6 Y, e2 `7 S% B% P5 B: \
2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
! X1 n' |- |5 T1 o8 R: F 从PHP5.6开始我们可以导入函数和常量。/ c9 p0 e' A1 t$ L1 f) C
<?phpuse func Namespace\functionName;6 A$ n9 e' ~$ ?& r8 p9 V% o
functionName();
$ q2 o: O) u; L, \ 也可以导入常量,, N9 r) F$ w0 g2 s7 f
use constant Namespace\CONS_NAME;: r; U. v- ^) k% s. H. g5 g# L
echo CONS_NAME;8 A$ }$ x; `" w$ X8 W- _ |6 P
函数和常量的别名与类名的创建方式一样。6 j+ Y! i s" H8 G1 U) }
最佳实践
/ G" t" ]- c2 a; T' l6 e 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。5 a4 P, M" [! H5 G% Z9 s
2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。, R, f8 }. \( b g5 K0 m% ^8 c' J
自动加载) _9 G, G- o$ E& L
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
" ^7 l5 Q' m1 U 2.使用接口( h/ |( f4 E) _9 M
1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
o$ {& ]$ I" t& k% i 3.性状
2 C7 S0 a F8 n, P; _ 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。. E" X6 W( g# ?' a8 l
2).性状使得两个无关的类可以使用相同属性和方法。
8 a' A0 b, m) O 3).PHP解释器会把性状复制粘贴到类的定义体中。
4 j# i$ \' A3 \! b 4.创建生成器
6 o, H" E( O& v' h2 }( j) b1 B 1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
; O3 v: C0 W. {6 g Z6 f) h) J <?phpfunction myGenerator() {. m) r- u" U) o$ Y
yield 'value1';
2 ?2 H5 b* [: p* ~" d S8 {' }! C yield 'value2';
7 O' z1 n+ v2 |0 H c) O7 k( ` }
9 L/ y U f2 s6 b, K M" b5 c 调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
$ N2 ]2 X7 S7 X( G <?phpforeach (myGenerator() as $yieldedValue) {! l8 T. K3 t' [" ?8 W
echo $yieldedValue, PHP_EOL;! P/ M" l) |! U, F5 N. G6 X4 G- J/ A
}% |) m# ?8 T8 p# v2 o8 w
以上例子会输出 @) i9 V/ _1 e* f4 P# f
value1
- L1 J% ~; d( g value2$ E/ m6 t, W% F$ w/ m7 n: Y6 L, M
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)) N( ^) L/ B+ j' @/ w
function makeRange($length) {) L8 G7 _7 I! Z, [/ Q0 a% r2 ]
$dataset = [];
0 t( m6 n5 L& Y: F for ($i=0; $i < $length; $i++) {: Y& Q1 ]7 r6 K* y- o
$dataset[] = $i;
I& N" M0 H& A! a# z6 w5 Q2 v } k ?2 Q! N, g4 M* {8 l$ V5 U" P ?
return $dataset;
; w, o7 |9 L: G0 v; {% t8 X }
$ h; l, X5 ^2 m6 `' I $customRange = makeRange(1000000);foreach ($customeRange as $i) {
: m$ R4 j9 ^6 s9 f6 Q echo $i, PHP_EOL;
3 V3 G* |# F6 ~+ y7 |5 ^ }2 V3 `8 E, w0 I- s% ]
预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。 v9 E3 a8 ]+ g) e
function makeRange($length) {
5 k5 g5 ]+ {3 d; A. a: i/ s; h7 r for ($i = 0; $i < $length; $i++) {
& W* e; ]. C7 N1 X% q% u, A; j s yield $i;
5 a- Q- G0 Q6 W }
3 `5 H; m, J% D) m- X7 P- ] }
- \8 j' e! B/ n, O5 h! S, T& n* W foreach(makeRange(1000000) as $i) {
9 L* e& _# a2 T+ n$ } echo $i, PHP_EOL;2 E, ?; V y# ^8 T' K) a/ v
}
) e' F3 r9 |5 Q5 J# r7 x 在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。, }# f1 v( f" p) n/ C* O4 r" t0 |+ J" `( ~
function getRows($file) {
& g/ T5 {5 h& Q3 n $handle = fopen($file, 'rb');/ G* h6 Y4 E4 p! ^9 s% m
if ($handle === false) {# z- h; R2 x) [$ ?. v
throw new Exception();
) {* r! P; `7 I) ^5 o. @ }3 |5 ~; F4 o* A7 v5 D! q$ K/ M, @7 E
//feof()函数检测是否到达文件末尾0 ^) d9 ^# a' e
while (feof($handle) === false) {
5 m/ `7 u0 v% y4 T/ W S //fgetcsv()一次读取csv文件的一行' V9 Y0 L9 K. u0 Z5 {" Y
yield fgetcsv($handle);
+ F$ X* \" m# g9 K* ?% q }
& b9 H- T# y% J- v0 d/ _3 h+ b fclose($handle)
. M& k! `1 O+ Z }
) ] g( K0 y C# e- ^6 z foreach (getRows('data.csv') as $row) {
4 l. }3 _! R A1 Q+ @; n4 q print_r($row);
* s: w7 k$ O: b2 W; F }' c3 r5 F2 m, T8 k# g
3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
( t# _/ k4 a, l4 y9 H: W$ X5 m& @# t
. W( [* D, ~( ?来源:稀土掘金 |
|