鱼C论坛

 找回密码
 立即注册
查看: 1676|回复: 0

Php学习之命名空间、性状和生成器详解

[复制链接]
发表于 2017-8-8 15:16:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
' ]' L' J) P0 [% N% x9 b! Y! n& D  1.命名空间2 k" O& U5 `6 m" n
  命名空间是什么?5 G2 _- b9 D* ^( t7 X& I
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
+ Q2 I5 B1 O& U! u  M  2).命名空间始终应该在<?php标签的下面一行。7 p7 F" {8 L7 u8 |, ~# G
  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
  @6 E* u5 O, s4 u1 I. s8 o  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。$ E1 l# S6 }+ X! y! @' \$ c
  为什么需要命名空间?
5 Z, Z/ W( M& I6 g* l3 K( _  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
4 K0 i2 H" |. `9 e/ R  声明命名空间5 c7 v8 X4 P7 A' S$ Q; U1 @
  1).顶层命名空间经常用于设定顶层厂商名。& x. Y3 D4 g& n: Z) N- c9 `
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
4 v0 x$ D7 i: i8 P  }  导入和别名' w2 o' Y: q2 [* d5 |  j
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
7 I- `( T* a6 i9 S( ?  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
9 ^1 R3 R. Y* p, L7 F  从PHP5.6开始我们可以导入函数和常量。
3 H4 C2 X) l3 w% e  t# ]# e1 j  <?phpuse func Namespace\functionName;5 Z3 F9 n. u: v" h6 C$ y
  functionName();
" j* J& b" f" |2 W; ^8 E9 H& Z" G  也可以导入常量,
- ~; c9 g" v' @6 k  A! G6 }0 a  use constant Namespace\CONS_NAME;
; o! o. u/ [$ t6 Y7 j2 ~  |  echo CONS_NAME;
3 K- h) S, @7 Y, I  a- W; X  函数和常量的别名与类名的创建方式一样。$ ]" Z/ d) K! c/ j- q1 _+ s" Y
  最佳实践
* i( s8 ~* h: T% o3 n% w! o  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
; b0 @7 f7 |+ h  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。, e1 Q: a1 Q) Y. O9 x& a
  自动加载
9 m1 S9 P7 b7 G4 O0 I  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。  B( x* F* f. e, b6 `* Z! }( W# S0 R( v
  2.使用接口! N% A! }8 n: I3 {& Q) |+ L
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。* {6 C" |& `( Q* B- J8 q" q. X. @' [
  3.性状$ x8 c& j  j# o% z
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。' S; D! ]1 P) u0 c. D5 `( t
  2).性状使得两个无关的类可以使用相同属性和方法。; W' v& p1 C5 p9 q$ M  r
  3).PHP解释器会把性状复制粘贴到类的定义体中。
0 b$ `' H: U% W6 e' t  4.创建生成器$ v1 W: S7 T4 E- ?
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
% p3 ^1 P. E2 K" h" I  <?phpfunction myGenerator() {
# V4 c% d) U2 N# m% K7 |! t  yield 'value1';; v, G  [) ?, I
  yield 'value2';8 R# O, |+ K) E9 S+ P1 z
  }
9 A  F4 l, j% v! a' F( M  v! z  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:3 `, u& m+ u  x* {/ u
  <?phpforeach (myGenerator() as $yieldedValue) {3 G1 d! A) q8 l) E
  echo $yieldedValue, PHP_EOL;! a3 A* {2 c9 }
  }
' H" z2 y2 l2 Y  以上例子会输出! b. _# \0 J3 v( J0 Z. |2 ^
  value1# \6 B( g: O) ]/ ?
  value2# R$ [% T1 q8 R- o/ a* }8 Q2 C
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)" o1 _& y# \) j, ^( m, |; G$ x
  function makeRange($length) {. Y" @2 x$ [5 l7 ~) j0 Y! F; ~
  $dataset = [];
+ E) r8 G3 R' l2 i9 O6 @/ y  for ($i=0; $i < $length; $i++) {2 U% P3 Q* ]' S9 \1 l( _
  $dataset[] = $i;
  s- b. H5 B; F  }0 g4 ?9 A1 e! ?3 u
  return $dataset;9 T" d- |2 E; ?: n# b' m1 e
  }
$ h, ~6 u3 ~' s  u  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
2 X& V" b. c# A% O- i& l5 ?3 s* a  echo $i, PHP_EOL;
" Z0 e; h+ {3 Z7 e  }- t5 K: w2 H0 J" I6 l
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
4 M$ r2 Z+ r$ q% Q2 Y' V  function makeRange($length) {1 r' g. s  y% h7 D( y' p- ^; O, y
  for ($i = 0; $i < $length; $i++) {4 v. b& q9 |9 u( h* ]8 D
  yield $i;
6 J* K) a. x8 v) [  }. h! Q/ M. n' ~% X6 N
  }  x' [' I$ D9 a- ^' F
  foreach(makeRange(1000000) as $i) {
5 d% k: C6 Y! W/ U9 B5 x  echo $i, PHP_EOL;0 V9 G$ G. p0 u$ I7 o
  }
" a; k0 I1 Z$ I  Z7 j  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。% B2 @! v2 `( f& c6 t2 y% n
  function getRows($file) {# C* }) O* ]  M1 x5 h- l
  $handle = fopen($file, 'rb');6 @6 G) i9 `/ L2 W. [+ f
  if ($handle === false) {* s/ D' Z6 H. i
  throw new Exception();
" N4 W) }7 S- `; L0 k  }
% X+ N" T* R* l. r# Q0 {! h  //feof()函数检测是否到达文件末尾8 c6 m" N7 K7 _! N
  while (feof($handle) === false) {% g2 g; X; D0 E6 X* @9 s
  //fgetcsv()一次读取csv文件的一行
% \" Q; }  K- Y- K( I+ w$ y  yield fgetcsv($handle);
+ N4 W% w, X) R) b4 l3 {5 W; J& x) ^  }
$ G# s% l: x: P! Q! J& \" O  fclose($handle)
2 ]1 r# z" I! h& v, y! ?+ ~  e  }3 W4 ?7 @( A/ @& b
  foreach (getRows('data.csv') as $row) {
6 S' k' B# k3 K1 e, \  print_r($row);
2 \! a2 _8 o7 m  ?+ Y  }. ?8 R6 P4 h5 x" J4 z8 z
  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。- ~+ @  `# n" w- b' y2 a$ C" d
3 }0 B/ Y( R; i; [* p* K" ^
$ @; p7 ~- J( x: u3 s$ q
来源:稀土掘金
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 16:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表