鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。) a7 u  |$ e0 c4 w+ _) ^% i5 \  S
  1.命名空间
+ Z4 e3 |" \1 o! b% B  命名空间是什么?
( d, L" Q. p  O. ^# j1 Q. I4 o# P  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。$ c$ m* d" g7 B; ~7 m  x
  2).命名空间始终应该在<?php标签的下面一行。
; ?( J/ E9 U* N6 X  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。2 j, W6 `5 H+ B$ R0 d& J
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。4 c: e# P! C% ?4 A9 h; m; o% w7 z
  为什么需要命名空间?) n5 I5 `* n& a
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
0 C9 v, Q, D, K3 l  声明命名空间
6 ]8 t3 L( K. u2 j( x6 c. w  1).顶层命名空间经常用于设定顶层厂商名。
2 I% Y0 \; {' J& Y$ [. o! r, j  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
# X) p' a- N3 Q9 c8 z$ n+ X  导入和别名
4 t! I& D! f- p* H; H" M  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
; a& {5 d/ A( p# k6 M# e0 r! m! o) b9 v  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
0 u- x+ d- r6 g# G+ I. T4 x  从PHP5.6开始我们可以导入函数和常量。
) M' d6 G$ `3 \# Q& z6 P  <?phpuse func Namespace\functionName;9 \7 N3 ~1 g: P' u# Y' o
  functionName();
* K  y& U- {4 D  也可以导入常量," ~( \9 ^2 Y) R) H: ~0 }
  use constant Namespace\CONS_NAME;
5 ^$ C+ }, ]8 L8 |5 |- v/ }  echo CONS_NAME;  _. L0 o$ _4 A. J: K
  函数和常量的别名与类名的创建方式一样。7 X! G/ N) Q) E
  最佳实践* w  x' N: [# T' \- O2 V
  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
) s5 @/ W4 G8 H" |+ _, l- |  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。. o4 J7 O' o9 c) k
  自动加载; a2 }: g, j) f. Z4 B" }) B' k# V% [& K* G
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
, ]9 X5 D* X5 e; S) H  2.使用接口
$ M) }1 ?* R2 I/ _3 U6 D% \% L  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。8 n8 R& J* ^6 k* s
  3.性状4 ?# A% @' W/ X+ O. S. g
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。5 x. ^8 E2 w. K. |. g
  2).性状使得两个无关的类可以使用相同属性和方法。5 x/ I) ^+ T  d/ M" F( x3 X
  3).PHP解释器会把性状复制粘贴到类的定义体中。
, f: K2 b; l' B0 y1 c: z/ k; `" e" V  4.创建生成器% g1 h- t* W5 E- D; `
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
$ U" W. p/ l1 h$ f  P& B" `  <?phpfunction myGenerator() {
" L7 a% Y) _# c, R  yield 'value1';
4 U, l% u8 ^- T  yield 'value2';- f% n6 b3 B7 R
  }2 o( m2 p% `+ b$ a
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
$ ~1 b. l: a7 K% J/ l/ g5 [- v5 v  <?phpforeach (myGenerator() as $yieldedValue) {7 Q/ }& R# |+ u+ _9 a9 T
  echo $yieldedValue, PHP_EOL;
) R4 m/ @1 u3 V& m# p6 J! w* B" Z+ e  }! G8 u& D8 ^, R; Y' `
  以上例子会输出7 \$ D- \% o8 i7 X6 j+ f
  value1; m% _- [/ ~- b9 h6 i# v! G! {
  value2& M2 p2 Y, P& Z( d( h
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
) Z0 y/ [) r" G7 R8 U# V  function makeRange($length) {
$ y- f9 T8 u; d- m& p7 r( b  $dataset = [];
: V- B6 f" \. a1 O2 O' t4 d# T  for ($i=0; $i < $length; $i++) {- q( ^" ]  K! @% m: I5 o
  $dataset[] = $i;
& _# l8 \4 n, w3 m" Q* \  }$ c1 b( y1 ?; M7 J
  return $dataset;
4 b' g: @$ {8 ?5 v2 s1 u- B6 ]  v  }& y) M8 ~" F8 `# s+ ?
  $customRange = makeRange(1000000);foreach ($customeRange as $i) {, G- ]9 d; O+ X, g
  echo $i, PHP_EOL;0 w- s) {9 ~1 n, Y
  }* y+ f  ]9 r2 o
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。4 d% U/ c0 L  c7 d' j( C
  function makeRange($length) {
  W- Q+ c( N  k2 V/ s3 T* f! N$ _  for ($i = 0; $i < $length; $i++) {& o) r, G$ D$ k2 h; e: j
  yield $i;
; a* t, p6 C* Q5 v- ~- q  }& U5 C$ K1 G& [5 L
  }
( \7 ^0 s' y3 E5 v  foreach(makeRange(1000000) as $i) {% M# F( E9 H  d/ N# m
  echo $i, PHP_EOL;) ~* Z' z) r9 ]7 T9 o' P
  }" _. b; \! O  @7 f2 t
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
# b* C3 ?$ m& {# l: W2 P  function getRows($file) {7 i5 s6 t: S' b* M# }; f" j4 O
  $handle = fopen($file, 'rb');
# I7 z' S  s( }/ r  if ($handle === false) {/ H7 h" z* F" _& z! q+ P" ~  h
  throw new Exception();% V) b/ T, L# M+ r* _
  }2 K. }3 _- ^% D6 \
  //feof()函数检测是否到达文件末尾
5 A1 w6 @+ p6 R  N. ]" q  while (feof($handle) === false) {# X$ `3 O: l0 w& h8 T
  //fgetcsv()一次读取csv文件的一行* ?1 O& ^- j: D0 G
  yield fgetcsv($handle);9 Z: p8 F# R; Y0 j3 o
  }3 |. i6 H+ {) ?; S
  fclose($handle)
: p; t( h- ^* d0 p5 p& E  }
1 P" M& m4 j; \  w  foreach (getRows('data.csv') as $row) {$ d: H7 U" q: Q4 W% h, o( M, j
  print_r($row);
' E9 {  J8 K  V, t( ~$ Z  }
: I% L+ g/ _2 Z+ N. r# h  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。7 R$ j$ Z. d( O! n: r9 |) w1 h5 K

% B- V7 S$ v/ n6 @* ~' `- s
9 `2 Q. _- f4 b, h来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2025-8-20 20:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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