• PHP6的namespace

    神仙 2007-08-04 15:45

      php是否需要namespace已经争论了很久。我是很希望php有namespace或类似的东西的。对于发布类库框架,或者构建大的程序来说是很重要的。可以避免类名和函数名冲突,又不用像Pear里那样把类名弄得老长。当初php5的测试版曾经出现过,后来正式发布时又取消了,让我空欢喜一场。7月初,php6的snap里又加入了namespace,希望这次不要再让我空欢喜了。

      这次的namespace实现和当初的实现有所不同,更接近于C++的语法。

    声明namespace时在文件里加上例如

    namespace blogbus::test;

    function foo(){
        echo "foo";

    class Test{
        function bar(){
            echo "bar";
        }
    }

      该文件中的类和函数:foo,Test就属于blogbus::test的命名空间。在其他文件包含该文件后,可以用blogbus::test::foo()来调用函数,用blogbus::test::Test来使用类。如果只是这样的话那打字还是很麻烦的。所以可以使用
    import blogbus::test::Test;
    之后就可以直接用Test了。也可以
    import blogbus;
    之后可以用test::Test来使用。可惜目前的实现没有类似Java的import xxx.*; 或是python的from xxx import *;这样的语法。要导入许多东西的时候还是有些麻烦。

       既然namespace是为了解决命名冲突的问题,那么使用import来节省打字,保护键盘的时候还是需要避免import进来的东西和原有的东西重名的问题。所以import还可以这样用:import blogbus::test::Test as Blogbus。这时,就可以用Blogbus这个名字来使用blogbus::test::Test。你可以$test = new Blogbus();然后echo get_class($test);看看结果,会发现输出的仍然是blogbus::test::Test。

  • 筛法找质数之PHP版

    神仙 2007-06-08 09:34

    下面的程序会找出 1000000 以内的所有质数。

    define('MAX_NUM', 1000000);
    $all = array_fill(0,MAX_NUM,0);
    for ($i = 2; $i < MAX_NUM; $i++) {    
        if ($all[$i] == 0) {
            echo $i,"\n";  //测试性能时去掉这行。输出会占据大部分时间。
            for ($j = $i; $j < MAX_NUM; $j+=$i) {
                $all[$j] = 1;
            }
        }
    }

  • 放一个自己写的变量文件流

    神仙 2007-04-09 11:44

    写了一个变量文件流的wraper。变量文件流对测试会来很大的帮助,而php手册里的那个sample不够完善,现在我改的这个可以用于include, include_once, 以及一切文件函数。

    http://syre.blogbus.com/files/11760902810.zip

  • 检测字符串是否是utf8编码

    神仙 2007-01-29 17:39
    给一个字符串,怎么判断它是什么编码呢?php有一个函数:mb_detect_encoding。不过这个东西需要有mb_string库,不是到处都能用的。今天看手册,在评论里找到了这个东西。
    function is_utf8($string) {
       // From http://w3.org/International/questions/qa-forms-utf-8.html
       return preg_match('%^(?:
             [\x09\x0A\x0D\x20-\x7E]            # ASCII
           | [\xC2-\xDF][\x80-\xBF]            # non-overlong 2-byte
           |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
           | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
           |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
           |  \xF0[\x90-\xBF][\x80-\xBF]{2}    # planes 1-3
           | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
           |  \xF4[\x80-\x8F][\x80-\xBF]{2}    # plane 16
       )*$%xs', $string);  
    }
    准确率基本和
    mb_detect_encoding一样,要对一起对,要错一起错。
    编码检测不可能100%准确,这个东西已经可以基本满足要求了。
  • 用php实现一个堆

    神仙 2007-01-23 21:48
      堆(heap)是一个很有用的数据结构。堆可以用于实现优先队列。比如一个任务队列,其中中有很多任务,而且不断有新的加进来。要求每次找到其中优先 级最高的那个来处理。如果每添加一个就要排序一次的话开销是很大的,时间复杂度为O(nlogn),但实际上我们要的只是其中最大的那个,因此完全没有必 要全部排序。堆这种数据结构保证了堆顶的元素始终是最大的。而且每添加一个新元素,或者弹出堆顶元素的时间复杂度仅为O(logn)。即使是有40亿个元 素,也最多需要交换32次。排序树(比如二叉搜索树)插入删除的复杂度虽然也是O(logn),但堆算法更简单,常系数也更小。同时,堆可以放在一个扁平 的数组中,不用额外的指针来维护结构,所使用的空间也更少。

    [下载代码]
  • PHPer聚会

    神仙 2006-12-23 21:11
      今天去参加了PEA (PHP Extend Association) 上海聚会。就是去凑凑热闹,看看能不能碰到些牛人。然后很欣慰的发现,还真有人听过“神仙”的大名。

    ShopEx的报道:
    http://www.shopex.cn/blog/2006/12/23/000225.html

  • Java vs. PHP

    神仙 2006-12-13 16:00
      最近在做一个J2EE的项目,用Spring + Hibernate。在开发过程中,我体会到了Java语言的麻烦,在许多动态语言中可以很简单的解决的问题在Java中就相当麻烦。但Java作为一种强类型语言的好处就在于方便了IDE。而对动态语言很难实现功能强大的辅助开发功能。不过对于开发者,尤其是熟练的开发者来说,IDE带来的帮助远不如语言本身的灵活性带来的好处大。如此看来,RoR的出现对Java社群带来的影响就是理所当然的了。
      相比起Java,PHP要简单得多。而且便于快速开发快速测试。在J2EE里,要对Servlet或者Controller/Action之类的东西做单元测试是比较麻烦的。因为不能自己构造request和response。虽然Spring提供了Mock对象,也有其他人做了类似的工作,相比 PHP里只要设置下$_GET,$_POST就能自定义请求数据来说,就要复杂了很多。
      Spring号称是一个轻量级框架,但实际用下来还是比较麻烦的。可以想见,传统的J2EE开发就更痛苦了。对于不那么复杂的Web应用,也是多数Web应用,其实还是PHP更适合。
      但PHP并没有受到很大的重视,一直都是叫座不叫好型的。PHP本身也有不少缺点,比如没有namespace/package,没有一个被普遍接受的好的应用框架,没有应用服务器。但更重要的原因恐怕还是PHPer普遍对面向对象认识不足。虽然PHP提供面向对象功能已经很久了,但多数程序里还是把 PHP当作面向过程的语言来用,在一些高人的眼里,PHP就成了低端语言。

      
  • memcached on win

    神仙 2006-11-04 19:40
    memcached是一个很好的分布式缓存,在linux上安装很方便,以前在win试过,没弄成功。今天showsa告诉我有一个win上的移植,这就方便多了。
    http://jehiah.com/projects/memcached-win32/
    如果下载的是二进制的版本,直接运行就可以了,可以加上参数来加以设置。
    常用设置:
    -p <num>          监听的端口
    -l <ip_addr>      连接的IP地址, 默认是本机
    -d start          启动memcached服务
    -d restart        重起memcached服务
    -d stop|shutdown  关闭正在运行的memcached服务
    -d install        安装memcached服务
    -d uninstall      卸载memcached服务
    -u <username>     以<username>的身份运行 (仅在以root运行的时候有效)
    -m <num>          最大内存使用,单位MB。默认64MB
    -M                内存耗尽时返回错误,而不是删除项
    -c <num>          最大同时连接数,默认是1024
    -f <factor>       块大小增长因子,默认是1.25
    -n <bytes>        最小分配空间,key+value+flags默认是48
    -h                显示帮助

    然后就可以用php的memcached客户端来试一下了。
    <?php
    //test1.php
    $memcache = new Memcache;
    $memcache->connect('localhost', 11211) or die ("Could not connect");
    $memcache->set('test', 'hello');
    ?>

    <?php
    //test2.php
    $memcache = new Memcache;
    $memcache->connect('localhost', 11211) or die ("Could not connect");
    echo $memcache->get('test');
    ?>
    依次运行test1.php, test2.php,就可以看到,放在memcached里的"hello"。
    具体的用法可以看php手册,这里就不多说了。
  • 写了一个错误处理类

    神仙 2006-08-31 12:10
    PHP 的 try - catch 总有很多东西抓不住。我还是自己写了一个。

    <?php
    /**
    * 错误处理类
    *
    * 用法:
    * ErrorHandler::begin();
    * //要捕获错误的代码
    * $errors = ErrorHandler::end();
    * 可以嵌套使用。
    *
    * 本类只捕获错误,不捕获异常。如需捕获异常,请使用try-catch。
    *
    *
    * @author XieZhenye
    */
    class ErrorHandler{
        private static $error = array();
        function begin(){
            set_error_handler(array(__CLASS__, '_errorHandler'));
            array_push(self::$error, array());
        }

        function _errorHandler($errno, $errstr, $errfile, $errline){
            if($errno == E_STRICT)
                return;
            
            $errInfo = array('errno'=>$errno, 'errstr'=>$errstr,
                        'errfile'=>$errfile, 'errline'=>$errline);
            
            array_push(self::$error[count(self::$error)-1], $errInfo);
        }

        function end(){
            restore_error_handler();
            $ret = end(self::$error);
            array_pop(self::$error);
            return $ret;
        }
    }

    ?>
  • php下aop的一个实现办法

    神仙 2006-08-05 15:11
      由于php不能动态修改类和对象的方法,实现aop就变得很困难。网上看到过用__get, __set, __call来实现的办法。这个我以前也想过。但这种办法也有很大的缺点。如果能够用 runkit 扩展,就好很多了。下面是个用 runkit 来实现方法调用拦截的例子。

    <?php
    class Target {
        function add($a, $b){
            echo $a + $b."\n";
        }
    }

    runkit_method_rename('Target', 'add', '#add');
    runkit_method_add('Target','add','$a,$b','
        echo "before call\n";
        $ret = $this->{"#add"}($a,$b);
        echo "after call\n";
        return $ret;
    ');


    $t = new Target;
    $t->add(1, 3);
    ?>

日历

关于神仙

神仙

世人都晓神仙好~~~~