鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。3 s$ e. e! O  e
  1.命名空间
' t0 e7 u& W# u) X3 ~# x7 ]* ?  命名空间是什么?& x% `! ^+ i1 @( |; w/ y& G
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
6 O( q( B' `5 c; n" X  2).命名空间始终应该在<?php标签的下面一行。
- W( R! S: l$ O6 w  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。% j+ R- c7 |/ ~4 \3 ~; K! W+ @. T
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
. \2 l; `9 G: Y1 ]7 y5 O$ ^3 [  为什么需要命名空间?
& Z9 u; B3 }- W$ a$ I1 u; B* J  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。  B6 ^, Z' Y9 M- s
  声明命名空间
6 o5 p7 r$ h4 r. F7 X, U# K0 N$ c  1).顶层命名空间经常用于设定顶层厂商名。
; s* N' t) X1 M; D  x* y  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
. W8 m' k' X+ G5 o  导入和别名1 s7 G4 f0 P7 w- G4 p
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
/ o" f/ E' C# @$ D  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
0 I( o/ W+ q. l9 s4 K  从PHP5.6开始我们可以导入函数和常量。" u# i. M1 ?: A4 d
  <?phpuse func Namespace\functionName;
, X8 n. i  H+ d$ g4 p  functionName();" v7 S% y0 p- \9 |4 {$ ^! l, s1 Q
  也可以导入常量,& i( G2 ^8 Z& r3 Q$ ^
  use constant Namespace\CONS_NAME;
' L3 |) [* Y# h0 q2 \8 D  echo CONS_NAME;8 h0 I7 u6 }$ o! m7 R
  函数和常量的别名与类名的创建方式一样。) M1 |  i7 y" X' }% A6 z- Y/ B
  最佳实践
# C  F( @9 G, `  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
' N$ x# o, ]( s# ^& l- k  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
6 M+ B1 q/ ~$ n1 g( G  自动加载; N& |' o/ Y$ z8 V$ Y2 Z2 e- ]& b8 k1 n2 y
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
! w9 b4 \8 ?( Z3 E8 j7 a6 t+ h- W  2.使用接口
( R% |" p2 Z4 l  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
8 s3 G8 i" \8 ~( i# D" Q; A. j  3.性状
) z4 d7 M5 {- }- V+ s$ ^6 O  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
. k9 _- k/ C3 I  2).性状使得两个无关的类可以使用相同属性和方法。4 r) C  H& [3 l1 B( D
  3).PHP解释器会把性状复制粘贴到类的定义体中。
' m; e/ }/ `8 l& _9 |& e  4.创建生成器
, n) b3 U" ~  b5 d2 f  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
+ m- O5 z3 b% W- v# p8 b& b  <?phpfunction myGenerator() {
% S4 b& q) w, A  yield 'value1';- j( k  W+ g) P+ v
  yield 'value2';4 d' x& b9 P6 b) N
  }, U5 q/ O4 |( F
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
- \1 c) Z6 X( l; D  <?phpforeach (myGenerator() as $yieldedValue) {! z0 D4 C3 p4 h" n
  echo $yieldedValue, PHP_EOL;
* V" F& J" o1 }0 D+ Y7 E' [  }. L3 u  ]* }! \! S% k+ @7 C- F" ]
  以上例子会输出
3 m/ ^8 m! L/ q  value1
5 k9 _" f  t$ W  a) o3 ^3 t  value2
# ^6 \& P1 c9 {& }% l  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
0 ^0 f# @$ \2 D, U6 o( O/ `  function makeRange($length) {) A/ V/ Z1 q5 |  Q
  $dataset = [];) O( ~) g( ]/ @( Q0 @
  for ($i=0; $i < $length; $i++) {' z1 c: ?) Y- k9 L8 X
  $dataset[] = $i;) `* G+ j) N3 V$ s
  }
8 Y+ ]; d  I1 r3 Z% f" r  return $dataset;( n/ f5 `. p& C1 a; I
  }
# ]* P% U# S  _6 ?9 c) E  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
; R$ K; D$ t: z9 \  echo $i, PHP_EOL;! c. g9 v3 `) f# C$ ]6 z
  }
  C; F# T) }5 y6 a  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。" c% r4 [% n  G3 W# w
  function makeRange($length) {
% P. H) Z; V7 F  for ($i = 0; $i < $length; $i++) {7 V  v2 m: R/ j. u0 U. |
  yield $i;& N7 \1 \6 |9 u  b6 D8 z
  }
8 F) H1 i4 f( x0 L3 j  }. L" q$ V- W) {2 S
  foreach(makeRange(1000000) as $i) {1 |3 V4 G, a0 y: {
  echo $i, PHP_EOL;
; H! V& Q3 a6 a  }; g' K) j0 }/ B* q3 H
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。2 ]! l- C1 f) Y9 x, G1 N/ R
  function getRows($file) {" ]+ {% ^& ?# ~( V; |0 @* b
  $handle = fopen($file, 'rb');
9 O* b; z( N! {  if ($handle === false) {
/ r, \( S( `( t  W4 c  throw new Exception();
0 b) ]4 b) W, v  }' b( @6 H* u* L6 D% i) g. i
  //feof()函数检测是否到达文件末尾! a0 W% |" i) d# I6 a0 M
  while (feof($handle) === false) {- q* \; H0 g2 i0 G, m- ^+ v( N
  //fgetcsv()一次读取csv文件的一行" b9 f; x$ I) ]" y% @& {
  yield fgetcsv($handle);
2 ^3 n: d" b. ^4 \. e  }* O. t. h/ ]& O. _7 U7 N, i/ z
  fclose($handle)  m; d5 k$ }/ j! ^* K
  }: I1 L. p3 t! V3 H' |
  foreach (getRows('data.csv') as $row) {% D* i- i* d! _1 m" H3 w+ l0 @# x
  print_r($row);6 Q# }" @, K9 v6 _. C% b) a: x4 K  q
  }
9 x. }6 g; c9 b+ M! ~( Y/ L7 N  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。' l7 W  l. z- {  Q
" n$ Q) @0 ^6 i8 g2 l- z
+ E8 `# J5 D* R. a4 F) A
来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2025-7-13 04:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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