鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。, Q. p. A9 }- w8 g$ ^4 \& d/ }: O. n
  1.命名空间# m% d1 c1 `- ]$ c7 d( U
  命名空间是什么?6 B+ ?% v" h. `
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
& @2 s" {/ p! h! J0 L# u4 i  2).命名空间始终应该在<?php标签的下面一行。
, P; v+ G. {7 u6 Q2 ~. n  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。7 _. T: m0 O) k5 k9 E: |, z; c
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
: u9 q2 l! Q# r6 e. P; w  为什么需要命名空间?$ E6 f- u8 D/ t5 |& F& P2 C7 ~# h
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
# o, e7 V- U- B8 @  声明命名空间( {; a! z# A. O$ j+ N
  1).顶层命名空间经常用于设定顶层厂商名。
2 w- q) w) e4 v4 Y/ D+ ]  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。' U* \7 z2 W; [3 ~7 l
  导入和别名
- V: h# r3 }9 i2 N, ~6 h  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。# ~5 V% a  e: I/ x) k$ l; W
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。/ w/ k3 f2 _9 d. [& U/ `: N
  从PHP5.6开始我们可以导入函数和常量。8 T" Y& J3 H" O; m8 b8 f) P! i
  <?phpuse func Namespace\functionName;
( E& _5 [1 R/ r; _2 N, w6 M7 R2 I  functionName();
- T- g4 C- K" @  ~% b  也可以导入常量,3 x* B! V- H3 [6 D( C9 N# J
  use constant Namespace\CONS_NAME;! F. z  ]# {! B* a0 L0 o
  echo CONS_NAME;/ n+ R' u: O9 t7 h$ v% |# i
  函数和常量的别名与类名的创建方式一样。
* e# D" r( C' b; N% [5 v; o0 W  最佳实践
$ Z) o" ]: F" W# q  H+ |1 [5 i  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。+ P8 x% |; r" e$ o3 _& x4 n- F
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。" x6 r' e7 r) R. Y7 x# k$ M
  自动加载3 N$ ?( ^# i" J- E2 X
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
* z1 [) Y6 _  O* g2 t; A4 W  2.使用接口7 Y9 x; q$ g# W% Z: G: i
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。2 A8 K6 m! T+ p$ {. h
  3.性状
" f3 E8 R9 C# g  l# k) @' D  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
9 w- g8 X! p+ X' \" `& s  2).性状使得两个无关的类可以使用相同属性和方法。: |- F  @7 Y6 z$ o8 e
  3).PHP解释器会把性状复制粘贴到类的定义体中。
7 {! I+ I. h8 X! ^% H, [  4.创建生成器
; s# e9 O2 W- P( Z6 X  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:& Y4 g" x- @0 U
  <?phpfunction myGenerator() {
7 F% Q3 {1 N  i: X7 u# h( c  yield 'value1';9 m1 C. m: z: }# V% H1 N
  yield 'value2';
1 @+ i9 T( {9 _) U2 r  [% |; Q7 o  }4 R  X' D/ }, K9 J2 _
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:1 U6 M+ n) O- A1 f
  <?phpforeach (myGenerator() as $yieldedValue) {
, y' \0 q9 r0 t; y* e8 T7 O  echo $yieldedValue, PHP_EOL;
: O7 k8 Q7 C& k" r- {" \  }3 S% ~& e& `* P7 x
  以上例子会输出
) u8 G) p) l4 ^3 S$ L4 J6 [! s) h  value10 _& m% a+ F) J. ]) i  U5 Q/ s
  value2
5 y) O$ l. p( M+ D  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)3 b& e% P# E. X% z
  function makeRange($length) {* s* Q1 \/ O* P2 w" X
  $dataset = [];
1 b$ X, h+ E% p$ u" v5 e  for ($i=0; $i < $length; $i++) {* x2 W3 p9 ~. M; ]: [: r
  $dataset[] = $i;6 E/ {. j- G9 {0 x8 J
  }
5 L6 [9 g+ z2 U/ y* H6 \" V  return $dataset;1 m1 d- S4 D7 Z5 q8 g% p7 E! z% p
  }
4 R, z4 V, `2 Y( c& `+ K. e  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
4 g. Y2 e1 O0 k4 y  echo $i, PHP_EOL;
. r" w1 M6 B6 w$ b- B* s  }$ f9 Z, Z" K$ F) @/ t; o5 H3 @, i  K
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
6 W0 I6 L+ i+ k: O6 ?, q8 T6 P  function makeRange($length) {  m- O" A6 M3 }
  for ($i = 0; $i < $length; $i++) {
1 e9 ]" E- {! U. F' Z% U+ L# s1 A  yield $i;
: Y; D  F+ a4 V! l# _: [2 G  }& u4 {) F; J; _" x" R; v
  }
( s8 L8 j2 z9 |5 N4 h2 C1 @  foreach(makeRange(1000000) as $i) {
# k" ~" @+ Y1 a& \6 A  echo $i, PHP_EOL;) q% E+ d0 {0 `$ a4 ]' `
  }! Y/ z  Y5 G( g- ?
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
% m' }4 ]" E% A+ \# `. B5 |  function getRows($file) {; T5 X2 X, ?0 `; J
  $handle = fopen($file, 'rb');
7 a, d! G8 k6 p3 L( p  if ($handle === false) {2 a) k4 t) X* S, A8 [( Q
  throw new Exception();
% c0 W  x4 J) q+ |5 b3 ^  }# i" D+ E' y! Z
  //feof()函数检测是否到达文件末尾
5 z  U2 N: z" u5 G& w  while (feof($handle) === false) {
& Y. Y+ f% v) O% Z. q7 O  //fgetcsv()一次读取csv文件的一行3 ?: H' K! C. `0 B
  yield fgetcsv($handle);
% @2 k2 G% o  @# e: c  }6 N" J. C3 l' ~- Y3 c' G0 |1 G7 q
  fclose($handle)' @% o2 k8 U2 T+ [: j7 g, c
  }
& ~% Q) x+ v: b4 M+ j+ {  foreach (getRows('data.csv') as $row) {4 u. {" J! m7 V1 v9 u2 a) b! G0 G; v4 O  S
  print_r($row);; m, l1 j3 [6 E7 M2 T; v
  }4 d4 N4 I1 o/ R- V
  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。0 i9 q6 k& h/ E
4 t: y; Y( t2 B

1 k; q7 K+ C& D1 ]. j4 Y来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-7-24 14:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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