鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
- }: h3 B  c, \  1.命名空间* p' [0 B0 d5 X9 w7 j( ^! B/ g
  命名空间是什么?
7 t8 o7 c+ U% l$ z  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
. L5 L% m# N' X6 y' N2 [  2).命名空间始终应该在<?php标签的下面一行。
1 M) v7 r; N6 t- O6 m1 u  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
0 c: B3 ^( }1 w: S) u6 r3 ~  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。1 W$ T5 i+ |' r2 O
  为什么需要命名空间?% _, Q! z. U; C% n  g9 E, Q
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
, f0 n# j$ t( H3 `% f8 w9 u  声明命名空间
2 F; F. P; d/ ^) h  1).顶层命名空间经常用于设定顶层厂商名。/ Q( a0 ]  h  c' h; [0 R0 V
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。$ H' @  B- h0 d# Q0 w5 v
  导入和别名7 }6 F9 a/ \  a$ u0 J6 r" `
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。0 M4 F" [/ A+ E$ P* p5 }6 x
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
# A% Z$ l1 o4 H" ]: V* {0 k  从PHP5.6开始我们可以导入函数和常量。: q7 ], T1 V/ C/ c/ I& r
  <?phpuse func Namespace\functionName;
4 r& g; q2 p% D/ p  functionName();( o6 h" s& L6 I" a+ ^& [
  也可以导入常量,% j0 F% k  }: i/ O# Q
  use constant Namespace\CONS_NAME;$ f7 o7 _9 k! [
  echo CONS_NAME;
/ A: g9 p: M. t+ z1 B9 b1 i. b  函数和常量的别名与类名的创建方式一样。  a' g8 H. b- G
  最佳实践: m: \# {7 p8 z* s% m
  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
, {' n0 k9 J  t) e' k  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。' U- X; F6 [; S  D
  自动加载
* l- g8 y, w# J7 u  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。2 ^2 N: l' i8 Z
  2.使用接口$ D" A% h8 M: s# h" U% ]
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
8 j% o& t9 W; b$ C8 i  3.性状
+ H& U0 @! i* B" c  `, n& T3 C  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。+ [" u6 }* U! p/ M7 x+ t
  2).性状使得两个无关的类可以使用相同属性和方法。" I3 T; Y+ @! ^+ R3 U, l4 X: A
  3).PHP解释器会把性状复制粘贴到类的定义体中。
' Y8 |1 `% a" h" D5 L# n" C2 g; [  4.创建生成器
. ^/ }" E  m4 {1 c( _  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
' d! N; b' j" R- ^2 q1 _  <?phpfunction myGenerator() {
! X8 n% m, |9 ~  Q; [# ]  yield 'value1';. ^9 z. ~, w0 E* D% i( `0 X$ R
  yield 'value2';- @& q; a7 k5 q: R# P! |
  }
  K$ Y/ z; @# c+ u0 @; m: J5 a  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:! D1 g" o! K2 ~' I
  <?phpforeach (myGenerator() as $yieldedValue) {# R1 _0 p' o3 t2 \4 @# y) q
  echo $yieldedValue, PHP_EOL;
8 ^! d7 T6 G. ^  }
' {+ d: f; G$ n5 q  以上例子会输出
# P: C  V5 l( i: r  value16 R( G2 {; d7 J& O* j
  value21 s  Y) t% }/ e8 z
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)- a- ~9 R" F- _
  function makeRange($length) {2 [& R9 h1 T3 V. t/ e( B
  $dataset = [];
" B. _$ l; m' M; k  for ($i=0; $i < $length; $i++) {& U' s* n- O. s% }
  $dataset[] = $i;) `2 p& Z: V' p' m. F
  }# t& j- A, ?' S3 v* x8 R
  return $dataset;
: q9 S" Q" ^) J& f& |3 _. i  }
4 ]+ R, Y* O- }  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
% Q2 B- T5 P8 u/ m4 V$ g  echo $i, PHP_EOL;, d3 }5 u, T9 z( u1 e
  }
" P! i0 i5 o0 n+ u, M5 y5 b  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。. ~* i% Z0 _( G& n& q
  function makeRange($length) {, t  }  x3 W( C; L, b8 s0 b' ?
  for ($i = 0; $i < $length; $i++) {& O: I# A: }7 ?/ I
  yield $i;
! P5 ?% o& k8 Q* T6 L/ q! t7 D  }
1 }4 j" }7 f. w7 Y9 e) x  }! H$ {; D9 F% k1 l* E
  foreach(makeRange(1000000) as $i) {
! e* k% A, u) ~$ e& U( T6 @! u% [  echo $i, PHP_EOL;
- h1 c& T+ d6 m) O( S  l  g  }5 O7 V- I% J" R" m7 d: M
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
, X' Y  Z& ?' @0 S% C# i  function getRows($file) {
3 c: R, }. V) d  E, F  $handle = fopen($file, 'rb');
; V  P. Z4 j  R3 q7 ^" p  if ($handle === false) {! a. N* n- C9 H
  throw new Exception();
' _9 E/ K: x  s: c& m! t+ Q: y3 }  }
& b2 `" S2 I; Y# F  //feof()函数检测是否到达文件末尾# e  e6 {5 A+ C& `) s
  while (feof($handle) === false) {
/ ~- v. z" j* }: s' F/ x3 r  //fgetcsv()一次读取csv文件的一行
% s+ ^- p+ y2 `; `4 `/ s/ `  yield fgetcsv($handle);0 ?  X3 j, n+ A7 ~2 B0 K
  }
! Z1 D) `( a$ x1 a3 n; A  fclose($handle)" q$ h  D% e) z8 r
  }- `2 B7 k2 }7 f: J6 F2 a( W* J' ]
  foreach (getRows('data.csv') as $row) {
( _  o/ M0 ^) E. _! M  print_r($row);
5 S& h' b9 O% A( [: P  }
3 {( @# E8 X! r1 Y- U0 f! h, e  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。# ^. {7 ~8 T7 @. D2 o* g: C0 x. s

% t1 `6 W' T" ~' t$ `, d6 ~, U! z9 \5 o! U( M% S
来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-5-25 07:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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