鱼C论坛

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

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

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

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

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

x
本文和大家分享的主要是php的命名空间、性状和生成器相关内容,一起来看看吧,希望对大家学习php有所帮助。4 t$ F$ ~/ I( {, t* o! F
  1.命名空间
6 T: M5 ~9 z9 @3 _! h  命名空间是什么?
$ w( \7 E; A+ U: g  1).命名空间在PHP 5.3中被引入,类似于文件夹的功能。例如Symfony框架中的Request和Response,位于Symfony的命名空间下。" H" I* \, W1 q
  2).命名空间始终应该在<?php标签的下面一行。
7 ^, v" M, s2 D# j! N; t  3).PHP文件的命名空间和操作系统的物理文件系统不同,这是一个虚拟的概念,没有必要和文件系统的目录结构完全对应。虽然如此,绝大多数PHP组件为了兼容广泛使用的PSR4自动加载标准,会把子命名空间放到文件系统的子目录中去。
# X  x" U2 w* h* P; I) Y4 P9 L  4).命名空间只是PHP语言的一种记号,PHP解释器会将这种记号作为前缀添加到类、接口、函数和常量的名称前面。
% k1 W2 G1 j+ M4 ]2 O4 E  为什么需要命名空间?( m+ G9 |- |- u! p
  1).命名空间使得程序可以像沙盒一样运行,可以和其他开发者编写的代码一起使用。确保了自己的代码和项目可以和项目的第三方依赖一起使用。4 t1 u) |, j) O* w, `3 M1 Y( i  J9 z
  声明命名空间
2 ~9 L+ E7 ]4 ]$ e! H3 q  1).顶层命名空间经常用于设定顶层厂商名。! a% J# g' ^" }
  2).厂商的命名空间必须具有全局唯一性,子命名空间就没有那么重要,但有助于组织项目的代码。2 M1 ~2 p3 s8 e0 I
  导入和别名
& V6 h3 J$ ]9 E) o& Y& I; U) n' ~  1).从PHP5.3开始可以导入PHP类、接口和其他命名空间,并为其创建别名。从PHP5.6开始可以导入PHP函数和常量,并为其创建别名。
2 F; k) I8 I( I1 @$ c/ I  2).使用use关键字导入代码时无须在开头加上\符号,因为PHP假定导入的是完全限定命名空间。use关键字必须出现在全局作用域中即不能出现在类或者函数中,因为这个关键字是在编译的时候使用的,不过,use关键字可以在命名空间声明语句后使用,导入其他命名空间的代码。  o" ~3 r# z$ `' g3 k+ H* R5 w
  从PHP5.6开始我们可以导入函数和常量。1 c1 f. `8 C% O# ^4 [1 S- \
  <?phpuse func Namespace\functionName;
& x" c/ w6 L  I5 t% ?  functionName();* c% U' d6 |& [+ {
  也可以导入常量,% P1 q7 n& l9 H( W& c
  use constant Namespace\CONS_NAME;9 K- H# A6 b" C# Z- P& t
  echo CONS_NAME;
8 C' W* \$ O1 ]8 u( X* t) L! s  函数和常量的别名与类名的创建方式一样。( H5 f$ p2 u/ c2 s% z6 N7 ^7 r# j
  最佳实践
( p' ~6 Z2 _. S1 \  1).PHP允许在一个PHP文件中定义多个命名空间。但是这么做容易让人困惑,违背了一个文件一个类的良好实践。) D8 B% s) ?9 I% a4 b
  2).在一个命名空间中引用全局的命名空间的代码时,需要加上\前缀,告诉PHP需要在全局中查找该类,例如PHP原生的异常类。
5 U' n8 F# D+ O# [$ l8 }/ V( [% E  自动加载3 O5 W5 ]% Y- g. `1 n+ g* U
  1).命名空间为PHP-FIG制定的PSR4自动加载器奠定了坚实的基础。" x# ?  r+ X: w+ T  ]+ ^' I- w
  2.使用接口9 C$ W6 I5 n* `' l
  1).就像我可以选择开不一样的车。因为他们都有方向盘、油门和刹车,并且燃料都是汽油。$ G, u) {$ q( c5 H% |+ y
  3.性状
6 l5 N; m  ?/ G1 @- @  y+ `  1).形状是类的部分实现(常量、属性和方法),可以混入一个或者多个现有的PHP类中,性状有两个作用,表明类可以做什么(类似接口),提供模块化实践(类似类)。  h! M. ~- d2 u
  2).性状使得两个无关的类可以使用相同属性和方法。
3 O* e' Z8 H# ]8 Y+ L  3).PHP解释器会把性状复制粘贴到类的定义体中。2 y- J( d) u' S# ?; V) \' s% G
  4.创建生成器
