|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。4 t$ F$ ~/ I( {, t* o! F
1.命名空间
6 T: M5 ~9 z9 @3 _! h 命名空间是什么?
$ w( \7 E; A+ U: g 1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。" H" I* \, W1 q
2).命名空间始终应该在<?php标签的下面一行。
7 ^, v" M, s2 D# j! N; t 3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
# X x" U2 w* h* P; I) Y4 P9 L 4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
% k1 W2 G1 j+ M4 ]2 O4 E 为什么需要命名空间?( m+ G9 |- |- u! p
1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。4 t1 u) |, j) O* w, `3 M1 Y( i J9 z
声明命名空间
2 ~9 L+ E7 ]4 ]$ e! H3 q 1).顶层命名空间经常用于设定顶层厂商名。! a% J# g' ^" }
2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。2 M1 ~2 p3 s8 e0 I
导入和别名
& V6 h3 J$ ]9 E) o& Y& I; U) n' ~ 1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
2 F; k) I8 I( I1 @$ c/ I 2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。 o" ~3 r# z$ `' g3 k+ H* R5 w
从PHP5.6开始我们可以导入函数和常量。1 c1 f. `8 C% O# ^4 [1 S- \
<?phpuse func Namespace\functionName;
& x" c/ w6 L I5 t% ? functionName();* c% U' d6 |& [+ {
也可以导入常量,% P1 q7 n& l9 H( W& c
use constant Namespace\CONS_NAME;9 K- H# A6 b" C# Z- P& t
echo CONS_NAME;
8 C' W* \$ O1 ]8 u( X* t) L! s 函数和常量的别名与类名的创建方式一样。( H5 f$ p2 u/ c2 s% z6 N7 ^7 r# j
最佳实践
( p' ~6 Z2 _. S1 \ 1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。) D8 B% s) ?9 I% a4 b
2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
5 U' n8 F# D+ O# [$ l8 }/ V( [% E 自动加载3 O5 W5 ]% Y- g. `1 n+ g* U
1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。" x# ? r+ X: w+ T ]+ ^' I- w
2.使用接口9 C$ W6 I5 n* `' l
1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。$ G, u) {$ q( c5 H% |+ y
3.性状
6 l5 N; m ?/ G1 @- @ y+ ` 1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。 h! M. ~- d2 u
2).性状使得两个无关的类可以使用相同属性和方法。
3 O* e' Z8 H# ]8 Y+ L 3).PHP解释器会把性状复制粘贴到类的定义体中。2 y- J( d) u' S# ?; V) \' s% G
4.创建生成器
3 {+ U5 p/ l& F6 S 1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:7 w) m3 `$ S1 c( Q2 o- t
<?phpfunction myGenerator() {
$ ]/ x3 M. ~- ~. J2 z9 E2 t4 ` yield 'value1';
0 h: ]4 x- j3 R2 g yield 'value2';
" P2 ]& Y5 a3 [. R" D }) E% n- J) S% |% A$ D
调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
( T- ~9 b+ o2 s& m3 q8 s5 o. y <?phpforeach (myGenerator() as $yieldedValue) {( C$ L2 C3 }7 o: ?) M2 b
echo $yieldedValue, PHP_EOL;2 d6 Q! N+ l) B! R
}( M# A" d3 J/ r( e' F4 W$ _
以上例子会输出
8 g% O' T( M8 U5 Z0 ^" ? value1
6 _3 P6 `0 U6 s7 g' C- n2 c/ V) o value2* y; y) w# O5 `7 Z0 \6 v# `
2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)1 c5 K& {& u# Z+ f" {0 ?
function makeRange($length) {
4 @7 K$ U8 f0 P" D& A $dataset = [];: m# _ R# ~8 M4 v& y* m' A1 G) t
for ($i=0; $i < $length; $i++) {/ X3 ?! `6 Y2 x7 w5 l# \8 c
$dataset[] = $i;- ]% k+ Y: w$ m
}
& l; y* v e: t) U* z! y return $dataset;
' ^. }9 d$ z- G9 g# g* T: T }3 h" B4 J( k( e5 H$ ?
$customRange = makeRange(1000000);foreach ($customeRange as $i) {8 q1 ]8 D9 l" h. z
echo $i, PHP_EOL;
# ^1 U k- Y7 M+ s$ t; x% \& B }
% u3 K' y1 x/ l 预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。9 G' R2 j# x* y5 X6 Y
function makeRange($length) {
& U9 b) _# B8 R. P, U for ($i = 0; $i < $length; $i++) {
5 s+ G! ]: L! }, y, Q1 f7 ~9 f( _( P yield $i;
, @# `) c- T& X7 A. ? }7 {3 h# U. D4 a1 J7 b% }5 I7 r- Q
}5 q* J8 B8 p; V: t
foreach(makeRange(1000000) as $i) {( Y" {% z: ~& U, j$ C |+ g
echo $i, PHP_EOL;
2 ^3 J5 F" |0 w& O% J( J }( t' n2 O! h7 W) Q4 Z9 [
在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
' ?( @ N* Y6 G) V( ?0 ^- U function getRows($file) {6 g4 W$ \1 b4 w# K
$handle = fopen($file, 'rb');# s8 @2 y4 E- Q P0 U
if ($handle === false) {1 K* n- |% w# a. _& h
throw new Exception();
0 P6 g5 m* g" K& x) u) K! _ }+ X: D# M* p' ?. B: s8 k6 y( R. x- e
//feof()函数检测是否到达文件末尾: E. P7 @* n0 B5 P6 e' Y$ K
while (feof($handle) === false) {: H! @; V% Y" o6 x2 w5 Z- ^
//fgetcsv()一次读取csv文件的一行
" p2 Y$ W0 t% h3 c0 E yield fgetcsv($handle);0 O! W% L/ W. a
}
# R) y6 M3 H7 {& D5 J fclose($handle)! ~ ~* ?: ?6 v4 u: r2 _) k) W5 a
}
$ k% K( T7 e4 y k* ] foreach (getRows('data.csv') as $row) {, U) u! ]) F6 l5 ^6 x- A8 e2 H
print_r($row);
1 Q5 q* ~# T- N$ d& K }
% l; G; A: T1 ? 3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。: s( a* ]+ W3 \. x( h4 U) {
1 }$ Y+ w$ a8 l) @5 H( W% @
& ~* E, T7 I. s" l8 D来源:稀土掘金 |
|