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. 从Java String实例来理解ANSI、Unicode、BMP、UTF等编码概念

    转(http://www.codeceo.com/article/java-string-ansi-unicode-bmp-utf.html#0-tsina-1-10971-397232819ff9a ...

  2. 【转】推荐10款最热门jQuery UI框架

    推荐10款最热门jQuery UI框架 原创 在进行Web开发时,并非所有的库都适合你的项目,但你仍需要收藏一些Web UI设计相关的库或框架,以在你需要的时候,加快你的开发效率.本文为你推荐10款非 ...

  3. android图片验证码--自绘控件

    自绘控件的内容都是自己绘制出来的 大致流程如下: 1.定义一个类继承view 使用TypedArray初始化属性集合 在view的构造方法中 有一个AttributeSet的参数 很明显是用来保存控件 ...

  4. iOS平台UDID方案比较

    苹果在iOS6中禁用了[UIDevice uniqueIdentifier],在iOS7中又把mac地址的获取给堵上了.没办法,毕竟人家是老大,说不让你用,你也没办法.在这边总结一下现有的一部分UDI ...

  5. Android 手机卫士--绑定sim卡序列号

    现在开始具体 处理每一个导航页面的逻辑,首先看第二个导航页 本文地址:http://www.cnblogs.com/wuyudong/p/5949775.html,转载请注明出处. 这里需要实现绑定s ...

  6. Appfuse:记录操作日志

    appfuse的数据维护操作都发生在***form页面,与之对应的是***FormController,在Controller中处理数据的操作是onSubmit方法,既然所有的操作都通过onSubmi ...

  7. Java开发代码性能优化总结

    代码优化,可能说起来一些人觉得没用.可是我觉得应该平时开发过程中,就尽量要求自己,养成良好习惯,一个个小的优化点,积攒起来绝对是有大幅度效率提升的.好了,将平时看到用到总结的分享给大家. 代码优化的目 ...

  8. APUE学习之多线程编程(三):线程属性、同步属性

    一.线程属性      可以使用pthread_attr_t结构修改线程默认属性,并这些属性和创建的线程练习起来,可以使用pthread_att_init函数初始化pthread_attr_t结构,调 ...

  9. QString::​arg的用法

    1.用法示例1 String str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11").arg("1"," ...

  10. 史上最全QC学习方案,值得收藏!

    Quality Center是一个基于Web的强大的测试管理工具,可以组织和管理应用程序测试流程的所有阶段,**制定测试需求.计划测试.执行测试和跟踪缺陷.此外,通过Quality Center还可以 ...