鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。: x9 N! K) S9 u4 o
  1.命名空间' d( V; S/ d' @% w
  命名空间是什么?
1 u0 ?9 D1 L- l6 t  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
- u. B- q8 G) I$ w+ G" L+ y% \  2).命名空间始终应该在<?php标签的下面一行。  \, v0 J' z4 U& K% n
  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。6 k$ |1 g: V( y* |0 D0 B
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
6 a. H. i1 P  P7 j8 \! E  为什么需要命名空间?$ t, s# B( S, }) R7 ]' t$ X
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。9 `- O2 J/ `. M- G/ ~) C
  声明命名空间
- E! ]9 c  X3 a" V& S  V" f  1).顶层命名空间经常用于设定顶层厂商名。3 q) B5 x# P% {* d" C4 c& s
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
- I" G6 v2 |2 `& x% G0 s  导入和别名3 J: p9 t3 p, K
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。. B: R/ @( l0 G3 h5 p6 b' L2 \
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。" m; [3 ~/ D3 `% x* [& Y% k
  从PHP5.6开始我们可以导入函数和常量。: z- d' ~3 Z7 f6 o" ?$ d/ ]+ I
  <?phpuse func Namespace\functionName;
8 c3 e2 |! D, t5 C  functionName();/ b; d' D- C7 z
  也可以导入常量,
4 j6 _0 X' q1 A& _; N2 k3 J, ^0 }  use constant Namespace\CONS_NAME;" F: }# y4 g! _2 O3 `( i
  echo CONS_NAME;
; b0 M& H# C# l  函数和常量的别名与类名的创建方式一样。1 K& h' l# C% [% S3 S  U
  最佳实践, c* P2 J6 L: {9 W: B  c
  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
2 E" X! z8 [. r: C  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
. D" ?, ^5 Z8 U- l  自动加载; L8 `" P# ?. T5 j2 H2 M
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
7 K* T1 n% I9 [" ~  2.使用接口1 g& z7 ~* o; [. M: F! A4 c( p5 N  _
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。7 @2 N9 K' c* W' Y
  3.性状
% b5 ~+ J3 ]& U2 y% |. Q2 a  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
4 ?$ v1 o/ m, u, K) J- @9 a  2).性状使得两个无关的类可以使用相同属性和方法。. j! I! Y$ M: O' d6 L: x* l% k- \
  3).PHP解释器会把性状复制粘贴到类的定义体中。* c* b# J' p7 F5 v; u  x4 W( @- W9 c
  4.创建生成器
" F5 r% e& L1 A& i  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
6 S, i8 D; G. `9 T" t  <?phpfunction myGenerator() {5 M; o, H5 L* _6 N
  yield 'value1';9 y$ u5 D5 i$ f2 q4 {
  yield 'value2';
" Q% z9 @6 M) y7 f, k  }
/ G& S( H6 E* B3 N2 k* T  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
6 {% h) c& b* Z: I$ Z9 `3 Z  <?phpforeach (myGenerator() as $yieldedValue) {
- H# M8 X4 C* f* M7 G. |  echo $yieldedValue, PHP_EOL;' C0 [# L& d% Q* h- A
  }
8 X8 L& n4 Z3 A% f; W  以上例子会输出
: L" D3 I# C8 b; U$ X( Y  value1
8 a: M- b/ q8 H. g( K  value2
4 F9 t* `. W# j1 I; M# o" h/ T  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)/ a! }/ I+ {. b% t
  function makeRange($length) {
, M4 U3 [$ ]& B# Z4 ~  c" _  $dataset = [];
! r# b. Y; J+ d2 i6 I* i- r& m  for ($i=0; $i < $length; $i++) {
: T: G2 {( q2 b; @1 L2 N+ e( C  $dataset[] = $i;2 o" g1 H/ f( X! t0 [! r
  }
7 L+ d# F9 G( i2 c0 M, ^% Z  return $dataset;
6 {, U) g+ a' _, d  }
) ^- ]6 t7 L3 ~& d! p& p" s  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
# F) w6 |( I9 }& y  echo $i, PHP_EOL;( O  ~# I6 v4 m! l( Y
  }& @( m% |1 W7 {2 ^
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
/ I$ y0 v1 ^" \  d) Z/ t; ?: |  function makeRange($length) {
# K+ o( s1 G  S3 \! s  for ($i = 0; $i < $length; $i++) {4 B) g. `* a. k0 P% w/ p
  yield $i;# E3 J# Z! Q: n$ M3 c0 z+ ?
  }
1 I' w2 A; U; k4 h3 I  }6 b' o& j" D3 @. B& A) {$ B* H
  foreach(makeRange(1000000) as $i) {. [; ?1 P5 R' o
  echo $i, PHP_EOL;
0 l( S5 d4 j: C" `  }
9 H7 E) w" g, r+ j7 x/ u& J  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。+ \5 C( X- G" |
  function getRows($file) {- l4 O5 L6 A/ n% |& i
  $handle = fopen($file, 'rb');3 ~) Z3 |' O, u2 O' {6 h: o
  if ($handle === false) {
2 n. w5 N* S% [) o4 f* I5 A  a1 l: m  throw new Exception();
- ~. W$ a& ^$ K& K- c, c  }& I/ K& r$ t& \- s+ B$ S
  //feof()函数检测是否到达文件末尾2 a# ]- b7 m$ T$ p# S
  while (feof($handle) === false) {
9 k4 W- w' x: {9 R* [8 \% `  //fgetcsv()一次读取csv文件的一行
4 J7 j  G. y( y/ l6 b- B  yield fgetcsv($handle);" W4 A! U* f( A) m. u
  }
' R8 T  D, r  ~3 W1 v  fclose($handle)+ ]1 G- q& ]5 g! P" C# y: |3 \4 `
  }" h8 f; }' G+ r" a! j. [) t
  foreach (getRows('data.csv') as $row) {
( s8 Z: Q  z* c" @9 B3 u( E  print_r($row);
5 V( K( K, `$ l8 B  }& M# D" J, \' R) S1 \. c4 t, r& ~
  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
! C3 r$ {1 y3 q5 ~
- B( _, g$ d/ W/ L, N! m% W5 S1 n" Q4 R! ~8 X( g' ]! y$ j
来源:稀土掘金
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2024-5-7 12:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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