3 {+ U5 p/ l& F6 S  1)在普通函数中一次或者多次使用yield关键字,不返回值,只生成值,这个函数就是一个生成器。例如:7 w) m3 `$ S1 c( Q2 o- t
  <?phpfunction myGenerator() {
$ ]/ x3 M. ~- ~. J2 z9 E2 t4 `  yield 'value1';
0 h: ]4 x- j3 R2 g  yield 'value2';
" P2 ]& Y5 a3 [. R" D  }) E% n- J) S% |% A$ D
  调用生成器函数的时候,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach()函数迭代,每次迭代,PHP会要求这个对象的实例计算并提供下一个要迭代的值,生成器的优雅之处就是在每产出一个值之后,生成器内部状态会一直停顿和恢复之间切换,直到抵达定义体的末尾或者遇到空的return;语句为止,例如:
( T- ~9 b+ o2 s& m3 q8 s5 o. y  <?phpforeach (myGenerator() as $yieldedValue) {( C$ L2 C3 }7 o: ?) M2 b
  echo $yieldedValue, PHP_EOL;2 d6 Q! N+ l) B! R
  }( M# A" d3 J/ r( e' F4 W$ _
  以上例子会输出
8 g% O' T( M8 U5 Z0 ^" ?  value1
6 _3 P6 `0 U6 s7 g' C- n2 c/ V) o  value2* y; y) w# O5 `7 Z0 \6 v# `
  2).生成器是如何节约内存的?生成一个范围内的数值(错误方式)1 c5 K& {& u# Z+ f" {0 ?
  function makeRange($length) {
4 @7 K$ U8 f0 P" D& A  $dataset = [];: m# _  R# ~8 M4 v& y* m' A1 G) t
  for ($i=0; $i < $length; $i++) {/ X3 ?! `6 Y2 x7 w5 l# \8 c
  $dataset[] = $i;- ]% k+ Y: w$ m
  }
& l; y* v  e: t) U* z! y  return $dataset;
' ^. }9 d$ z- G9 g# g* T: T  }3 h" B4 J( k( e5 H$ ?
  $customRange = makeRange(1000000);foreach ($customeRange as $i) {8 q1 ]8 D9 l" h. z
  echo $i, PHP_EOL;
# ^1 U  k- Y7 M+ s$ t; x% \& B  }
% u3 K' y1 x/ l  预先创建了一个包含很大整数组成的数组,再看使用生成器的例子。9 G' R2 j# x* y5 X6 Y
  function makeRange($length) {
& U9 b) _# B8 R. P, U  for ($i = 0; $i < $length; $i++) {
5 s+ G! ]: L! }, y, Q1 f7 ~9 f( _( P  yield $i;
, @# `) c- T& X7 A. ?  }7 {3 h# U. D4 a1 J7 b% }5 I7 r- Q
  }5 q* J8 B8 p; V: t
  foreach(makeRange(1000000) as $i) {( Y" {% z: ~& U, j$ C  |+ g
  echo $i, PHP_EOL;
2 ^3 J5 F" |0 w& O% J( J  }( t' n2 O! h7 W) Q4 Z9 [
  在实际的例如迭代一个4GB大小的文件中功能中,迭代器大展身手。
' ?( @  N* Y6 G) V( ?0 ^- U  function getRows($file) {6 g4 W$ \1 b4 w# K
  $handle = fopen($file, 'rb');# s8 @2 y4 E- Q  P0 U
  if ($handle === false) {1 K* n- |% w# a. _& h
  throw new Exception();
0 P6 g5 m* g" K& x) u) K! _  }+ X: D# M* p' ?. B: s8 k6 y( R. x- e
  //feof()函数检测是否到达文件末尾: E. P7 @* n0 B5 P6 e' Y$ K
  while (feof($handle) === false) {: H! @; V% Y" o6 x2 w5 Z- ^
  //fgetcsv()一次读取csv文件的一行
" p2 Y$ W0 t% h3 c0 E  yield fgetcsv($handle);0 O! W% L/ W. a
  }
# R) y6 M3 H7 {& D5 J  fclose($handle)! ~  ~* ?: ?6 v4 u: r2 _) k) W5 a
  }
$ k% K( T7 e4 y  k* ]  foreach (getRows('data.csv') as $row) {, U) u! ]) F6 l5 ^6 x- A8 e2 H
  print_r($row);
1 Q5 q* ~# T- N$ d& K  }
% l; G; A: T1 ?  3).生成器没有为PHP添加新功能,需要实现在数据集中执行快进、快退和查找,最好自己编写类实现Iterator接口,或者使用PHP标准库中的某个原生迭代器。: s( a* ]+ W3 \. x( h4 U) {

1 }$ Y+ w$ a8 l) @5 H( W% @
& ~* E, T7 I. s" l8 D来源:稀土掘金
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

GMT+8, 2026-3-17 00:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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