鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
9 T8 c, |0 A* ~1 k" f8 ^* O  1.命名空间
; e: K  p2 p$ x2 [6 B/ }) ~/ b0 \  命名空间是什么?
2 e$ s6 ]- B2 H2 v5 C( L7 G  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。) ?' A2 t7 v7 Q) {
  2).命名空间始终应该在<?php标签的下面一行。
; o5 S7 b- E" Q. m# m7 r  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
$ O$ b6 _' u( j  K2 S+ u  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
' w- X1 H+ p& f: o7 e0 b- M: i  为什么需要命名空间?+ A; k# y/ ~+ R* g4 x9 B+ t7 c1 m
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
9 ~2 v1 m; b/ p+ T  声明命名空间/ n: a( w) o5 [4 R+ F  ^  Q( y6 L
  1).顶层命名空间经常用于设定顶层厂商名。: O1 O2 M5 [. Q  B6 D) x! O1 E; U5 Y
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
8 w! V$ Y. X' Q4 k& ]5 K2 P  导入和别名: @2 L" O1 \% M5 }
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
8 r0 i( Z0 s* Q3 P9 k9 h  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
- f; `/ ^  K& t  K" |/ F' D. C  从PHP5.6开始我们可以导入函数和常量。% W! {" f$ ]8 R* y0 X
  <?phpuse func Namespace\functionName;$ ^8 A& ^/ U/ r
  functionName();
4 B# ?/ w" E* j: A+ L4 g. R  也可以导入常量,, k' B2 S# ~' S5 m, U0 }2 \
  use constant Namespace\CONS_NAME;3 J) W1 T/ }) L3 s
  echo CONS_NAME;
0 {8 e1 `; B% `+ b: Y  函数和常量的别名与类名的创建方式一样。
+ `4 @7 }' N+ G4 m  最佳实践  J! Q+ N4 R$ z1 r: H' r: N
  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。* K% W" a0 a1 T. x' |+ P, @
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。' S. B4 w% G, ?
  自动加载
, ]+ @/ q" ?+ _9 X( s: k, G  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。$ X# c7 J; I( U( R( k$ Z( ~% F
  2.使用接口  L( {% W6 }# i( [
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。
$ U& Y5 I1 N5 z6 b0 g! _  3.性状: |  c# X; c; [0 H% ^) y3 p
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。, K) J6 I! ]; d. m: T8 ^
  2).性状使得两个无关的类可以使用相同属性和方法。
% D4 T, M, s; V" d$ o4 |  3).PHP解释器会把性状复制粘贴到类的定义体中。
) G; B9 a, E3 P  4.创建生成器0 t4 I4 D4 _: L) e5 |$ t
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:
& L1 ^  u/ t) z5 Q! ?9 I, p! i+ T  <?phpfunction myGenerator() {: v* J$ @8 O" E* C! D
  yield 'value1';
* c; W: `/ z$ l0 |# v  yield 'value2';+ K- D  H, N5 V: V1 _6 v
  }
) r- q" w8 G: Y  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
: w1 {: X2 w3 t7 `) `1 Z1 a& G  <?phpforeach (myGenerator() as $yieldedValue) {
; E$ u6 i& v+ P7 w% A  echo $yieldedValue, PHP_EOL;. p5 L. r  S( k9 X
  }
& [# U( [+ }$ c  以上例子会输出  {/ i& z! ]% b' P! v
  value1
( F9 H) u0 P1 R8 o$ b4 w2 J7 Z  value2
" U& ~' d" O+ X! o% d/ Y& E  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
. l! @7 `' B3 s1 h. n: V  function makeRange($length) {' b5 ^1 y6 ]- }8 {$ H2 ~9 i
  $dataset = [];
; K7 G" w1 Q: K3 Z# ]  for ($i=0; $i < $length; $i++) {
7 S7 F( M8 i- P# {  $dataset[] = $i;# V7 m5 r# }2 z- L# O, i# ^! c$ h; M
  }4 L5 l3 F/ q- v
  return $dataset;/ L1 ~0 _& f1 \# V; `4 X7 T" C
  }* H" R# S* w9 h* O3 p. B
  $customRange = makeRange(1000000);foreach ($customeRange as $i) {
- u. i7 u. t: h3 z0 ?  echo $i, PHP_EOL;( g4 l# m& F7 D6 W+ p$ H
  }$ l7 l2 ]4 k! C* q$ \8 B+ F% i5 O8 h5 j
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。6 `6 g  Q1 g4 y" r- _* D
  function makeRange($length) {) ?; c* U, }; ]! J
  for ($i = 0; $i < $length; $i++) {( C3 e& W* |: [
  yield $i;, q9 X! l8 A: j; O& o1 \0 i
  }
9 E) L2 m3 ^9 V/ f3 Q  }
! b) m0 k  @7 W8 L) {- o0 m; ~  foreach(makeRange(1000000) as $i) {3 p' ^  f( T* C* q- k+ X
  echo $i, PHP_EOL;8 o" E9 F# D* O( |& {
  }
  k( ?# V; B+ |: E0 b  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
% H8 b! H0 R4 W" N8 j" @  function getRows($file) {
( n+ _7 E; ]& j) a  $handle = fopen($file, 'rb');6 k* }/ u! F7 ^$ g% z- {: y' w# a
  if ($handle === false) {
" e8 p% h. k5 S' N+ r  throw new Exception();
& ]- P0 D4 B+ R, w+ T3 s( e# h2 V& E  }
9 q, j; w; j& N7 K: a" O1 s  //feof()函数检测是否到达文件末尾/ @6 O! }1 L* d" Z7 e9 v
  while (feof($handle) === false) {
% ^8 w* F1 m! R/ E  i  //fgetcsv()一次读取csv文件的一行
0 L9 s( X1 l- w# c  yield fgetcsv($handle);% ~+ z' w; o8 c+ |0 |
  }
  e) S9 H( k. k) J$ f6 [) G% L) L  fclose($handle)2 w3 _5 o. u+ r9 `$ r, u  G' v
  }+ d' t1 v* c$ S2 d$ N$ u
  foreach (getRows('data.csv') as $row) {& l% W) m7 N; ?0 y$ G# `" f( O
  print_r($row);' F8 ?. v% G; h" }; G4 a) {' Z
  }
1 i4 t- V$ V4 S  X/ a! m  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。/ A/ y1 E7 j: e2 T7 K

; r! ~1 u) C4 P8 d! z  F7 b, t
: H, \8 r$ m  N& O) t来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-7-17 13:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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