PHP中trait(性状)与generator(生成器)

PHP中trait(性状)与generator(生成器)

一、trait (性状)

最近在看Josh Lockhat的《Modern PHP》,这本书很薄。但是其中给出了一个很重要的学习方法。就是写PHP程序的时候不要凡事都自己来创造,如果已经有牛人写好了组件,直接放进自己项目中用就好了,并且给出了组件的链接。这半年看技术不少,外国的程序员比较喜欢按部就班的按照规范来写程序,包括代码规范,如何保证代码的性能方面,都严格按照工具进行测试。但是我前一份工作,对于代码规范和上线规范就比较松懈。这家公司有了很大的提高,在项目组长的要求下,还开发了功能强大的上线系统。

这本书中我看到了性状,于迭代器这两个对于我来说比较新的内容。其实这两个东西都比较好理解,因此就不单独写博客介绍了,合并在一篇博客中介绍,大家看代码就好。

<?php
header("content-type:text/html;charset=utf-8");

trait BandAid
{
public function __construct()
{
echo "Hello BandAid<br/>";

}

public function getName()
{
echo "Roverliang<br/>";
}
}

trait BandAid_2
{
public function hello()
{
echo "I'm BandAid_2<br/>";
}
}

class Body
{
use BandAid;
use BandAid_2;

public function __construct()
{
echo "Hello Body<br/>";
}

public function makeDance()
{
echo "Dance<br/>";
}

}

$roverliang = new Body();
$roverliang->getName();
$roverliang->makeDance();
$roverliang->hello();

结果:

Hello Body
Roverliang
Dance
I'm BandAid_2

其实PHP manual 中关于性状讲解的更为清晰:trait:性状

其中有一个需要注意点,容易犯错代码如下:

<?php
header("content-type:text/html;charset=utf-8");

class TestClass
{
public static $bar;
}

class Foo1 extends TestClass {}
class Foo2 extends TestClass {}

Foo1::$bar = "hello";
Foo2::$bar = "World";

echo Foo1::$bar;
echo Foo2::$bar;

//result is
/**
* WorldWorld
*/
/*********************************************/
trait TestTrait
{
public static $bar;
}

class Foo3
{
use TestTrait;
}

class Foo4
{
use TestTrait;
}

Foo3::$bar = "Hello";
Foo4::$bar = "world";

echo Foo3::$bar;
echo Foo4::$bar;

//result
/**
* Helloworld
*/

由于这个markdown 工具没有代码折叠的功能,所以只能让大家看这么冗长的代码了。trait 是一种灵活的代码段。PHP5.4 版本才增加这个功能,所以使用的时候一定要先看下自己所使用的PHP版本。PHP文档中说了,trait是一种代码复用的方法。我对于trait理解是,trait就是一个创可贴,哪里需要了就贴上去,满足功能。trait的__construct 在使用的时候会被重写,因此使用trait的时候可以不用写构造函数。

generator(生成器)

关于生成器详细可以看官方文档:生成器总览

尤其要注意的是,生成器的版本要求是PHP 5 >= 5.5.0, PHP 7

示例如下:

<?php
header("content-type:text/html;charset=utf-8");
date_default_timezone_set('Asia/Shanghai');
$file = "./ip-to-country.csv";

function getFile($file)
{
$handler = fopen($file, 'rb');
if ($handler === false) {
throw new Exception();
}
while (!feof($handler)) {
yield fgetcsv($handler);
}
fclose($handler);
}

$stime = microtime(true);
foreach (getFile($file) as $val) {
//print_r($val); save to redis
}
$etime = microtime(true);
$exectime_1 = $etime - $stime;

function getFile_2($file)
{
$handler = fopen($file, 'rb');
if ($handler === false) {
throw new Exception();
}
while (!feof($handler)) {
fgetcsv($handler); //save to redis
}
fclose($handler);
}

$stime = microtime(true);
getFile_2($file);
$etime = microtime(true);
$exectime_2 = $etime - $stime;

echo $exectime_1;
echo "\r\n";
echo $exectime_2;
echo "\r\n";

//352.71399402618
//331.73138713837

本文测试的文件大小如下:

[root@roverliang html]# ls -lh
总用量 2.0G
-rwxr--r--. 1 jack jack 171 11月 17 13:23 Creator.php
-rwxr--r--. 1 jack jack 236 11月 17 13:27 GraphicFactory.php
-rwxr--r--. 1 jack jack 963 11月 20 07:53 index.php
-rwxr--r--. 1 root root 2.0G 11月 20 06:38 ip-to-country.csv
-rwxr--r--. 1 jack jack 243 11月 19 13:38 TextFactory.php

