鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
! {- G1 x% Z5 E( S5 b" O4 E* R' o' o  1.命名空间. v+ I, }: z+ J) X8 ~5 w
  命名空间是什么?
. B4 w' B: c+ a) F9 p1 Q; b2 D  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
, f4 S6 Y- g0 B$ B" G  2).命名空间始终应该在<?php标签的下面一行。% z+ |7 f& [5 V) y6 a5 S
  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。) v# b8 M, O: I3 G* F$ b9 D% g
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。6 l/ s( v/ y- L1 E; e3 n
  为什么需要命名空间?% S8 P7 R" @5 ?9 e" g
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。9 T: V; e  Y% n" Q) ]
  声明命名空间
3 L7 U7 ^; D/ H- J; t. b, L9 K1 B  1).顶层命名空间经常用于设定顶层厂商名。# R. d* A. [( j
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
# B) }% t9 J" C( B8 s  导入和别名
) \+ d0 n8 G! P, ?  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
9 W7 O  C; u0 G) U5 T9 _  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。% }& l5 e* U& `0 Z
  从PHP5.6开始我们可以导入函数和常量。
- K; n5 j" E% e  <?phpuse func Namespace\functionName;8 q0 Z% A7 T/ z$ x
  functionName();
* ^! r* h$ v/ ^/ l5 I9 J  也可以导入常量,) k6 C# V* O( g
  use constant Namespace\CONS_NAME;
: A( ^/ ?0 g  U, w$ N& V; i( ]3 b) a& d  echo CONS_NAME;
$ Q2 g! G, ^0 q5 x  函数和常量的别名与类名的创建方式一样。$ ]2 Q- V  v1 J! G1 d: P6 X3 e: g
  最佳实践7 e2 O. {  _; q8 {; u
  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。6 f( E  W1 d  {0 c
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
% `$ Z% z6 Z' h7 f2 H$ k  自动加载3 k! @1 P  x  \! v% l
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
8 l6 {( w% `9 R4 B: ]  2.使用接口
+ ?& @2 q  H3 i( R2 A  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。9 N/ Y. X! L& r9 p: M: R$ k
  3.性状" \- P- `$ [- }9 p7 i8 ]9 {+ f
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
$ m: F& O, r( D. j' _# ^, O  m  2).性状使得两个无关的类可以使用相同属性和方法。
6 d, d0 B: \5 V3 r1 ^3 c3 [3 r  3).PHP解释器会把性状复制粘贴到类的定义体中。
* k& Y8 Q0 N9 ^1 E  4.创建生成器' S8 I# G9 k' y# c/ s; s
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
! u0 x, E8 j1 h4 y$ Q7 `8 x  <?phpfunction myGenerator() {+ W5 w% }# ]# J3 M" K
  yield 'value1';
4 z8 X. x7 b" T* v9 t  yield 'value2';( S% d$ n4 f- \! a
  }; L3 i% j$ G" ~/ |
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:7 t* H6 l9 h# J: c
  <?phpforeach (myGenerator() as $yieldedValue) {
( z" f' X& W% w& G. ~. b) k  echo $yieldedValue, PHP_EOL;
3 J: P& I7 r' u. S  }
- _9 t2 V$ q% F6 @' t  以上例子会输出6 l; [( u/ g- x9 S+ U; t$ k1 }( S0 u
  value14 T3 W  w: ~( `- l0 l
  value2. V+ c  f! j0 g2 t' F' [( q+ T( A$ P
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)" @% }" P* y7 X7 s# x( w3 t& p7 u
  function makeRange($length) {+ p1 B1 Z( Y2 f8 U
  $dataset = [];3 l7 Y& s9 U' L$ e  ]2 J* ^
  for ($i=0; $i < $length; $i++) {
) x/ j7 W, X# L' T8 L& {  $dataset[] = $i;% \& n9 c6 d1 ]; d1 g4 w2 ?
  }
& }4 b. z' C1 {& K" ?  return $dataset;
- g8 `4 p7 D  n- P2 w  }
/ @3 w: |- r/ O+ V/ l6 }1 {  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
8 c( e$ X" l: p' s2 u2 u9 O2 b  echo $i, PHP_EOL;8 q" I0 F( p7 H2 k, V8 }
  }; h0 m# W& L' A# Q6 Y* [! C8 C! J
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
9 f- |) l& i7 _0 ?( Q$ T+ a  function makeRange($length) {
& B7 b, e0 J+ j: m( }8 A: `  for ($i = 0; $i < $length; $i++) {
" m1 f! _# ?2 l% i. u  yield $i;
! }4 Y: |5 r6 _0 k$ z  }
+ h* U6 |6 a- u3 J8 y  }  N: R- q( V' v) g* l# {% S3 s
  foreach(makeRange(1000000) as $i) {9 h: W& n) I  b; Y7 Q* P
  echo $i, PHP_EOL;% c3 Z. w0 @( W2 v% ~
  }; m& O6 m, O# P
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。6 d/ R  W' Z8 T  x; {
  function getRows($file) {
5 j, k5 N# N" Q5 b/ o  $handle = fopen($file, 'rb');
# K; f2 d! Y) M; [  if ($handle === false) {( q. i2 X9 K. t
  throw new Exception();, g, d/ f6 v: v, N9 c& M& D
  }
# A( h5 \# V. L, K4 o  p: I  //feof()函数检测是否到达文件末尾! H4 U2 c5 I$ ]$ Y
  while (feof($handle) === false) {4 u- s  ?( X9 }, q) a
  //fgetcsv()一次读取csv文件的一行
9 b/ Y1 ~. a) y4 u& d2 L4 h/ _/ k. D  yield fgetcsv($handle);$ D& j; ^! G" g
  }" x  q1 T, G1 M7 _) I" U1 m3 \* b* M
  fclose($handle)+ s5 S# o" `7 u: z0 p/ V2 W7 U
  }
4 q9 |3 K  _( v  }  foreach (getRows('data.csv') as $row) {$ t3 r- Z+ Z7 L* W% B+ Q
  print_r($row);
  }! k6 Q+ b/ i5 a; [5 H' C" y  }/ S4 a- c- {5 R+ O& ]# p3 C
  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
- O% S+ G  S# ?; n/ F/ ^7 V' \5 S! T
! y: j. H/ O2 C+ ?
! r$ K: Q6 v* V% b6 p: v5 U6 L来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-1-9 17:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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