鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
, h$ o. s+ ?6 ]& p% A  1.命名空间
- J9 O! M2 i0 P( S% p( T  命名空间是什么?
+ @3 C! ^0 k5 j, t" D- a  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
; M. M0 M* f2 r- l- y; j6 S  2).命名空间始终应该在<?php标签的下面一行。: d6 h% v0 w* d4 t* J+ L$ x
  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。0 |3 c2 r6 `# z8 y- }' J' r) [
  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。9 B& W8 e/ d* q( M6 U, k2 ^0 }6 [
  为什么需要命名空间?
! v. W2 P1 T% o$ k  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
* ~: ~9 O  m, v  声明命名空间- N% h3 q3 h2 _4 w/ D2 E% m
  1).顶层命名空间经常用于设定顶层厂商名。
' T. b9 d+ l: ~  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
% J  C7 ~7 o# u  导入和别名2 @6 d% Q, H- d- T' ^. u8 F
  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。3 C/ e) u* e4 Q' B5 {. i
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。) F; E( S. }) t& R+ x2 {
  从PHP5.6开始我们可以导入函数和常量。0 y9 u2 z7 C, ~
  <?phpuse func Namespace\functionName;
0 P+ j2 @) d/ B, E  functionName();1 j* Y; d" w/ |+ V7 B2 X
  也可以导入常量,
5 o- o- B+ `: m: M. b; T- x) ]( N  use constant Namespace\CONS_NAME;% X) a6 @7 ?8 j9 L1 [
  echo CONS_NAME;
  r8 t8 k; z* v  函数和常量的别名与类名的创建方式一样。
2 i2 M  T1 _7 m$ c" _3 Q/ {* Z  u  最佳实践4 x3 l9 V( i8 X3 {# S. Y* e* c% h
  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。$ v# J( f" c/ V. C; s' j& H
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
+ i/ f. \& d3 ~" i! X  自动加载* T* e" T' N+ w3 M8 h1 S* @/ K
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。" U1 J( E% U9 `' c: g
  2.使用接口' m5 J5 r0 o- [
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。& G6 a. ?2 ]$ B  ^" N
  3.性状- r& l4 m! g# c/ L4 B2 @
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。' V& v9 }2 Y/ G% y( T
  2).性状使得两个无关的类可以使用相同属性和方法。% m7 h6 U1 X: H1 @% n# }+ }9 [- V
  3).PHP解释器会把性状复制粘贴到类的定义体中。4 W- y+ @- s/ a$ J0 b$ @
  4.创建生成器
6 o- W+ |" A: l4 e5 _( _% E" F3 O0 R  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:; W4 ?8 y$ T8 u) h; t6 j' W
  <?phpfunction myGenerator() {
- _. u  H9 f& \" d  yield 'value1';& c" V* \, [( [7 ^5 @
  yield 'value2';
' S3 z% N/ K# l) Q1 o" B2 K% j- x/ @  }
! [7 c. K3 }) J# B0 Z; O  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:. D9 ?- C4 S9 H* k
  <?phpforeach (myGenerator() as $yieldedValue) {* r$ q/ |. T, p# A8 o& P
  echo $yieldedValue, PHP_EOL;9 _* v5 V- j$ r" p
  }- F& _& Q0 @7 u" [7 w( x% j
  以上例子会输出* L( \3 J- B- e$ }" v. Y
  value12 K8 `6 C- z" c9 w( D/ Y
  value24 e  L* U& h% t" ?2 T& }* y% B
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式): d  F7 E3 Q* S5 I; x7 N) K: P
  function makeRange($length) {, R- h) e* @5 d. d
  $dataset = [];; E! m# w* I/ F( }% }1 M
  for ($i=0; $i < $length; $i++) {
. m1 o9 A0 Z. c. Z: e8 T3 n7 _  $dataset[] = $i;
& f0 p+ m. F* `/ t/ o* c+ P  }6 |, D$ Y- c# B! m; ?* `- X
  return $dataset;
/ e+ F* O! h8 u$ [, R5 i6 U  }
2 |4 n) D% ]" n9 [& D  $customRange = makeRange(1000000);foreach ($customeRange as $i) {2 P+ w: z+ x- d3 V) q3 `
  echo $i, PHP_EOL;
& j' E- X/ }- H  r7 B  }+ u  f' E; J  p9 f
  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
) j' k5 j9 N; x% b6 _  function makeRange($length) {* w2 [2 x5 z  b1 b* {+ S) G$ @
  for ($i = 0; $i < $length; $i++) {% V8 @. ~2 Y/ v5 _& V
  yield $i;/ S% v2 s4 L" l  S" T5 Q9 ~4 q. Y) B8 `
  }0 N6 U" \3 F1 _1 t
  }. z. w5 I) B! ^, w# O& c# _
  foreach(makeRange(1000000) as $i) {3 Z0 v) W  ?2 A* i5 b
  echo $i, PHP_EOL;; m  S* I. i' u' l) c$ i* C4 K
  }
; A6 ]# Z9 ^6 h% Z% }  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
  C2 p7 o3 v% |  function getRows($file) {
- C! m/ R2 _' ^/ o$ u  $handle = fopen($file, 'rb');' O3 B6 {* A0 g; W4 k/ C
  if ($handle === false) {, S& Y; V7 q/ U$ L2 h' W; V1 @
  throw new Exception();# H+ w7 A1 J: X+ I( O! c" R
  }5 P& W2 i3 w" j
  //feof()函数检测是否到达文件末尾5 c4 N9 C# N2 S
  while (feof($handle) === false) {( K+ {' V" k6 h# W% m- s) R: @/ R
  //fgetcsv()一次读取csv文件的一行' r# g7 l7 F0 R+ ?  S' T
  yield fgetcsv($handle);) ~' `0 A3 |8 M" h6 S5 t) m
  }9 ]7 D& T* V' y
  fclose($handle)
8 _% M/ ?& [) o  }5 @' }/ X. u/ k8 M* W' q- E
  foreach (getRows('data.csv') as $row) {+ a. K& b  D; b# l8 V
  print_r($row);- Y, u4 T1 @5 [3 i* Z. ~
  }
4 b! N" x. r; Q" a  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
2 T5 P$ F7 l. H4 j* L" f4 M) ?6 T3 H$ \' m2 K
! _8 U1 M! z1 g# j
来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-5-25 08:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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