鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。1 t* q6 ?. I8 B+ S6 b4 o
  1.命名空间
: d! u% R, Z7 _  命名空间是什么?1 u! f! ~# h6 }  |( g% M/ I
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
  I# v2 w: {0 r- c& N  2).命名空间始终应该在<?php标签的下面一行。
9 T* s. z% J; \: b# M  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
5 ?$ ?$ i( N+ W8 t1 J9 i  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
# I6 }' l' g0 Z' Q  为什么需要命名空间?
5 K; w9 ]5 c% t% [  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。% n$ _* r# z  l5 S2 r. d! Y
  声明命名空间
7 ?3 o- q+ |- ]5 I9 U  1).顶层命名空间经常用于设定顶层厂商名。1 r! T( X! p  s. O5 A/ H4 w
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
6 V# Q5 E2 {1 t, d: O* s  导入和别名
2 N+ p- n0 h" z* Q" H  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。; R! U4 K; ^0 \7 w4 C
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。) }% T6 o1 u; Q0 G
  从PHP5.6开始我们可以导入函数和常量。; g' K" E- ?: l
  <?phpuse func Namespace\functionName;
4 ]& P  @! Z% p2 T2 P6 b9 l  functionName();
# u9 Q1 G+ |( r0 |6 B  也可以导入常量,
+ C# c$ j2 L! f3 n. O8 C: V6 v2 J1 I+ m$ M  use constant Namespace\CONS_NAME;
2 X( I; y6 X; w$ v% v  echo CONS_NAME;
. V% F6 @, S( H) K  |5 ^  函数和常量的别名与类名的创建方式一样。
  x- @4 _/ Z5 `  最佳实践
! k+ J# u4 @: S) j% r7 q6 Y  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。
' b7 W6 }  u6 G( U0 L- F) Q, z& q  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
# B: E6 J. F! m; n4 y. ^% U' d  自动加载
. E; ~0 |/ p. L# m  j- i  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。0 a! W2 t$ l; q, D( q
  2.使用接口
2 w( S) g7 r' U  N/ V) T5 n( D  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
/ N" D+ i4 W& G; P. r+ B+ H  3.性状
: L1 i' S7 O  K& \  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。: t! r8 @" d6 z* j$ g( i: F2 Y
  2).性状使得两个无关的类可以使用相同属性和方法。
* D6 c  X) J% J& k! z4 O2 d  3).PHP解释器会把性状复制粘贴到类的定义体中。" _: t' A- r7 K7 G# U
  4.创建生成器
1 u1 u) {0 t. B9 ]. ~6 ?- I  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:+ P$ H6 O: \( L2 ]; F
  <?phpfunction myGenerator() {  ^! W7 X" x8 o. ?* _
  yield 'value1';
. E  X1 X$ G# e6 z  yield 'value2';
7 k; I2 m  ^% l/ _+ N! Z5 [, t6 F  }5 R  p( Q: {1 C( ~& {
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:- b3 U5 y4 H! C4 G6 t
  <?phpforeach (myGenerator() as $yieldedValue) {: J: w$ }) Y2 W  b$ \. q7 Z- V  t
  echo $yieldedValue, PHP_EOL;6 }- m* m+ I9 {) _/ Y* z/ z8 j9 j
  }
6 o3 N. e. A9 E# J8 H  以上例子会输出
) o/ ^0 Q- Z$ O. Y  value1
* ?4 i- j3 w3 j+ p) k+ S# D, B  value26 J" y) ]/ F9 j  I, M3 Q
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)9 w6 [6 @. o7 y2 F3 `8 X2 n
  function makeRange($length) {* J: [" i+ v" j1 f/ l4 \
  $dataset = [];- O; v$ Y  h5 H. \) ~
  for ($i=0; $i < $length; $i++) {4 G2 X$ s0 t. w0 e4 `
  $dataset[] = $i;
7 a% g- Z3 Y+ l  @, b5 u8 z  }+ _7 ^8 ^6 K& i% a- A
  return $dataset;
' ^  F& v1 W0 o4 v7 X$ x! C9 O  }' I" Y9 a0 {% p- `  i
  $customRange = makeRange(1000000);foreach ($customeRange as $i) {5 G( z* z& n, Q* T& _4 a& G) O9 b6 Y
  echo $i, PHP_EOL;8 [* P6 a% i$ Z/ U  n9 @
  }
- v7 f9 L+ Z2 ~) T/ S; d+ C0 Q7 g; R) C  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
2 l- G! R) q' @$ s  function makeRange($length) {
/ ]. S- A% S. g- {  for ($i = 0; $i < $length; $i++) {
* E8 a" {% w  h  yield $i;- |  b5 {. u* w+ P* w
  }
8 A% f# p0 E1 D- W6 {, P9 W  }3 T" G4 k7 ]( P3 Y: |5 @
  foreach(makeRange(1000000) as $i) {5 L* D- ^/ l; k+ R! ^- M7 s
  echo $i, PHP_EOL;# n  G7 J( Y/ @! |1 h
  }
* W: [* \0 S/ m  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
: J- v8 W1 F! r9 |" b5 |  function getRows($file) {- ?: s" n; I" n/ s( h
  $handle = fopen($file, 'rb');1 M% ?/ U& ]3 ~
  if ($handle === false) {+ J3 t9 U. t; v7 ]& v1 o
  throw new Exception();$ D( ^2 q1 F& L( U
  }
3 R- ~% d! d* ]' |1 f4 s, {7 }+ z  //feof()函数检测是否到达文件末尾
' L4 q0 S4 H! U6 l  while (feof($handle) === false) {
6 [& G# h% `' o0 m) v3 K5 l, k/ ~  //fgetcsv()一次读取csv文件的一行
3 C5 ]7 ?, m2 E& U' Z  yield fgetcsv($handle);2 G) |" C$ N* P3 C6 D
  }
) l4 _& y* l' R2 g; Y  fclose($handle)
3 h+ B9 p# k/ G* a% w' x. T+ a  }
8 ?. l8 p* l$ H  foreach (getRows('data.csv') as $row) {$ v1 o( P0 b- e
  print_r($row);6 k: @( X7 Y+ N5 k' _
  }8 w1 o9 g. i) \+ z! H3 j
  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。" o& \6 B* y1 Y  r- \$ @# ?

/ K; N" u2 F' `2 B. ^' R/ P8 B7 Z5 Y7 f: n  f, V9 O  ^" a* s
来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-4-25 00:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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