鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
" Y3 e. H* i! @3 y) E8 n  1.命名空间
* m3 d0 I7 o6 c. A) ^  命名空间是什么?$ \' z/ v( m, N9 k& ~
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
/ N7 \" Y) }0 s  2).命名空间始终应该在<?php标签的下面一行。1 B3 K9 ~0 [% u; a
  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。: K' }6 P- U" j' T7 V# }
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。/ v, ?; S( g! |
  为什么需要命名空间?
4 g9 D* e( d7 n5 R# p2 J6 K  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
8 Z9 J& {0 N: N- T  声明命名空间4 o. d8 |, C+ @" f
  1).顶层命名空间经常用于设定顶层厂商名。/ B9 Y3 @; v$ T4 v
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
; v* L) ?  h. Q& t4 O) |* V  导入和别名
: W; r6 H' h/ D6 o" b  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。/ E- \5 L7 B, ?3 o* t
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
4 K4 I7 b* U+ T4 C* q; @/ J8 F  从PHP5.6开始我们可以导入函数和常量。
3 F8 g9 [+ i# O9 d2 ]- C  <?phpuse func Namespace\functionName;% m2 M2 z: Y4 a9 ~& j4 y2 E8 c
  functionName();" K, `$ l+ x; ?7 C6 ^& P  ]* b
  也可以导入常量,
  x5 F% c: [2 }  use constant Namespace\CONS_NAME;. L! l5 G  h1 M4 b
  echo CONS_NAME;( {9 O+ u* k- r+ C: B
  函数和常量的别名与类名的创建方式一样。
9 v4 z  u4 T* q0 m# S. e  最佳实践
2 u( H6 V% N, U. y# x7 V$ w  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。* B5 }6 B0 t) m/ T$ d" W+ `5 u
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
4 j3 t/ D$ l/ O4 w0 ?$ H2 f  自动加载, W5 G% W: P! U; |
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。. I' Q/ S1 E' n& U$ ~0 H, W) ~
  2.使用接口
- B- U( q. k* s/ d; M8 e* ~" a; N  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。* a: ^( m+ A$ r% _
  3.性状
: ~5 a: K) e+ C8 t2 I6 @  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。1 X- J7 s- T/ }* q6 _5 {- D7 R
  2).性状使得两个无关的类可以使用相同属性和方法。
# n. P+ @. T* B! O0 B' f* T# N  3).PHP解释器会把性状复制粘贴到类的定义体中。
: a6 l" u- l' f3 E  4.创建生成器
8 V( ^: z4 A- H  B( S( r  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:, X4 K9 L' K; V6 a0 M9 H% T
  <?phpfunction myGenerator() {
. v% `" ~2 p+ }3 C* p* O, v5 K! |  yield 'value1';
6 g' A+ o& p& a  yield 'value2';
4 Z- m: ?  V' l) l6 B& b  }
6 w. E; `3 G, T6 p" f1 v  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
" N  H, g* E; x# w  <?phpforeach (myGenerator() as $yieldedValue) {
/ G1 K& C. k, p  }  echo $yieldedValue, PHP_EOL;  N0 [( J9 t/ P" a: c) L
  }
4 g( b: Q- }8 p& d  以上例子会输出; R, c+ {, u* U( P5 ^! R
  value1
1 O1 T: A5 ?( S! @$ Q# R- R5 E  value2! ^: R3 H) i9 U8 U4 D$ o
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)0 \' d7 O5 e0 y% k' |3 @6 Q
  function makeRange($length) {3 `1 ]+ _+ [6 A  ]  v. V
  $dataset = [];* q7 J# t% n0 ^  H: F
  for ($i=0; $i < $length; $i++) {
) s' p8 m0 N4 ?, @2 q8 u  $dataset[] = $i;
# h9 m9 a3 d1 _: X/ \# ^6 C. k  }
7 @0 N5 p; e+ u( V  return $dataset;, R* T3 n, G" j* b) @5 ?
  }, n0 i% P$ ?) ?4 v9 r
  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
( Y+ V- Q7 G6 M# Y3 l: J  echo $i, PHP_EOL;- `. M" z3 Y  w7 v" j# @4 B2 E
  }
" m4 x* Y9 [+ J2 Q  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
' ^0 P( O. d) X% K; j- R% }! u! Z  function makeRange($length) {- z; u) l3 s. S; _
  for ($i = 0; $i < $length; $i++) {
* }7 Y6 F; D# I# [* F( D, K+ u  yield $i;- A. f5 Y$ m, U7 N  ?
  }
+ x  Y" c% Y# p. c7 T' U, r  }! L) x$ q! l) [! L& a- p+ w1 K6 R
  foreach(makeRange(1000000) as $i) {
0 s1 u: Q% q! F) ~8 S/ t  echo $i, PHP_EOL;
4 d5 d! }: G& N: f- D6 @" x  }
7 L9 B) j& }6 Y! V# m  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
' Z/ x7 W/ C8 y- {. G  function getRows($file) {
3 P- ?, g3 }5 \( O' p  $handle = fopen($file, 'rb');
* H! d% Z% z" n1 T; T: `  if ($handle === false) {/ v" ?6 P: Z: H, L
  throw new Exception();" n* B- |6 W& m6 N7 U5 O0 x. [
  }
. l/ L1 H) K4 Q7 t5 c6 F  //feof()函数检测是否到达文件末尾8 i4 G; T& k+ S( {9 C0 L$ q
  while (feof($handle) === false) {
3 ^7 g6 ~4 c5 t  //fgetcsv()一次读取csv文件的一行+ b, S1 t3 d( x9 V6 z
  yield fgetcsv($handle);
1 [8 K/ Q4 e. G# T: a; Z* y' V  }
8 N) T2 c0 t2 v  fclose($handle)
. M6 J7 C, ~* X  }5 X6 g; x$ W" |% {2 f
  foreach (getRows('data.csv') as $row) {8 d+ J& P4 {: i; r
  print_r($row);
, A  y% y' _$ V' \4 A4 t% S5 _* E9 V  }
- t) K' n6 ]) i9 d& T4 t  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。! n" y3 _3 T3 l9 }5 x
+ i1 S" q* ?7 y6 b4 s
& g; x. ~) X1 {# R8 r
来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2025-12-6 08:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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