鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
6 }* d+ L/ p/ I' l  n  1.命名空间0 @( ^1 V* ?. Y! }5 t" o9 O
  命名空间是什么?2 M: n6 Z, s% j
  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
& G3 @% s1 Q8 M  2).命名空间始终应该在<?php标签的下面一行。
+ Q9 q1 }. v! I  `5 H9 c' l9 V  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
0 y+ ?% \6 L: `0 j( V9 A9 p  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。' f1 V) I0 w7 e  S& z0 ~' P+ t' g3 @
  为什么需要命名空间?1 @/ f0 ^8 Q; e# A" x; a
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
( d. ~. G+ a% B  声明命名空间$ g. y9 C1 p+ ?+ r
  1).顶层命名空间经常用于设定顶层厂商名。- O+ x7 a& b, [8 D$ L
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
) j8 v& D: O- b, E: ]& J! m  导入和别名: K' k4 d" f' ?+ b1 L
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。2 }& }6 Y, e2 `7 S% B% P5 B: \
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
! X1 n' |- |5 T1 o8 R: F  从PHP5.6开始我们可以导入函数和常量。/ c9 p0 e' A1 t$ L1 f) C
  <?phpuse func Namespace\functionName;6 A$ n9 e' ~$ ?& r8 p9 V% o
  functionName();
$ q2 o: O) u; L, \  也可以导入常量,, N9 r) F$ w0 g2 s7 f
  use constant Namespace\CONS_NAME;: r; U. v- ^) k% s. H. g5 g# L
  echo CONS_NAME;8 A$ }$ x; `" w$ X8 W- _  |6 P
  函数和常量的别名与类名的创建方式一样。6 j+ Y! i  s" H8 G1 U) }
  最佳实践
/ G" t" ]- c2 a; T' l6 e  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。5 a4 P, M" [! H5 G% Z9 s
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。, R, f8 }. \( b  g5 K0 m% ^8 c' J
  自动加载) _9 G, G- o$ E& L
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
" ^7 l5 Q' m1 U  2.使用接口( h/ |( f4 E) _9 M
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
  o$ {& ]$ I" t& k% i  3.性状
2 C7 S0 a  F8 n, P; _  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。. E" X6 W( g# ?' a8 l
  2).性状使得两个无关的类可以使用相同属性和方法。
8 a' A0 b, m) O  3).PHP解释器会把性状复制粘贴到类的定义体中。
4 j# i$ \' A3 \! b  4.创建生成器
6 o, H" E( O& v' h2 }( j) b1 B  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
; O3 v: C0 W. {6 g  Z6 f) h) J  <?phpfunction myGenerator() {. m) r- u" U) o$ Y
  yield 'value1';
2 ?2 H5 b* [: p* ~" d  S8 {' }! C  yield 'value2';
7 O' z1 n+ v2 |0 H  c) O7 k( `  }
9 L/ y  U  f2 s6 b, K  M" b5 c  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
$ N2 ]2 X7 S7 X( G  <?phpforeach (myGenerator() as $yieldedValue) {! l8 T. K3 t' [" ?8 W
  echo $yieldedValue, PHP_EOL;! P/ M" l) |! U, F5 N. G6 X4 G- J/ A
  }% |) m# ?8 T8 p# v2 o8 w
  以上例子会输出  @) i9 V/ _1 e* f4 P# f
  value1
- L1 J% ~; d( g  value2$ E/ m6 t, W% F$ w/ m7 n: Y6 L, M
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)) N( ^) L/ B+ j' @/ w
  function makeRange($length) {) L8 G7 _7 I! Z, [/ Q0 a% r2 ]
  $dataset = [];
0 t( m6 n5 L& Y: F  for ($i=0; $i < $length; $i++) {: Y& Q1 ]7 r6 K* y- o
  $dataset[] = $i;
  I& N" M0 H& A! a# z6 w5 Q2 v  }  k  ?2 Q! N, g4 M* {8 l$ V5 U" P  ?
  return $dataset;
; w, o7 |9 L: G0 v; {% t8 X  }
$ h; l, X5 ^2 m6 `' I  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
: m$ R4 j9 ^6 s9 f6 Q  echo $i, PHP_EOL;
3 V3 G* |# F6 ~+ y7 |5 ^  }2 V3 `8 E, w0 I- s% ]
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。  v9 E3 a8 ]+ g) e
  function makeRange($length) {
5 k5 g5 ]+ {3 d; A. a: i/ s; h7 r  for ($i = 0; $i < $length; $i++) {
& W* e; ]. C7 N1 X% q% u, A; j  s  yield $i;
5 a- Q- G0 Q6 W  }
3 `5 H; m, J% D) m- X7 P- ]  }
- \8 j' e! B/ n, O5 h! S, T& n* W  foreach(makeRange(1000000) as $i) {
9 L* e& _# a2 T+ n$ }  echo $i, PHP_EOL;2 E, ?; V  y# ^8 T' K) a/ v
  }
) e' F3 r9 |5 Q5 J# r7 x  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。, }# f1 v( f" p) n/ C* O4 r" t0 |+ J" `( ~
  function getRows($file) {
& g/ T5 {5 h& Q3 n  $handle = fopen($file, 'rb');/ G* h6 Y4 E4 p! ^9 s% m
  if ($handle === false) {# z- h; R2 x) [$ ?. v
  throw new Exception();
) {* r! P; `7 I) ^5 o. @  }3 |5 ~; F4 o* A7 v5 D! q$ K/ M, @7 E
  //feof()函数检测是否到达文件末尾0 ^) d9 ^# a' e
  while (feof($handle) === false) {
5 m/ `7 u0 v% y4 T/ W  S  //fgetcsv()一次读取csv文件的一行' V9 Y0 L9 K. u0 Z5 {" Y
  yield fgetcsv($handle);
+ F$ X* \" m# g9 K* ?% q  }
& b9 H- T# y% J- v0 d/ _3 h+ b  fclose($handle)
. M& k! `1 O+ Z  }
) ]  g( K0 y  C# e- ^6 z  foreach (getRows('data.csv') as $row) {
4 l. }3 _! R  A1 Q+ @; n4 q  print_r($row);
* s: w7 k$ O: b2 W; F  }' c3 r5 F2 m, T8 k# g
  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
( t# _/ k4 a, l4 y9 H: W$ X5 m& @# t

. W( [* D, ~( ?来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-1-29 23:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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