鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。7 U2 A2 K) R2 K) K5 X/ t
  1.命名空间
1 O9 p& X: r* j# E! f" S0 ]  命名空间是什么?- K+ E) `- q  {: h) X5 O, j
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
, F. |1 g& K3 k9 C# W  2).命名空间始终应该在<?php标签的下面一行。
( D6 l+ O0 _: O  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。# V& y) q) S0 O' z# d1 P8 h  S  Q* ?8 X
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。  r6 N8 i% R! O
  为什么需要命名空间?0 A% t( R- k) v- G7 u; f
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
  B- m# b! C$ {! C  `3 p* ~5 v  声明命名空间) z9 }/ e% F' q6 l0 ?. W! G. a
  1).顶层命名空间经常用于设定顶层厂商名。
7 A  j8 _3 r& o. c4 E4 z8 v  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。/ F, o, K: b" B% V( \6 ~) q
  导入和别名% z3 Y4 y) h' i
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。, d; F5 e9 X8 F# \( O0 X# U
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。9 ?: m- Z+ O- @
  从PHP5.6开始我们可以导入函数和常量。
, U6 K7 z6 R; Z4 I) `: z  <?phpuse func Namespace\functionName;$ H6 e, S' ^! Z# x& D, M1 y
  functionName();7 F! {7 X; z( _& g4 s, Y+ |  s
  也可以导入常量,0 ]7 ^  e6 t1 E# I$ u+ _% ]- s8 [
  use constant Namespace\CONS_NAME;
' s7 _+ {) Y* X* X, ^% {( K  echo CONS_NAME;% @2 z# `+ q# Z9 o! u+ o
  函数和常量的别名与类名的创建方式一样。2 _6 s3 y* d0 L
  最佳实践
3 D0 ~6 E) Z* m# r, a3 M, v, k  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。- {2 w# m! C5 m
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。2 S1 v' B, i* N2 Z- `7 ]6 P
  自动加载0 X1 p+ P. y& f, E7 x4 F1 t4 D( f
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。% ~. W, w- v4 d4 I: ~+ A- O9 q
  2.使用接口" s0 |  v( g$ y
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
/ L1 ~' q* R* ]/ w* i3 k$ W  3.性状# Q7 u+ q$ f# ^
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
* C8 S2 h6 [2 V9 z* f) I  2).性状使得两个无关的类可以使用相同属性和方法。
  K" T% N9 U6 o& Z  3).PHP解释器会把性状复制粘贴到类的定义体中。
$ t# I4 b  l& _. n/ i  4.创建生成器/ f9 K' W  w) X  \1 `6 @
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
. |! Y4 ~- b' i: d8 O1 C  <?phpfunction myGenerator() {
, d0 }8 q! l1 n7 G  yield 'value1';
4 R( X" o. Q# D& w1 g8 o  yield 'value2';% i) N+ o* j0 a9 w  R- v
  }
* d- j( @, [: Q- P% A0 o% I" S  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
& N7 P7 F. z6 Q0 t. n, D3 O" t  <?phpforeach (myGenerator() as $yieldedValue) {& v3 D7 i" h, {' L/ E3 V/ J) Y
  echo $yieldedValue, PHP_EOL;
& q! a. n4 o* Y& ]9 Y' O  }
8 x7 o& ^; ^, L, X6 t) P  以上例子会输出
# F4 r, r$ V6 `0 B& a! [) W8 m  value1" @# d' ~0 ^( o1 {7 ]% v: l
  value2: g, p! T) S9 E) ^$ p6 |
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
- U8 L% @4 E8 W$ Z2 Q% ?* f) Q$ \  function makeRange($length) {
4 h. F- D. s' a) ^, p  $dataset = [];
, ^# Q1 J  Z6 q$ `  for ($i=0; $i < $length; $i++) {% a: ~8 t/ Q6 H( t7 Q
  $dataset[] = $i;' W, }6 N9 R. l2 h# e8 R
  }
! H! H) ?3 Q* ~* H3 D1 V4 h  return $dataset;
: {$ D: h. P$ y4 a- a. b  }- h! W2 U$ q) W9 y
  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
  `: K& y, v" F. g0 X  echo $i, PHP_EOL;
/ I" H3 W( L. y  V1 O  }
$ g* H- T3 B9 {: X+ V, |% V3 S  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。3 J  Z4 V2 E! n4 k* f: s' B
  function makeRange($length) {
, s' Z& x0 O- _4 ~" G4 S* Q  for ($i = 0; $i < $length; $i++) {: `. x' |! w3 e4 ^" u+ I$ |
  yield $i;
+ m; F  |. m9 u/ O* Z% r8 ]  }" {7 J9 l! c' y' g7 S
  }
. w& M5 `4 C7 }  ~  foreach(makeRange(1000000) as $i) {2 t5 v: T" R; s! \4 g7 i7 H
  echo $i, PHP_EOL;
: f% ]: j6 J3 F# j$ I  u4 Y0 d  }& X. G& Y! k6 u: G& n
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
" c; W/ R* ?( y+ w  function getRows($file) {6 l( G1 Z3 {5 X; M4 F% ^
  $handle = fopen($file, 'rb');
% C; e. b* F4 o$ F  if ($handle === false) {7 y; z- C& F& r! H
  throw new Exception();
) v$ E/ Z) R/ t: Q  }
; b1 Q# J6 s  n" n1 e  //feof()函数检测是否到达文件末尾
" ~  Q6 L( ~' q, e& e% b  while (feof($handle) === false) {
1 |$ f1 O$ K  o. h  p0 T4 M0 r  //fgetcsv()一次读取csv文件的一行
* l! V2 Y. S& R, A! `  yield fgetcsv($handle);: u& I) ^/ J/ w6 ?
  }
2 F- r: [  D5 J% }) ^  fclose($handle)1 ^- c  q% M7 y$ k
  }) F2 S, w4 X; e* n
  foreach (getRows('data.csv') as $row) {
- f3 ~/ g. a4 h1 B0 c. y1 m* U  print_r($row);
7 m- a" M% P4 K8 e$ B7 m  }
, k1 I0 S7 ~- u5 Y4 d, z& T7 s  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
  F8 G3 m9 G6 Y, Q" B% o
; j: P8 U' @5 V5 _4 S! ?, V8 p  a7 u4 p
来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2025-4-27 09:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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