PHP 5.4的traits使用方法

5.4主要包括以下特性:

  • Added: Traits language construct Added: Array dereferencing support
  • Added: DTrace support Improved: Improved Zend Engine memory usage and
  • performance Moved: ext/sqlite moved to pecl (sqlite3 support is still
  • built-in) Removed: break/continue $var syntax Removed:
  • register_globals, allow_call_time_pass_reference, and
  • register_long_arrays ini options Removed: session_is_regisitered(),
  • session_registered(), and session_unregister()

这里本人也初步看了traits的使用,将会对这个新功能按本人理解做一下讲解。

Trait简单使用

<?php
 
trait A {
    public $var1 = 'test1';
    public function test1() {
        echo 'trait A::test1()';
    }
}
 
trait B {
    public $var2 = 'test2';
    public function test2() {
        echo 'trait B::test2()';
    }
}
 
class C {
    use A,B;
}
 
$c = new C();
echo $c->var1; //test1
$c->test2(); //trait B::test2()

优先级问题
Trait会覆盖继承的方法,当前类会覆盖Trait方法。

    <?php 
trait A {
    public $var1 = 'test';
    public function test() {
        echo 'A::test()';
    }
    public function test1() {
        echo 'A::test1()';
    }
}
 
class B {
    public function test() {
        echo 'B::test()';
    }
    public function test1() {
        echo 'B::test1()';
    }
}
class C extends B{
    use A;
    public function test() {
        echo 'c::test()';
    }
}
 
$c = new C();
$c->test(); //c::test()
$c->test1(); //A::test1()

多个Trait冲突问题
如果没有解决冲突,会产生致命错误;
可用insteadof来明确使用冲突中哪一个方法;
可用as操作符将其中一个冲突方法另起名;

    <?php 
trait A {
    public function test() {
        echo 'A::test()';
    }
}
 
trait B {
    public function test() {
        echo 'B::test()';
    }
}
 
class C {
    use A,B {
        B::test insteadof A;
        B::test as t;
    }
}
 
$c = new C();
$c->test(); //B::test()
$c->t(); //B::test()   可以用as另起名

as可用来修改方法访问控制

<?php        
trait  HelloWorld  {
    public function  sayHello () {
        echo  'Hello World!' ;
    }
}

// 修改 sayHello 的访问控制
class  A  {
    use  HelloWorld  {  sayHello  as protected; }
}

// 给方法一个改变了访问控制的别名
// 原版 sayHello 的访问控制则没有发生变化
class  B  {
    use  HelloWorld  {  sayHello  as private  myPrivateHello ; }
}

$b = new A();
$b->sayHello(); //Fatal error: Call to protected method A::sayHello() from context ''
  

Trait中使用Trait

<?php
trait A {
    public function test1() {
        echo 'test1';
    }
}
 
trait B {
    public function test2() {
        echo 'test2';
    }
}
 
trait C {
    use A,B;
}
 
class D {
    use C;
}
 
$d = new D();
$d->test2();  //test2

Trait支持抽象方法、支持静态方法、不可以直接定义静态变量,但静态变量可被trait方法引用

    <?php        
trait A {
    public function test1() {
        static $a = 0;
        $a++;
        echo $a;
    }
 
    abstract public function test2(); //可定义抽象方法
}
 
class B {
    use A;
    public function test2() {
 
    }
}
 
$b = new B();
$b->test1(); //1
$b->test1(); //2

Trait可定义属性,但类中不能定义同样名称属性

    <?php        
trait A {
   public $test1;
}
 
class B {
    use A;
    public $test2;
}

Continue reading...

据说,码农在美国的生活

硕士毕业IT码农一个,毕业工作1年零3个月,就职于美国某不知名小公司,年薪8W美刀。
8W是什么概念,多吗?好,放几个数据让大家分析分析,以下的全部以美元为单位。
一箱可乐(24罐):6 $
油价(国内93):3.45$/加仑 约 0.9$ / 升
手机话费:40$/月 无限通话短信流量 其中4GLTE网络流量为2G,超过后降为3G网络
一个阿迪达斯的书包:20 $
一双NIKE的Air Force 1板鞋;30 $
一条普通的levis牛仔裤:80 $
一部iPhone 5:600 $
一台苹果的mac pro基础配置:1200 $
一辆奥迪A6: 4W $
一辆路虎揽胜标配:6W $
一辆法拉利430:25W $
一套80平米的公寓:5w $
租一套80平米的公寓:900 $/月
一套200平米的单层别墅+同等面积的草坪:20w
一套N百平米的两层别墅+另外一栋两层单独的阁楼+1千平米的草坪:50w
美国白领平均3个月买车,3年买房,永久私人产权,房子地下就算有石油也是你的;
中国白领平均3年买车,30年买房,70年产权,地下的石油是ZF的;
好多人问我:你以后还回来吗? 你们说呢?

其它:
美国警察无权在大街上查人民的身份证件,即使怀疑你是非法移民也拿你没办法
警察无权入室查水表without搜查令,第一次你必须警告,第二次你可以开枪!
打电话报警后警察不来或者晚来你可以直接起诉警察局并获得巨额赔偿
任何ZF机构,银行,医院,在工作时间必须接待你,否则你可以起诉ZF并获得巨额赔偿。
ZF每年的每一笔财政支出都公布在网上,精确到小数点后两位。
乱停车会被直接拖走。
种族歧视是严重的违法行为。
打人后果很严重
个人的信用记录全社会共享,即使考试一个小小的作弊也会让你以后申不到信用卡,甚至租不到房子。
上大学以前全部是免费教育+每个月的生活补助
医疗保险赔偿90%,自愿购买

