鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。
3 `! z1 z# w$ k. S% N, d9 O( e  1.命名空间
% k9 C6 ]7 j' j7 m  命名空间是什么?
$ z( s9 v# b7 e: y) O  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。
1 M9 a+ ~+ A1 ^6 x  2).命名空间始终应该在<?php标签的下面一行。4 x- K( g  Q  x8 E. ^) p7 O1 e
  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
0 N0 }7 E$ @$ E- C+ r: s& X# `, D  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
8 {$ i6 H9 ?1 U6 c: d0 |  为什么需要命名空间?
$ }2 z( b1 w2 F2 s0 c0 E9 `  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。
$ W$ ?+ g) @% h- H- D6 x9 O+ O, @  声明命名空间
% K7 k4 C& D  B; v; ~  1).顶层命名空间经常用于设定顶层厂商名。
+ H& t2 [- B/ m7 e* z  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。
4 H1 ^3 H8 {, ?" r+ m  导入和别名
8 {9 |; a& x- h$ C  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。$ W2 h% b% |$ b. l+ L
  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。
+ N; l) D0 {, y6 b' c/ n  从PHP5.6开始我们可以导入函数和常量。9 W7 e6 E7 l( Y( g5 w
  <?phpuse func Namespace\functionName;
& w: o( R( ]" a/ I6 v' T  functionName();
+ e: ]5 z' n; J- a9 B) @1 L; V  也可以导入常量,
: f4 d+ `2 N3 w, m  use constant Namespace\CONS_NAME;% B$ C# @4 |0 X8 d  _) k/ }  ?4 M
  echo CONS_NAME;/ t( X% ~- t* {
  函数和常量的别名与类名的创建方式一样。
9 M4 G) I6 E/ F/ h8 @. P9 s  L* Z  最佳实践
# U* Q1 @- S9 P) Z: z6 }  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。1 s4 ?; e6 V, m; J& e& q4 a8 c& W
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
! z& _/ I9 |4 g/ }3 a, K6 y  自动加载5 _& K  x, p+ j0 ~$ i+ ^
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。
- j) P7 b& S  j2 T  2.使用接口
4 {9 l; T. M- k) K3 z) |4 E3 }8 A  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。) D& P; ?# j- _# R6 j+ ]* I0 h
  3.性状" o5 j8 ]$ ?# f4 F
  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。
0 [" K  @& e" }" z9 x( B  2).性状使得两个无关的类可以使用相同属性和方法。
4 N& u1 F+ b& [# y9 y  3).PHP解释器会把性状复制粘贴到类的定义体中。
/ O, m, u2 q/ i- H( S  4.创建生成器' @: y- \7 C1 `. V
  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:5 {' ^# o5 D: y2 c; ]" O- x
  <?phpfunction myGenerator() {  T; k) F( z6 P5 R9 v( z+ K" r
  yield 'value1';
4 E* o" q8 P9 w) U  yield 'value2';
+ k8 H; R/ E. K5 V! l4 `% X1 G  }/ e: w+ V; |" [/ x6 T* G/ z; _- z
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
5 w7 y1 L* b$ q+ _  <?phpforeach (myGenerator() as $yieldedValue) {. f' Z: z$ t6 q' k; U
  echo $yieldedValue, PHP_EOL;9 h0 ~' W' E  [) U' Q7 A" \2 y
  }
% a# ^$ r5 u) v* y$ T' X  以上例子会输出
+ H0 s+ t) h: |  value1
+ F5 Q" _: Q/ I5 `( N- T  value2% Y% b9 L" w2 B+ [5 Q1 a
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)
# a9 N; S  w3 D6 `! n  function makeRange($length) {: \: `- g7 f% t/ z. B
  $dataset = [];
+ }& R  s; l) s0 M5 d  for ($i=0; $i < $length; $i++) {9 u- J* k7 V( V4 S
  $dataset[] = $i;
6 @6 k, v% A5 o. E- E8 X. p  }/ v! a( `6 h4 l- g, p+ x8 p& y
  return $dataset;" w7 d% a+ }# s9 t7 }
  }
+ r8 ?3 Y* G4 u9 r; M$ }  $customRange = makeRange(1000000);foreach ($customeRange as $i) {' o! ^2 f9 a0 [. ~' V$ w. j. W5 X) ]* d
  echo $i, PHP_EOL;& J5 ^" U  F& W
  }
6 b; J( p2 D! G7 b' Z% V  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。
; m3 k8 b. P5 ~8 E% w0 t  function makeRange($length) {+ t+ l9 s! G0 t1 h% E- Z) [3 Z* X
  for ($i = 0; $i < $length; $i++) {
4 H& B; W. U9 q; P  L  yield $i;
4 d; h* W) u5 }$ U$ ~  }
5 B- B/ G& h, Z; T. v0 t  }
1 `  k" ]; k: W9 F1 S+ p  foreach(makeRange(1000000) as $i) {
, U: M: v- Z$ {3 p  echo $i, PHP_EOL;
) w1 e- x, q4 D! [; n7 _# J  }( l+ f- K" l( Y2 k# R3 J! b. P. Y
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。+ {6 f7 x9 p' G' ^; k; m
  function getRows($file) {7 R$ w! [% I1 U- l- O- A$ `
  $handle = fopen($file, 'rb');4 `) J  a; r6 S# C; _% K; ]& e
  if ($handle === false) {
. w/ X/ q9 C4 C5 F: a  throw new Exception();- q1 m0 x  ]' l6 j
  }* j4 ~( X: s; x- r, F% I1 d
  //feof()函数检测是否到达文件末尾
  |3 Z& _  |7 C, g. l( b2 @  while (feof($handle) === false) {
! r; ?* S7 `5 P5 V* g. J8 P, H  //fgetcsv()一次读取csv文件的一行
* R, f/ l2 z# `! L! W; k! ?! z  yield fgetcsv($handle);+ }8 g, }8 A8 S7 R. K8 ~+ b
  }- ^. Y1 L# R0 y$ F
  fclose($handle)+ J+ _4 I, V# u( m8 Q
  }& m/ n' X' `/ t" Y4 N; e- G# T6 ?2 n- V
  foreach (getRows('data.csv') as $row) {
8 e0 k4 x% l8 m' P  print_r($row);
. V7 j1 l/ r1 r4 i, F6 s. i6 u  }; Y2 W5 N; N( A+ V
  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。
+ h  E: b0 @6 o( h- u1 k5 j3 H4 U9 @  Z0 s" o; V

% N2 L) V/ b7 w  F% \来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-9-19 20:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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