鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。+ {" }4 Y0 C- c; q( p$ Q( ]# O
  1.命名空间! y, u. v+ s4 J, [$ R7 Y+ @* \
  命名空间是什么?# |- x3 K8 b) G! J! g3 N8 l+ Y
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
# [7 z8 W1 z5 }, K" x  2).命名空间始终应该在<?php标签的下面一行。0 g" M6 r3 k- T
  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。* R( e/ L* Z( w2 {! X! i# B
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
0 m4 A6 v1 V! w3 h1 m& U5 s  为什么需要命名空间?0 c1 G* m! y( I4 w/ F+ c
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。" {+ U$ n- L- I( Y, A
  声明命名空间, o- N* {7 r+ A, U7 u0 G3 k3 U
  1).顶层命名空间经常用于设定顶层厂商名。1 m" P* J+ c; O- t5 j# e
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。0 Z) ]4 ]9 s, |* A1 }
  导入和别名
  Q9 @& g  W. d) {' S  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
( D5 b! a" Z, ^& ?" w7 E& U& y  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
- n" [% U; m& Z6 k) ~7 N4 b8 F" x; e, Q  从PHP5.6开始我们可以导入函数和常量。7 N( q0 q& F4 u4 d
  <?phpuse func Namespace\functionName;, r( _) z% K( z
  functionName();
) e( M( Z# }# R8 t# t) U1 r  也可以导入常量,
, c' n- {# v$ A* w) O0 |  use constant Namespace\CONS_NAME;
+ V* K3 k5 V! P0 x6 a2 k$ [0 [  echo CONS_NAME;. D5 E, P0 J1 n5 {+ c+ |: N
  函数和常量的别名与类名的创建方式一样。
# y' W6 a7 }5 l& W" A$ n% D0 Y  最佳实践
3 h1 j) |+ b9 X( X& S. D0 D- u  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。3 P' H  Y1 Z6 N; E" a
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
* ]3 e( z1 T9 Y, |- v  自动加载
# u6 P& H3 _8 j  ?0 A  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
4 Y* Y) n$ j3 T6 c  2.使用接口
' K' F* p* n% P0 K8 g1 r  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。& h) l1 ]4 Q1 r2 W
  3.性状% N0 L' U* i) _, J: z
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。. K# A, `8 u, A- F
  2).性状使得两个无关的类可以使用相同属性和方法。3 n0 @; H3 H, q  O, {
  3).PHP解释器会把性状复制粘贴到类的定义体中。
3 R  V+ x! P0 |& ?0 L. n1 r0 o6 K7 M  4.创建生成器6 g1 B/ V2 h4 |: z6 [! C
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
2 {) h& |3 K0 Y  x6 M4 [5 [  <?phpfunction myGenerator() {2 V- M$ E7 ?2 R, v7 n- t0 J' r) }
  yield 'value1';
$ {# ^9 N7 B) |5 U8 k  W  yield 'value2';7 D: {% ], T2 S4 Z1 |
  }7 Z& [% T0 J' A0 _! J( O9 C
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:! P3 T+ q- i' f9 ]8 ]* G
  <?phpforeach (myGenerator() as $yieldedValue) {
0 Z/ o. I: U$ L# Q+ ~  echo $yieldedValue, PHP_EOL;" s' ~" i# ^* {) R
  }
; g# y7 s) @0 y& F  以上例子会输出
# o) q- k$ R$ y- B  value1& i9 [: L2 o( t# f
  value2: J. f! c3 \) l7 v+ T8 m
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
, R0 t% r' \/ y( k3 x( N  function makeRange($length) {
, ~. F! M) L, a) o3 r  $dataset = [];  t+ U3 O, l( o' W8 @& v' [, L# h
  for ($i=0; $i < $length; $i++) {. W, _" _$ Q- c9 Z$ z; I
  $dataset[] = $i;$ Y. T# w& w; F! L7 ~
  }6 P3 q9 q/ m" \5 o, \
  return $dataset;! J$ a/ ?) C4 ]# e  d
  }; x( N, `: a/ c3 |( h
  $customRange = makeRange(1000000);foreach ($customeRange as $i) {* z9 {# e& u+ f( c8 Z% y
  echo $i, PHP_EOL;
+ V2 D, i: y, `/ x0 P2 ~& F  }
% e$ p0 O; R5 u  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。: C% T9 u5 v1 N: S! D& |
  function makeRange($length) {' B8 `5 f# n9 ?  k, l# H8 O
  for ($i = 0; $i < $length; $i++) {% l5 A2 t* w+ ^; K# y0 v9 x% E1 D3 g
  yield $i;
# y) i# ]) m" Z  }
/ z/ e/ O! ^$ s: _  }
6 e' Q/ U8 ^. g) s, `3 |  foreach(makeRange(1000000) as $i) {
! A' N; s$ @9 }1 a, b' I" `. D% P  echo $i, PHP_EOL;" {! i$ `6 e8 h0 I0 C
  }
2 h1 s: n  r: N& _/ z  t  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。1 t3 S2 j7 ]/ m. X2 j
  function getRows($file) {
6 a+ @3 U4 h) R  $handle = fopen($file, 'rb');5 c; M! G; {: l3 _' n
  if ($handle === false) {. e9 K3 _& [( i+ I6 l6 J! w
  throw new Exception();/ T, A# M  @5 ?: [- M
  }
# E: r7 Q5 o, \6 U! ~; Q: J) b" ~  _  //feof()函数检测是否到达文件末尾6 |8 Z- i2 W+ Q7 O
  while (feof($handle) === false) {
% Y) z( |# k5 b8 q! @7 N9 g  //fgetcsv()一次读取csv文件的一行0 t- m/ l2 v2 B% `
  yield fgetcsv($handle);
) I6 F0 _: E9 u( p. H# I* B3 H1 s  }2 X$ O: w- Q4 @. Z+ G# |+ ?
  fclose($handle)
$ o: y- m0 p$ ?: S- l  }/ |: p1 u& u- F8 y5 w% @
  foreach (getRows('data.csv') as $row) {
3 b' j# K4 M8 u3 z4 Z$ T2 ?8 C  print_r($row);& |5 Q! ^9 f) m5 H4 ]
  }
& `: o# A& w2 o6 x& ~  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
" r+ j% \$ K0 @# I
3 s* c! D& ~1 N) s7 d* r/ z4 M
- }2 m8 E( G$ R; k. N7 Q3 v来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-9-19 15:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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