Continue reading...

PHP实现的一个RC4的加密解密算法

PHP实现的一个RC4的加密解密算法

<?php
/**
 * cr4加密解密
 * @link http://en.wikipedia.org/wiki/RC4
 */
class RC4
{
    /**
     * 加密
     * @param string $key 私匙
     * @param mix $data 需要加密的数据
     * @param boolean $decrypted 是否解密
     * @return 16进制字符串
     */
    static public function Encrypted($key, $data, $decrypted=false)
    {
        $keyLength = strlen($key);
        $S = array();
        for($i = 0; $i < 256; $i++) $S[$i] = $i;
        $j = 0;
        for ($i = 0; $i < 256; $i++)
        {
            $j = ($j + $S[$i] + ord($key[$i % $keyLength])) % 256;
            self::swap($S[$i], $S[$j]);
        }

        $dataLength = strlen($data);
        $output = "";
        for ($a = $j = $i = 0; $i < $dataLength; $i++)
        {
            $a = ($a + 1) % 256;
            $j = ($j + $S[$a]) % 256;
            self::swap($S[$a], $S[$j]);
            $k = $S[(($S[$a] + $S[$j]) % 256)];
            $output .= chr(ord($data[$i]) ^ $k);
        }

        return ($decrypted) ? $output : bin2hex($output);
    }
    /**
     * 解密
     * @param string $a 私匙
     * @param mix $b 需要解密的数据
     * @return 字符串
     */
    static public function Decrypted($a, $b)
    {
        if (function_exists("hex2bin"))
        {
            return self::Encrypted($a, hex2bin($b), true);
        }
        else
        {
            return self::Encrypted($a, pack("H*", $b), true); // hex2bin php5.4才支持
        }
    }

    static private function swap(&$a, &$b)
    {
        $tmp = $a;
        $a = $b;
        $b = $tmp;
    }
}

Continue reading...

一些实用的PHP公共开源的工具

swoole
swoole扩展了PHP很多新的特性,在未来开发游戏和PHP服务端的程序很有帮助

redis
redis是可以集群的高并发的内存缓存组件,需要多了解redis的使用场景
phpredis
rediska
predis
以上三个是php使用redis的客户端,需要了解每个客户端的并发,性能

memcache
key-value的高效内存存储

sphinx
全文检索系统

symfony
目前我们各个项目使用的开源PHP框架,需要掌握可以自定义的方法,性能优化,组件开发的相关知识

siege
ab
简单的测试工具,在进行接口压力测试时使用

xdebug
PHP代码断点和性能分析的扩展

twemproxy
codis
dynomite
以上三个是目前比较流行的redis代理组件,需要掌握每个组件的性能,调优,以及和PHP结合使用

zeromq
高性能的消息队列,具有多种协议

mysqlnd_ms
一个自动化的mysql读写分离的扩展

Continue reading...

两个时间段重叠判断算法

在日常做项目中我们会遇到很多与时间相关的一些检测。
如一个酒店的钟占房订单系统,须要计算出一个时间段内是否与一个或多个时间段是否重叠的例子。
用php的实现方法,直接看源代码

<?php
/**
 * [Detection_Overlap_DateTime description]
 * @param  [datetime] $starttime        [开始时间]
 * @param  [datetime] $endtime          [结束时间]
 * @param  [array]  $exist_time_array   [已存在时间数组]
 * @return [Boole]                      [时间冲突返回true]
 * @author [陶之11] <11@pao11.com>
 */
function Detection_Overlap_DateTime($starttime = null, $endtime = null, $exist_time_array = array())
{
    //将时间转换成unix时间戳
    $gstime = ctype_digit($starttime) && $starttime <= 2147483647 ? $starttime : strtotime($starttime);
    $getime = ctype_digit($endtime) && $endtime <= 2147483647 ? $endtime : strtotime($endtime);

    $i = 0;
    //将新加入时间做new标记
    $_array = array($gstime=>'new',$getime=>'new');

    //循环已存在时间并转成unix时间戳
    foreach($exist_time_array as  $v){
        $i++;
        //对已存在时间做标记,把时间戳设为数组键名
        $_array[strtotime($v['stime'])] = $i;
        $_array[strtotime($v['etime'])] = $i;
    }

    ksort($_array);//然后按时间戳排序
    reset($_array);//重置数组
    print_r($_array);
    while(key($_array) != $gstime) next($_array);
    if(next($_array)!='new'){
        return true;
    }

    reset($_array);
    while(key($_array) != $getime) next($_array);
    if(prev($_array)!='new'){
        return true;
    }
    return false;
}

以上带代码用数组排序功能实现了整个算法,其中数组的ksort next prev等方法是该算法的核心。
可以看看调用示例

<?php
//已存在时间段数组
$datetime  = array(
        array('stime'=>'2015-06-26 10:12:12','etime'=>'2015-06-26 10:50:15'),
        array('stime'=>'2015-06-26 11:00:00','etime'=>'2015-06-26 11:20:00'),
        array('stime'=>'2015-06-26 12:11:00','etime'=>'2015-06-26 13:30:00')
               );


//假如要插入一段时间
$stime = '2015-06-26 13:30:01';
$etime = '2015-06-26 14:00:00';

//检查时间段是否冲突
var_dump(Detection_Overlap_DateTime($stime, $etime, $datetime));

结果将返回false 因为$stime中的13:30:01与$datetime中的最后一条有重叠。

Continue reading...



about me

  • 陶之11's Blog Name:陶之11 OICQ:14779023 Site:Pao11.com

分类

快捷入口