鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
( ]% h$ K7 |" P) ^5 U. N  1.命名空间
3 q. C2 @8 a# [) T  命名空间是什么?
# F+ E# D4 p# \" i2 V/ D  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。  W! I4 K1 A. W! U- K9 b
  2).命名空间始终应该在<?php标签的下面一行。
" d) c; Q: X0 q& ^# O8 p  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
8 z8 y, j* R( V) e9 Z/ ]  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
) j; ~* q* |) I+ e6 z  为什么需要命名空间?. R  O  U$ ^. y0 d! {
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。  d4 o0 N2 a( c& c4 w' }
  声明命名空间
1 c+ k+ [/ t' ?2 y/ z4 k9 L  1).顶层命名空间经常用于设定顶层厂商名。1 J& `5 Q7 u/ g
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。( n  e% p9 ~. i9 J2 [
  导入和别名
1 S- `3 D. X; o' t  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。, w- X, |% ~( s4 R* C, I2 _1 C
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
! j2 v" T! ?! U. Q, @  从PHP5.6开始我们可以导入函数和常量。
+ b8 f1 J" T* W2 v  k  <?phpuse func Namespace\functionName;
8 c+ d9 d0 w0 Q' q$ p  p5 D! w6 m8 m. n  functionName();
' j9 E1 \: q8 @2 H  也可以导入常量,3 B+ Y' r6 z& ]( r+ l" O
  use constant Namespace\CONS_NAME;# J5 Q. w0 {* y" k' z0 F
  echo CONS_NAME;
0 K( B- @4 g4 ?' r+ _- u# y  函数和常量的别名与类名的创建方式一样。  @1 P0 c" m6 s' X3 _& G  f
  最佳实践2 b, e% K7 j& E& y# D' C0 g+ Y% k
  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。! P" \7 j' j# k# P4 r+ ?' D
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
5 t4 `5 G6 K$ T1 }# C5 l% T  自动加载
! }6 T" V3 a7 E% ^7 _3 d3 \  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
+ |3 l+ ~" p& w  2.使用接口' ?/ A3 j# J* G. T
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。, C* `. v6 q; {) M  |/ @* {% W
  3.性状' ?& w4 I$ D' U7 g1 J5 k
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。9 U( x. e9 s* p& S
  2).性状使得两个无关的类可以使用相同属性和方法。
# n( c: O! O+ b  3).PHP解释器会把性状复制粘贴到类的定义体中。
) H, W9 c" }3 Z- N5 p  4.创建生成器7 V  Z3 }# |/ r. Y7 J. k' q
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
% V  x: C4 M7 t$ ?% m: a7 F  <?phpfunction myGenerator() {8 L% ^/ A# q; N$ C2 @: U" A8 C9 M& N
  yield 'value1';
- z9 O! d. v0 f! i  {: ?  e4 z  yield 'value2';* l( [/ s' t: q4 |
  }
* ]3 U4 T% ?# F! ?  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
2 N1 J, Q! r6 ~% N  <?phpforeach (myGenerator() as $yieldedValue) {
3 @  e! `8 t. Y8 @4 G  echo $yieldedValue, PHP_EOL;
0 B3 t: j8 t: T1 b# J5 d3 i  }- V2 L/ u1 b' E
  以上例子会输出8 x  T0 X2 m7 s9 ?
  value1
: C2 H  w2 s6 G  Y& `+ n/ Q  value2
0 e8 U+ a. {, V$ Z2 S  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
; Q; U6 P+ C# X4 m+ t+ v  function makeRange($length) {1 D# e# g. `& r, C6 b8 W
  $dataset = [];* e: d' j% R7 M! l8 a
  for ($i=0; $i < $length; $i++) {
3 j* r) k0 F1 L, M  $dataset[] = $i;
. R/ t) H& K( J, v! C; }  }& l& A; R# v& P
  return $dataset;/ x, F% q  d3 {5 o" l* h
  }
& z. t7 t  D- b; s3 c/ Z  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
) [; z( J8 T' l2 k( |( g  echo $i, PHP_EOL;/ f4 ?6 [9 {% h4 f8 ?. P* x" U
  }1 V' F7 q$ H( P+ J/ R) x+ v1 T) P$ |# g
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。3 I# N$ M, l8 U# H
  function makeRange($length) {8 M: F- _, d' W5 L
  for ($i = 0; $i < $length; $i++) {
8 c) e$ p& J% R4 z3 ^% S+ h  yield $i;# s/ q/ h8 P, G3 d% Q
  }' x' O8 M  b9 m8 n. h- Y: F, P
  }
$ w1 H+ q: s$ X: s' q  foreach(makeRange(1000000) as $i) {$ I* m- f+ [: ^0 Q! X7 ^6 H. F
  echo $i, PHP_EOL;
8 k  K7 `+ R; P1 k" ]  }
2 d$ S6 `  ~& K  C: B& ~, v  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
$ x, ]" k/ I" g% C# I  function getRows($file) {, r& c- O5 f: b, J1 M
  $handle = fopen($file, 'rb');
! \# T+ l) F. Q9 q6 `  if ($handle === false) {/ L  Q6 I) m0 y5 U! U4 p2 U. ~
  throw new Exception();' F  R' C6 Q5 J( J5 \0 S
  }. f( S; B. _- U3 A
  //feof()函数检测是否到达文件末尾
: S4 a# b, m/ n# ]  while (feof($handle) === false) {
; r# N' c% H' K$ A- f6 {  //fgetcsv()一次读取csv文件的一行/ I1 M4 p; P8 m5 r9 s( {9 j
  yield fgetcsv($handle);
# t" L9 ~7 c0 O3 `, z  M6 L, w  }. I+ x9 O8 Y& d5 R
  fclose($handle)
6 c- s1 @  J  _" Q9 y  }
/ d3 U- c; W6 y0 _1 t  foreach (getRows('data.csv') as $row) {. Q7 J' A1 `7 \1 x& O2 K' \
  print_r($row);+ X7 |* }2 y3 K3 m
  }
8 y( Q$ g# T. G% v) g7 a' I  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。  i$ t  _' M7 E! j: Z

7 E: f6 w! V' K
4 _* E  `7 n& D( I% Q* J7 X来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-2-4 01:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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