经过测试发现,迭代器在读取大文件时候并没有表现出其官网所宣称的那种效率。甚至比使用使用常规的逐行读取方法还要慢一点点,不过这种时间上的差距可以忽视。比第二种方式略慢,可能是因为迭代器内部的状态切换所带来的性能开销。

那么两种方式在系统内存和cpu占用上有何不同,看下图:

使用迭代器



不使用

由此可以看出,使用迭代器和不使用两者并没有明显不同。

虽然如此,还是需要了解迭代器,至少给予我们一种不同的方式来进行数据操作。

php中trait(性状)与generator(生成器)的更多相关文章

  1. ES6新特性:Javascript中Generator(生成器)

    ES6的很多特性都跟Generator扯上关系,而且实际用处比较广, 包含了任何需要异步的模块, 比如ajax, filesystem, 或者数组对象遍历等都可以用到: Generator的使用: G ...

  2. ES6中的迭代器(Iterator)和生成器(Generator)

    前面的话 用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而在许多编程语言中,已经开始通过程序化的方式用迭代器对象返回迭代过程中集合的每一个元素 迭代器的使用可以极大地简 ...

  3. Javascript中Generator(生成器)

    阅读目录 Generator的使用: yield yield* next()方法 next()方法的参数 throw方法() return()方法: Generator中的this和他的原型 实际使用 ...

  4. ES6中的迭代器(Iterator)和生成器(Generator)(一)

    用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而在许多编程语言中,已经开始通过程序化的方式用迭代器对象返回迭代过程中集合的每一个元素 迭代器的使用可以极大地简化数据操作 ...

  5. ES6笔记(5)-- Generator生成器函数

    系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...

  6. MyBatis Generator 生成器把其他数据库的同名表生成下来的问题

    [问题] 使用MyBatis Generator生成器时,发现Mapper文件中出现字段与连接数据库不符,经过查找发现该表是其他数据库的同名表的字段. [解决问题] 在构造文件中,这里是generat ...

  7. Generator生成器函数

    接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还有一种常用的解决方案,它就是Ge ...

  8. Python高级语法之:一篇文章了解yield与Generator生成器

    Python高级语法中,由一个yield关键词生成的generator生成器,是精髓中的精髓.它虽然比装饰器.魔法方法更难懂,但是它强大到我们难以想象的地步:小到简单的for loop循环,大到代替多 ...

  9. 取代Promise的Generator生成器函数

    接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还有一种常用的解决方案,它就是Ge ...

随机推荐

  1. 在 ASP.NET CORE 中使用 SESSION

    Session 是保存用户和 Web 应用的会话状态的一种方法,ASP.NET Core 提供了一个用于管理会话状态的中间件.在本文中我将会简单介绍一下 ASP.NET Core 中的 Session ...

  2. 一步步学习 Spring Data 系列之JPA(二)

    继上一篇文章对Spring Data JPA更深( )一步剖析. 上一篇只是简单的介绍了Spring Data JPA的简单使用,而往往在项目中这一点功能并不能满足我们的需求.这是当然的,在业务中查询 ...

  3. 【转】深入浅出JavaScript之闭包(Closure)

    闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...

  4. 脱离spring集成cxf(基于nutz框架)

    什么是webService WebService是一种跨编程语言和跨操作系统平台的远程调用技术. 理论资料: http://blog.csdn.net/wooshn/article/details/8 ...

  5. 使用c/c++扩展python

    用python脚本写应用比较方便,但有时候由于种种原因需要扩展python(比如给程序提供python接口等). 之前一直想整理下,今天终于坐下来把这件事情给做了,这里记录下,也方便我以后查阅. 说明 ...

  6. Atitit.css 规范 bem  项目中 CSS 的组织和管理

    Atitit.css 规范 bem  项目中 CSS 的组织和管理 1. 什么是BEM?1 1.1. 块(Block)2 1.2. 元素(Element)2 1.3. BEM树(和DOM树类似).3 ...

  7. SQL Server 2012 新特性:服务角色管理

    数据库角色管理,已经可以使用alter role,create role和drop role. 2012增加了几个ddl语句,可以操作服务级别的角色管理,   CREATE SERVER ROLE 用 ...

  8. 虚拟机环境下安装ESX不能安装虚拟系统解决方案

    在虚拟机环境(ESX.workstation等)下安装ESX或workstation等虚拟机,在虚拟机上再安装操作系统,会提示“虚拟系统不能启动,直到你配置了外部虚拟机(vmware esx in a ...

  9. Java线程并发:知识点

    Java线程并发:知识点   发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用.   逃逸:在对象尚未准备 ...

  10. 4-4 grep及正则表达式

    1. grep:Globally search a Regular Expression and Print:根据模式搜索文本,并将符合模式的文本行显示出来 pattern:文本字符和正则表达式的元字 ...