鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
, V2 q7 V: |- h2 v  1.命名空间
' u( S; R; K! z' G% D. K" u  命名空间是什么?- v3 s' m- R6 d/ P% A
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
& }  h6 N% K7 j# K  2).命名空间始终应该在<?php标签的下面一行。
0 d4 k) e8 X1 v) \( z  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
1 l# F# Z% q& b& l% b  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。( s- g- b) \7 W0 v; |
  为什么需要命名空间?4 g8 X( u/ ^/ [0 i1 B: _  V8 t% l
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
) T7 c+ W" X5 G; Z+ b. `2 K9 l  声明命名空间
9 x6 p# \" a: m! g! v  1).顶层命名空间经常用于设定顶层厂商名。
* P; h" ]& s( Z1 K! U  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
7 K7 Y6 B1 v6 p" q% z" K# C2 d  导入和别名
8 W; B4 l& E. \; l  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。; w& Y$ l3 R) z
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
6 N. y7 K# Q) h# y  从PHP5.6开始我们可以导入函数和常量。. l: S* K5 }) H; ^' |# N
  <?phpuse func Namespace\functionName;
2 O! C& R4 N" j9 h; W4 T; C) s2 a  functionName();( L/ R# X$ d/ x, {
  也可以导入常量,# N& |3 l. K, d$ O  B
  use constant Namespace\CONS_NAME;
$ W+ K8 a+ H6 V! [; C! I6 g/ d  echo CONS_NAME;8 O7 z4 ]1 ?& X( p
  函数和常量的别名与类名的创建方式一样。
# }/ m# B4 j( H8 I$ h! j  最佳实践
( s6 R7 I3 e3 ?: Z- r( j  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
& B8 D  |+ Q, J* F7 I, u2 l. ~  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。; D, b* _3 s/ ?0 k6 g
  自动加载6 U" M% y( p% x  X
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
! Q. g$ m& r% j0 f1 a6 Z( z/ Z  2.使用接口
! ]$ V3 F: O# W7 d  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。# k" q' \' m* {* ?, I& i4 p! j/ g
  3.性状
' O! }3 Q8 C+ I5 K  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。- @. b) t/ w$ Q& d9 H
  2).性状使得两个无关的类可以使用相同属性和方法。
5 C4 K' _8 K1 a  A1 h% k- @0 j6 ~3 Q  3).PHP解释器会把性状复制粘贴到类的定义体中。' o: Z- [  e5 w% \2 T
  4.创建生成器  Z; K7 T* P/ s2 s4 ~
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
- y( Z4 [' R% R5 u  <?phpfunction myGenerator() {  J7 m5 C+ b8 v0 J4 i* b
  yield 'value1';
) k' }' z/ m$ [2 Z  yield 'value2';
4 N0 i$ O; x3 D. w- C$ M8 Z" [- z  }
7 o( J8 M+ R& p( Q( p. T  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
, z* ]( m' C7 ^& `& o" C  <?phpforeach (myGenerator() as $yieldedValue) {5 ~+ q1 f* O. |4 ]
  echo $yieldedValue, PHP_EOL;7 Q) A6 \3 M5 ^+ W% p
  }
, W1 y1 [) c+ Q, \; G6 @  以上例子会输出
( l# w0 S9 }# k0 w9 h/ [2 ?  value1
, `4 r& s. Q4 ]  C5 L/ v1 a. ^& a  value2
1 \% L% Z3 @  m2 m& H: r% S! D/ h* l  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)  f2 \7 m# V+ g7 X. h6 ^
  function makeRange($length) {/ Q, [: \( e9 i1 s* |7 j+ ~- e' K: I
  $dataset = [];8 @! ~2 d* I; m# U1 c& }+ [
  for ($i=0; $i < $length; $i++) {
4 W; q5 c; M" j; J  $dataset[] = $i;4 Y2 h% K. {4 W6 e# r
  }
; }1 ?$ W1 v0 m& f6 P  return $dataset;. G' _) R' C# S. x) N4 \( {. s
  }/ `9 N. I" c6 g7 ^- ~  K: r
  $customRange = makeRange(1000000);foreach ($customeRange as $i) {9 i6 R6 S( w- z4 r( J$ r# P
  echo $i, PHP_EOL;! X7 X1 c3 g5 A8 G, a. k5 \1 k/ v
  }
5 ], n! }0 t0 u2 C# P7 {  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
% [: a9 H0 @5 f1 i* M( R  Z  function makeRange($length) {
" D0 c4 ^3 K% t  for ($i = 0; $i < $length; $i++) {2 S! O% Z# p9 Q( [8 v" E4 |
  yield $i;7 l! L6 O" U4 {5 G$ |+ e! c5 p
  }
3 D& {+ ^7 n0 G+ L7 v: A  M* y' _8 b  }
' c; @" J# w0 h  foreach(makeRange(1000000) as $i) {, c1 L5 M  i/ x
  echo $i, PHP_EOL;
5 y7 R6 G; K: Y+ y' ]: N, V  }. c- d' Y3 ^; u
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。6 L. f9 N' a) `. S  @1 a
  function getRows($file) {. p4 }) }. L% B- X9 K6 n# E! [; k4 J
  $handle = fopen($file, 'rb');
% X; T; R9 h: _  if ($handle === false) {
( ~# F& v  N& r( z$ C  throw new Exception();
2 i5 p/ G. {4 R: ?, ?  }& g3 R0 [' z3 E, Q7 d
  //feof()函数检测是否到达文件末尾8 R/ Y8 u3 e$ n6 ?
  while (feof($handle) === false) {
  C0 J* S, @4 `7 ~# @& B/ z5 o, s  //fgetcsv()一次读取csv文件的一行
  d: m" w1 l- c" i2 ^! [  yield fgetcsv($handle);
  [6 |% z+ {: n& U. ?4 P- F/ q& ?  }1 z" A. V4 o6 T' T
  fclose($handle)
: o) x- b/ q1 [6 Y7 g  G  }- b1 j  t* k4 b( `; L
  foreach (getRows('data.csv') as $row) {
( G' A$ C" X; d( p. @  print_r($row);' W0 w# Q7 A& i  _- B5 S+ z3 ^
  }
0 |3 M0 B6 _' @3 w7 A  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。* V4 B8 _9 j5 k  I0 G/ h, W

) P3 a+ b$ N3 `) g2 j
% W" B7 w# X% N8 j- P来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2025-11-19 14:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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