鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。( ]" j( G2 u  {1 l3 U4 G- F
  1.命名空间
& u/ Y, _/ Z: f. F, H  命名空间是什么?8 @6 g, n) H. i! T0 t, Y. u
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。) p+ y' Z. C$ u4 |0 k( ?
  2).命名空间始终应该在<?php标签的下面一行。
0 `; J/ _- c. g7 g# M/ D  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。6 e. r& ?$ [  Z1 N) l6 G) ~
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。. b) Y, r* j1 A+ P
  为什么需要命名空间?* e1 k4 y  }( k) Z& S% M0 v' }
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
* b% _& Q/ C  `  声明命名空间1 R7 M8 k0 y; G) S( [: ?# n; |% T- }
  1).顶层命名空间经常用于设定顶层厂商名。7 j  {+ w( f+ q
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
- q4 T. h: j: T4 X+ @$ j/ p* ?  导入和别名* k8 [4 D( a4 r- Q3 s
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。; K" D9 e9 b6 ^* L. p
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。% Z1 j  ^$ d  @! q# s  o; t4 w( D, u' y
  从PHP5.6开始我们可以导入函数和常量。
9 D* \3 D: E8 z# O; C6 v9 H  <?phpuse func Namespace\functionName;
- ~: w, w# F  F: _% I# w  functionName();
$ g( ~; }2 d1 B1 L$ k  也可以导入常量,3 y  Q8 N8 N  z7 E) `9 d
  use constant Namespace\CONS_NAME;
! z: ]$ M5 Q/ k' G  echo CONS_NAME;
; Z) t7 P- ]9 X+ L7 V$ B+ M8 K  函数和常量的别名与类名的创建方式一样。
' E, @3 S8 ^5 Z2 R! B8 ~( b  最佳实践4 E! T* @4 M1 A
  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。6 T3 V$ M6 E, r# p  T
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
6 }, Y0 G0 c! q7 \2 \6 C  自动加载
' z2 m# J* g% d" j5 P! B) N1 K  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
8 N# W) o0 v* h( d$ e  2.使用接口
- }9 K  ^; K5 D$ Y  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。! e' @* f4 V+ ]2 o' b. K+ O
  3.性状- H0 T, w, y. @  @- d
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。$ z( r5 y- B6 Z% h8 a: X3 V8 g# _% ]
  2).性状使得两个无关的类可以使用相同属性和方法。
& T6 X# i- v6 V, u" M! k9 r" W) ?  3).PHP解释器会把性状复制粘贴到类的定义体中。
* s+ S. ~' V5 }) S4 {  4.创建生成器
  I8 T, l4 b/ @2 e  L" P, `  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
1 N8 t5 h: s' [* h  <?phpfunction myGenerator() {
) G8 S0 b9 I& ~5 Y1 U; a* J  yield 'value1';
+ I4 r: T0 ~" O) K1 m/ B7 l$ ~  yield 'value2';# b: Q1 f. V, U! o* U
  }! v" W. K) b1 [1 R/ C' d
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:& j* Y# b. e1 a! t
  <?phpforeach (myGenerator() as $yieldedValue) {
' u: {1 d2 u0 Y( U! b  echo $yieldedValue, PHP_EOL;
6 p: G7 R6 q# r/ M# R3 V- ]  x5 x  }
0 t# r/ h( m% ~  以上例子会输出3 J9 H2 j# }- ?* j) i! R" w. Q; _
  value1
, Q8 L/ P' D0 J0 x) U  value2
/ M/ d7 j0 z! [/ t  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
" {: q' T4 z& ]: ]4 k# o  function makeRange($length) {$ Y/ X# o$ D& l" |7 m2 m
  $dataset = [];
# `* }5 i* s5 T; W  for ($i=0; $i < $length; $i++) {2 N- V" Z3 ?6 e. I
  $dataset[] = $i;: c1 x& E  L% z& N. k% \" X
  }
% P: y# T5 F+ O; R$ V9 @( O: P, Q8 l. N  return $dataset;
0 n/ d0 N% f3 K/ s  }5 j' }. _8 i3 |3 t0 ^9 k
  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
# `9 s: ?) a' _/ ]5 n  echo $i, PHP_EOL;( u/ j6 S. f1 h
  }
' d6 Z/ J2 @4 ^5 T( q/ I  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。- ^% {4 I; ]2 d& w0 |; G0 d
  function makeRange($length) {6 p4 \3 k& V$ d, X) u- k& F& Q
  for ($i = 0; $i < $length; $i++) {0 `! X) Z. T* X2 E8 o$ X! C
  yield $i;
5 V+ t! [: ^; u% J; H% R8 l8 g  }
4 c/ Y, e* L1 S7 `" `& T5 z: V  }/ M  H4 A, V8 S( p9 J7 x
  foreach(makeRange(1000000) as $i) {6 V4 p% ~5 W, Q
  echo $i, PHP_EOL;: \4 h% _. w4 e# J- }5 d
  }. P/ {/ a+ Y5 `4 Q5 ^* M6 M* v* z
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。; C6 O2 @; P6 K- w
  function getRows($file) {
0 v( K3 i9 {$ x& a: @  $handle = fopen($file, 'rb');
) S; k7 D2 ]  v' Q( F. q  if ($handle === false) {7 H! t4 K  u$ \7 ~& B5 r; I, C$ a
  throw new Exception();; P0 j1 N. K: U) K) H* N- h3 P& M
  }( E/ v- G; \; g$ ~9 y: X
  //feof()函数检测是否到达文件末尾+ R# A! O& \+ k
  while (feof($handle) === false) {# V& F3 C+ C; f1 f
  //fgetcsv()一次读取csv文件的一行
+ v7 w0 j. a  z9 \9 @% i9 T  yield fgetcsv($handle);
( t; \$ v/ m3 K: Z; F% |  }, q9 D9 x$ ]& x* S" ?+ K
  fclose($handle)
+ N1 q  w8 M# x4 v  g  }
: Y! {- K+ p2 i4 y. w  foreach (getRows('data.csv') as $row) {. y: O0 E- H& A9 i
  print_r($row);
! R7 i  s0 x% f- S! L  }
0 t4 |7 H, k  Y  e8 h5 z9 c+ o! z1 L  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
' @5 t1 \, }9 H; H( n
6 U- P. \- K5 `  q) P, }1 g: f
2 g6 m4 H$ \4 D, h$ l0 Q% m3 `来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-2-14 05:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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