鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
. I- }: B' |; @, L  1.命名空间
! w: `! {' D/ H# y; w  命名空间是什么?
7 x! R$ k; g$ C  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。( m: R# m/ M! `: k, ~- X2 ~0 n
  2).命名空间始终应该在<?php标签的下面一行。6 ^  f3 J1 x2 q- }$ _8 x
  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。; K4 a5 X3 @/ ]0 Q0 [! `5 B+ `
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。: k( y" w4 y( G) H  K( m! J& v8 S
  为什么需要命名空间?2 G# Y( P/ \6 \( I1 A4 l8 M* Y
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
* V1 \9 O3 [% Y" Z9 G0 L8 H) X2 k  声明命名空间
2 {8 b, `- C, j6 q5 v  1).顶层命名空间经常用于设定顶层厂商名。5 N0 U# L! A7 s1 F: `) j( V  D
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
; ?1 N# s- m2 X# D0 i  导入和别名* ^$ i/ s6 T) y! P" Q
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
% m5 ]2 g& i3 t* z  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。% d3 I# J4 T" m- G
  从PHP5.6开始我们可以导入函数和常量。* K% T, I8 E- X$ R
  <?phpuse func Namespace\functionName;
$ b, r! j  e5 C/ `  E  functionName();& w1 x) K" n3 j! O3 b5 D8 ]( C7 r
  也可以导入常量,
9 U1 x& T" E' }% R1 n, R  use constant Namespace\CONS_NAME;
0 M( V# R2 K; t$ h3 r9 y6 k  echo CONS_NAME;
, Z- x+ }. H' z* N- j0 @- _7 ~  函数和常量的别名与类名的创建方式一样。
8 y6 K/ Q2 m' R( l  最佳实践
) X7 N8 }7 c* T/ s7 X" G* i* }% k  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。6 H& m; w/ p7 s  P  q3 t
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。% F7 l3 c- G, \
  自动加载1 Q6 w9 J: D! F. \1 ^
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
9 S$ A$ A! ~6 g' j  ?# c1 v* u  2.使用接口
: d5 d% z' Y% x' v9 _" a" T  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
" U; Y% R4 D; V* r$ i  3.性状
# w, n- ?7 M1 ?  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。8 p+ U( R" Y2 f5 s7 Q
  2).性状使得两个无关的类可以使用相同属性和方法。9 o3 g0 G/ j, I: N* v
  3).PHP解释器会把性状复制粘贴到类的定义体中。; m3 v( i. m. W% R9 t
  4.创建生成器
. ]+ ]# p: c2 s  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
& R- c2 f! O  e0 r- N% n$ U  <?phpfunction myGenerator() {7 S# h+ f; U, P  }1 r2 _1 K1 H% }
  yield 'value1';0 M" c! e) n8 X! |: X
  yield 'value2';
3 k  Y, f: |- |+ l! I, `# ]' l  }6 V3 [& o8 A- L0 D) f% G9 s8 P2 d- {
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
/ }/ ^* V$ }4 J" Y3 s4 q& c  <?phpforeach (myGenerator() as $yieldedValue) {  ^9 }$ ]/ @9 v# W1 o0 K( L
  echo $yieldedValue, PHP_EOL;
+ p+ ?5 h5 T% E  }
* L1 {1 B% F0 |6 p; E. f" m7 i, l  以上例子会输出
9 b( \* H" ?0 y) c# `  value1  Y: k* y! J% o
  value2
8 ^" |- D. v, [/ Q0 Q  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
& V" i; H" ~" W: d8 e" n  function makeRange($length) {9 n5 g* p( y& i9 G# x% }  X2 S* d
  $dataset = [];9 w" o6 V' l9 _5 r
  for ($i=0; $i < $length; $i++) {
" S( A3 l' j' Z$ S/ `  $dataset[] = $i;! B/ Z6 u$ D; ~  Z7 l3 t
  }
' b& Y# N4 Y% r# {  F8 r, o; T9 K  return $dataset;) O1 I+ G7 b/ T
  }
$ I) b, c" s' O' _, g  $customRange = makeRange(1000000);foreach ($customeRange as $i) {2 I* {$ Y8 L" y  n8 v
  echo $i, PHP_EOL;
4 ]! }4 `; ]# b) x2 I) X  }
' o( ~2 m% F4 A. ?5 q  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
- Y, t, ?3 o, P" }* l8 F, m  function makeRange($length) {
1 ~% h, P! ~  R4 l: c  for ($i = 0; $i < $length; $i++) {
, ?! ~" b& l) ~  yield $i;
, t* [; e& @3 ^( ], c9 i' i: w  }) n( W- u- t: p, k: j. ]  V* q
  }9 {5 ^5 @8 a* L) B0 l* @, \
  foreach(makeRange(1000000) as $i) {1 Q6 F7 O* Z) i6 c# `
  echo $i, PHP_EOL;
8 n" L2 H# D7 s/ \2 l, {  }# {9 x" [& j  B9 W& N; B
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
5 ~. Z8 S) a7 l! O# @  function getRows($file) {
, h9 f. M+ e; d8 m- A8 K  $handle = fopen($file, 'rb');
, H! S0 G* {7 j4 d0 @' R3 p) v  if ($handle === false) {3 a4 u+ I# |' C+ ^
  throw new Exception();! Z4 }( T, J% j
  }, K- l. h- u- J8 g: c4 f
  //feof()函数检测是否到达文件末尾4 u8 l+ }* F% r
  while (feof($handle) === false) {) Y. v; R4 z* }
  //fgetcsv()一次读取csv文件的一行) B- f3 k  ~  c5 r) g+ |' b3 |  K
  yield fgetcsv($handle);
  D8 P* L" t& B; u; q# y  }( E! s' o" A' l
  fclose($handle)" [) M2 c  H7 e4 ~4 i0 Y
  }+ c, }: q4 I( y' n7 }2 x. c
  foreach (getRows('data.csv') as $row) {0 \3 W6 L$ [9 e8 K
  print_r($row);' r/ [' ^2 v& T7 {) @% f! |! {' e
  }2 x% y  K) _6 P4 B1 @$ |
  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。: S* x2 C0 n/ d/ q

4 z; Q. o% L+ T$ c: r
% ~( V1 p& {* s! c6 U; d$ G来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2025-8-20 21:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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