鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。: L& u+ @8 Y) A5 Y. ^. m8 g
  1.命名空间
1 X$ ]" f, M: W0 M' N  命名空间是什么?" {: n3 l" [3 @" H( n5 p' _9 E) f" U
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。+ G) S+ d" f' X8 v
  2).命名空间始终应该在<?php标签的下面一行。
* t5 B5 C9 q& b& w' A  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。+ l5 T8 V, k+ k- E( n0 k5 q3 F
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
. P0 v2 t  Y. x: ^! Q* s  c5 s& T  为什么需要命名空间?$ u% C" k3 x/ P8 y
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。$ k+ W- b7 g6 t1 F* Q
  声明命名空间' j6 {$ w$ ^; i/ P" t
  1).顶层命名空间经常用于设定顶层厂商名。
' i" ]& F& U3 \1 T) N6 H% j  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。; S2 \4 a. `. @6 Q
  导入和别名
/ S; _& i5 z! I, ]0 }+ _  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。; G2 X$ j7 m9 G* \3 f, ^" |3 A/ a) j
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
4 x6 A/ u, g' F- y+ s! i  e0 i! Z  从PHP5.6开始我们可以导入函数和常量。
& t/ a) r0 ~( ?7 P2 S, _  <?phpuse func Namespace\functionName;8 F7 I" U7 L' E5 y/ h
  functionName();
: B' l  [3 l0 T7 g9 \4 e- h; @  也可以导入常量,
, s4 M$ ?- L( V3 p3 G  use constant Namespace\CONS_NAME;( V/ N7 Z* x3 k" w
  echo CONS_NAME;. c* g' A0 V% R: Z1 X
  函数和常量的别名与类名的创建方式一样。# q8 O6 E8 `  K8 e% C2 e9 W- |( E# p
  最佳实践
( N8 L) e5 y+ C7 o. ~% z0 w  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。  c  C) b) K: M/ D
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
$ ?# l! p$ p( \) k  自动加载3 x# R; R4 b( N$ Z" ^
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。6 e9 b( d  {" B
  2.使用接口
! k$ V" J) }7 W8 b2 |( w  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
' G8 c( ?2 e; _7 N  3.性状" `0 e0 I- o5 g, \1 R5 P* z1 Q; u
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
  M8 |9 ^1 \) N  2).性状使得两个无关的类可以使用相同属性和方法。5 ~2 S4 a( p2 m
  3).PHP解释器会把性状复制粘贴到类的定义体中。8 F4 N4 E) e, ~4 |3 D
  4.创建生成器9 ?: i$ k  t8 C: a! m5 R
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
4 U3 g) B! e$ Y& ~" H1 O3 k  <?phpfunction myGenerator() {5 Z2 A( E1 T7 J: q1 \7 R
  yield 'value1';, ^! }, B5 L: B9 d6 V* C
  yield 'value2';& N. ^5 |6 N- K! A6 z- X
  }
8 X( T$ d& }) s  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:, W" [/ p. C! Y
  <?phpforeach (myGenerator() as $yieldedValue) {
# t! A' O* d* V( v+ `: f  echo $yieldedValue, PHP_EOL;( W3 E# d! R- @" V$ R) L" q2 s
  }9 U9 J, {& j1 p0 H8 w: Y
  以上例子会输出/ W: V- m' o/ U
  value1! `/ f" s% J' x2 S" ~
  value2
/ q, V! M5 Z  f2 r, g& e' q  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)4 g, K# o; R* ]2 u. }2 `
  function makeRange($length) {! T% L3 O8 l  t* J) o
  $dataset = [];/ {0 [* x# ^; V( Z+ r2 `# ?; L9 ~' L
  for ($i=0; $i < $length; $i++) {
7 S- h5 I  c$ Z& q$ X4 G  $dataset[] = $i;( Z1 J* V7 d# S3 |1 b2 E* W& L
  }
0 j, N) p1 K* C7 _( Q3 r2 B  return $dataset;
% E$ i$ R1 }. K7 R5 Z; l; M3 d  }
! E$ ^  I0 Q; t. f0 v6 \  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
, [  I: F+ v& W, p, n6 ]" S  echo $i, PHP_EOL;, A9 A) ?/ h! R- Q1 \
  }9 l+ ^' a$ k* M0 M; W
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
+ M  b9 m) l4 }  }. S  function makeRange($length) {1 ?; i% o+ `4 ]/ Y& O0 r2 I
  for ($i = 0; $i < $length; $i++) {/ ?# S9 ~, [* D; Z, o  N6 j
  yield $i;0 r5 g1 d/ m& @4 r" g
  }
/ o* u7 I: i: T* T) R! x  }
( H5 [' T4 x4 f. f" e) n  foreach(makeRange(1000000) as $i) {
- l5 m* z, ?6 f* x* Y5 l  echo $i, PHP_EOL;  S. @; b4 I$ b. \+ Y0 M
  }
( O0 ~7 {1 t' Q( x/ d  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。' n/ k3 `( `% e4 \" Z1 l% R. Y& n
  function getRows($file) {. ?- M) I  Y3 b% P9 F
  $handle = fopen($file, 'rb');1 X; ~! _& e& S: @0 W- y+ s2 D
  if ($handle === false) {/ ]6 Y8 N# ?* A: g1 W  W7 v
  throw new Exception();
, ^. }! D! y9 x( d  }
7 w+ O' U3 [2 f% t2 J  //feof()函数检测是否到达文件末尾
% x- l- N+ ?" }1 J$ |( ~1 H( H0 k  while (feof($handle) === false) {
" x1 X, z6 g% [' W6 L  //fgetcsv()一次读取csv文件的一行: \. a8 c& D" \$ Z! `1 v/ c4 B
  yield fgetcsv($handle);
" I0 S  b$ a: u1 m2 j- O9 p% I  }/ h2 h7 [' O- J# N4 _. _7 p% ]% |
  fclose($handle); l: g+ c2 g7 x( x% R  e) U
  }- S# W  S: F" E7 I) `
  foreach (getRows('data.csv') as $row) {
+ u9 Q& q' I9 X! ~8 c  ~9 Z. }  print_r($row);/ G0 C0 L* u# ?0 g( V
  }7 ]4 ^7 p: o. M+ v
  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。+ R* S7 Y; M& N' K; D+ f; R
' A" N/ n; Y4 m

! [( V: q) ]6 x3 K来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2025-8-20 21:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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