关注LAMP|PHP源代码分析|web架构|PHP扩展|Erlang|服务端架构
  • 空间更换到国外了

    2010-07-22

    之前的合租空间不做了,现在换到国外了,速度上可能有点慢。

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • GFW连http://www.python.org/download/都强掉了

    2010-06-17

    防民之口甚于防川

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • 我的腾讯微博

    2010-06-06

    t.qq.com/qingliangcn

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • 装了Ubuntu 10.04

    2010-05-06

    这两天着实折腾了一把,先后安装了ubuntu的32位和64位版本,最后无赖还是选择了32位版本 — 软件支持的原因。

    之前一直因为QQ的问题无法转过来,现在有了webqq和linuxqq,暂时可以尝试下了。

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • 我心目中的英雄

    2010-03-21

    我是个凡人,但这并不影响我对英雄的仰慕、敬佩。王克勤,一个普通得名字,做的却是不普通的事!http://wangkeqin.blog.sohu.com/

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • QQ群:PHP内核与扩展研究 48448818

    2010-03-09

    QQ群:PHP内核与扩展研究 48448818
    PHP内核与扩展研究。加群请说明自己感兴趣领域或者擅长领域!否则一律不予通过,请谅

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • 使用新的域名 www.qingliangcn.com

    2010-02-25

    即日起使用新的域名 www.qingliangcn.com,原有域名保留一定时间。

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • 虎年好运,新春愉快!

    2010-02-14

    虎年好运,新春愉快!

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • Windows7试用

    2009-10-23

    这几天折腾了一下Windows7,总体的感觉不错。从体验上来说,各方面的设置都和XP类似,即使是有变化也是过渡的非常平稳。唯一感觉不太好的是Windows7的画面感觉不太舒服,看起来非常的累,我的显卡是蓝宝4830的,应该不是卡的问题,舍友安装后也觉得电影的画面看起来有格子的感觉,可能是驱动的问题。

    可能是因为我刚换的4核CPU,感觉windows7的操作似乎比xp还要流畅。

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • 折腾了许久WP,终于找到了比较好的高亮方案

    2009-07-05

    WP固然强大,但是其编辑器一直是比较鸡肋的。今晚折腾了挺久终于放弃了WP自带的编辑器,而改用强大的FCK。之后就可以不使用代码高亮插件了,方法如下:

    1.本地将IDE编写的代码复制进WORD

    2.拷贝WORD的代码,如浏览器有访问剪切板的提示则选择允许,OK,代码高亮了。

    限制:某些IDE的代码拷贝到WORD后颜色会丢失(基于Java开发的貌似都不会,而DW之内的则会丢失)

     

     

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • javascript之setTimeout使用详解

    2009-06-13

    setTimeout的第一个参数为函数名或者以""包含的js代码如果是第一种情形当函数带有参数时往往不能达到我们预期需要的效果文字说明比较抽象我们来看代码: Read More »

    作者:庆亮 | 分类目录:HTML/CSS/JS暂未分类 | 标签:
  • 第一次工作月总结

    2009-05-23

    工作已经两个月, 有一些汗水, 有一些收获, 有一些欢乐, 有一些郁闷. 前方的路依然光明, 我要继续走下去.

    整理一下两个月的收获和问题,说的不全,完全以这段时间的实践为主线。

    一 面向对象 VS 面向过程
    1.我们的选择
    项目开始时,技术经理那边决定使用面向过程作为我们的主要开发方式,当时主要的考虑点是效率和项目人员对OO和面向过程的熟悉程度。
    我们的项目是一个交易平台,预计并发、高负载、快速响应会是项目最重要的问题,再结合PHP本身的特点,我们觉得面向过程应该是我们的更好选择。
    另外,项目中,除了我本人接触的OO较多外,其他人对于OO的理解还仅仅位于“对象”上, 对OOA/OOD/Design Pattern等基本无概念,而由于我们的时间和现有资源的问题,我们也不可能进行这方面的入职培训。 所以最终我们决定使用面向过程。

    2.如何选择
    很多人大谈OO或者面向过程的好处,互相攻击对方的方法缺陷。就讨论本身而言,辩论有利于更好的交流以及对知识更深层次的理解。但也容易带来一些偏见,这些往往是由于个人的阅历经验、对新事物的心态以及是否辩证看待事物有关。每个人的工作环境、项目要求等等都不尽相同,而OO和面向过程都不是万能的解决方案,他们有各自的优缺点,有各自的适应环境(所以不能一概而论, 不能断定哪种方式绝对的好),同时也有重叠的部分(既然有重叠,那么在某些情况下使用OO和面向过程皆可,具体使用哪一种,主要取决于个人的偏好)。
    因而我们讨论两种方法,重点在于分析他们各自的利弊、适应环境,而不是打败对方。我们的目的在于赢得真理, 而不是赢得讨论。无论枪有多好,刀也不会淘汰;同时枪也的确比刀强大很多—某些情况下。 Read More »

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • FF和IE对js保留字class的支持

    2009-04-08

    ff支持 var class(只测试了class), 而ie则不支持这样的写法. 备忘.

    js关键字和保留字列表

    1. 关键字
    break,  case,  catch,  continue,  default, delete,  do,  else, finally  , for, function, if, in, instanceof, new, return, switch, this, throw, try, typeof, var, void, while, with

    2. 保留字
    abstract
    boolean
    byte
    char
    class
    const
    debugger
    double
    enum
    export
    extends
    fimal
    float
    goto
    implements
    import
    int
    interface
    long
    mative
    package
    private
    protected
    public
    short
    static
    super
    synchronized
    throws
    transient
    volatile

    作者:庆亮 | 分类目录:HTML/CSS/JS暂未分类 | 标签:
  • 自己写的日期联动菜单

    2009-04-03

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml">

        <head>

            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

            <title>Untitled Document</title>

            <script type="text/javascript">

                var yearBegin = 1900;

                var today = new Date(); 

                var yearEnd = Number(today.getFullYear()); 

                var monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

                var monthDaysP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

                window.onload = function init()

                {

                initYear();

                initMonth();

                initDay();

                }

                function writeDate(year, month, day)//

                {

                if (year < yearBegin)

                {

                year = yearBegin;

                }

                else if (year > yearEnd)

                {

                year = yearEnd;

                }

                if (month >12 || month <1)

                {

                month = 1;

                }

                //做个日期合法检查

                if (IsPinYear(year))

                {

                if (monthDaysP[month-1] < day)

                {

                day = monthDaysP[month-1];

                }

                }

                else

                {

                if (monthDays[month-1] < day)

                {

                day = monthDays[month-1];

                }

                }

                var yearObj = document.getElementById(‘year’);

                var monthObj = document.getElementById(‘monthSelect’);

                var dayObj = document.getElementById(‘daySelect’);

                yearObj.selectedIndex = year - yearBegin;

                monthObj.selectedIndex = month-1;

                dayObj.selectedIndex = day-1;

                }

                

                function initYear()

                {

                var yearObj = document.getElementById(‘year’);

                var monthObj = document.getElementById(‘monthSelect’);

                var dayObj = document.getElementById(‘daySelect’);

                for(i=yearBegin; i<=yearEnd; i++)

                {

                yearObj.options.add(new Option(i, i));

                }

                }

                function initMonth() //

                {

                var yearObj = document.getElementById(‘year’);

                var monthObj = document.getElementById(‘monthSelect’);

                var dayObj = document.getElementById(‘daySelect’);

                for(i=1; i<=12; i++)

                {

                monthObj.options.add(new Option(i, i));

                }

                }

                function initDay()//设置日期

                {

                var dayObj = document.getElementById(‘daySelect’);

                var month = getSelMonth();

                var year = getSelYear();

                dayObj.options.length = 0;

                if (IsPinYear(year))

                {

                days = monthDaysP[month-1];

                for(i=1; i<=days; i++)

                {

                dayObj.options.add(new Option(i, i));

                }

                }

                else

                {

                days = monthDays[month-1];

                for(i=1; i<=days; i++)

                {

                dayObj.options.add(new Option(i, i));

                }

                }

                }

                function monthChange()

                {

                initDay();

                }

                function yearChange()//年份发生改变

                {

                initDay();

                }

                function getSelYear()//获得当前选择的年

                {

                var yearObj = document.getElementById(‘year’);

                var yearIndex=yearObj.selectedIndex;

                return yearObj.options[yearIndex].value;

                }

                function getSelMonth()//获得当前选择的月份

                {

                var monthObj = document.getElementById(‘monthSelect’);

                var monthIndex=monthObj.selectedIndex;

                return monthObj.options[monthIndex].value;

                }

                function IsPinYear(year)//判断是否闰平年

                { return(0 == year%4 && (year%100 !=0 || year%400 == 0))}

            </script>

        </head>

        <body>

            <select name="year" id="year" onchange="yearChange();">

            </select>

            <select name="monthSelect" id="monthSelect" onchange="monthChange();">

            </select>

            <select name="daySelect" id="daySelect">

            </select>

            <a href="javascript:writeDate(1987, 9, 7);">19870907</a>

            <a href="javascript:writeDate(2987, 9, 7);">不合法的日期29870907</a>

            <script type=‘text/javascript’>

                //<![CDATA[

                if (document.getElementById('processtime')) 

                    document.getElementById('processtime').innerHTML = "<span class='runtimedisplay'>Run in 51 ms, 8 Queries, Gzip enabled.</span>";

                //]]>

            </script>

        </body>

    </html>

    作者:庆亮 | 分类目录:HTML/CSS/JS暂未分类 | 标签:
  • PHP单例模式的必要性

    2009-03-30

      多数人都是从单例模式的字面上的意思来理解它的用途, 认为这是对系统资源的节省, 可以避免重复实例化, 是一种"计划生育".  而PHP每次执行完页面都是会从内存中清理掉所有的资源. 因而PHP中的单例实际每次运行都是需要重新实例化的, 这样就失去了单例重复实例化的意义了. 单单从这个方面来说, PHP的单例的确有点让各位失望. 但是单例仅仅只有这个功能和应用吗? 答案是否定的,我们一起来看看.

    1.
    php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时(废话), 如果使用单例模式, 则可以避免大量的new 操作消耗的资源.

    2.
    如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看zend Framework的FrontController部分.

    3.
    在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志.避免到处var_dump, echo.

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • Zend Framework自定义路由一则

    2009-02-22

    经常性的看到如下的url:
    http://www.example.com/id/4
    或者更干脆
    http://www.example.com/3
    链接清爽,且搜索引擎友好.
    ZF为我们提供了快速简单的实现方式,代码如下
     

    //$front为前段控制器实例

    $router $front->getRouter();

    //实现如http://www.example.com/id/4类型的url

    $router->addRoute(

    ‘test1′

        new Zend_Controller_Router_Route(

         ‘id/:aid’

            array(‘controller’ => ‘index’ ‘action’ => ‘view’)

        ))

        //实现如http://www.example.com/3类型的url

        ->addRoute(

        ‘test2′

        new Zend_Controller_Router_Route(

         ‘/:aid’

            array(‘controller’ => ‘index’ ‘action’ => ‘view’)

            )

    );

     

    addRoute有两个参数,第一个为URL规则名称,第二个为URL规则的实例,该实例对应类必须实现Zend_Controller_Router_Interface接口,通常为Zend_Controller_Router_Route.
    Zend_Controller_Router_Route有三个参数,定义原型为:
    public function __construct($route, $defaults = array(), $reqs = array())
    其中,
    $route为URL匹配的方式, 例如test1实例中的’id/:aid’表示匹配http://www.example.com/id/x,":"代表之后为URL变量分隔符, 表示在实际的URL中aic为变量.
    $defaults表示在URL匹配$route指定的形式时默认的各种参数,本例中设置了 控制器为index,动作为view, 所以当URL匹配时则相当于访问了http://www.example.com/index/view/id/x
    $reqs则用于指定匹配的正则表达式, 例如 我们可以指定aid为整数时才匹配, 则:
     

    $router->addRoute(‘test1′,    

        new Zend_Controller_Router_Route(‘id/:aid’,    

                array(   

                    ‘controller’=>‘index’,   

                    ‘action’=>‘view’                           

                  )   

              ),   

        array(‘aid’=>‘\d+’)   

    );

     

    简单的介绍下,更多请查看ZF手册.

    补充:
    定义了’id/:aid’形式的路由规则之后,在动作控制器中,使用
    $this->_request->getParam(‘aid’);
    来获得id值.

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • Zend Framework代码实例 — 手工扑捉PHP内部错误

    2009-02-20

    很明显本文的标题不够准确、不能很好体现本文所要表达的意思, 如果你想明白我想说什么, 那么你只好看下去. 呵呵.
    今天看ZF源码时看到类Zend_Config_Ini中一段比较有意思的代码:

    set_error_handler(array($this‘_loadFileErrorHandler’));           

    $iniArray = parse_ini_file($filenametrue); // Warnings and errors are suppressed   

    restore_error_handler();   

    // Check if there was a error while loading file   

    if ($this->_loadFileErrorStr !== null) {   

    /**  

    @see Zend_Config_Exception  

    */  

        require_once ‘Zend/Config/Exception.php’;   

        throw new Zend_Config_Exception($this->_loadFileErrorStr);   

    }   

     

    看了这段代码我的第一反应时为什么要这样处理呢?立刻转到错误处理方法看看
     

    protected function _loadFileErrorHandler($errno$errstr$errfile$errline)   

    {    

        if ($this->_loadFileErrorStr === null) {   

            $this->_loadFileErrorStr = $errstr;   

        } else {   

            $this->_loadFileErrorStr .= (PHP_EOL . $errstr);   

        }   

    }

    很简单,错误处理方法只是在出错时将类的$_loadFileErrorStr 属性设置为出错字符串.

    翻看PHP手册, 从parse_ini_file函数的定义我们可以看出该函数在出现错误时(例如文件不存在,ini文件格式不正确等等)直接输出错误信息, 而不是通过返回值来表达出错信息, 这样我们在使用该函数时就无法很好的控制——在出错时合适的终止程序并给出错误提示或者不可避免的将可能不可理解的错误信息呈现给用户, 为了能够比较简单的手工处理出错信息, 这里采用了这个修改出错处理函数的方法, 由于这个出错函数比较有局限性, 所以之后又立即恢复了出错处理函数.
     

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • PHPUnit简单入门

    2008-10-14

    Php的测试驱动开发闻之已久,却从来没有试用过,今天又看到相关的介绍,就花了点时间简单的看了下. 以下为从官方实例翻译过的来笔记:

    从一个案例开始
      通常我们在测试我们的php程序时,会使用诸如print,echo等语句来输出一些结果,以查看我们的程序是否正常或者哪里出错.例如:

    <?php   

    $array array();   

    print sizeof($array);   

    array_push($array‘newElement’);   

    print sizeof($array);  

    结果
    0
    1
    这样我们就知道$array变量是我们预期的结果.现在我们希望能够直观给出测试的结果,而不是看到0, 1这样的结果后再去判断. 我们修改测试代码:

    <?php   

    $array array();   

    print (sizeof($array) == 0) ? "OK\n" "Not Ok\n";   

    array_push($array‘newElement’);   

    print (sizeof($array) == 1) ? "OK\n" "Not Ok\n"

    结果
    OK
    OK

    为了方便重用及修改我们将测试代码的断言部分置于函数中

    <?php   

    $array array();   

    assertTrue(sizeof($array) == 0);   

    array_push($array‘newElement’);   

    assertTrue(sizeof($array) == 1);   

      

    function assertTrue($condition)   

    {   

      if (!$condition)   

        throw new Exception(‘Assertion Failed!’);   

    }  

     

    如此我们就可以简单的实现测试的自动化了.
    自动测试的目的是减少错误,使用自动测试你能够明显发现你的代码的错误的减少.还有一些其他的好处……PHPUnit的目标就是如此.那么我们开始我们的PHP Unit Test吧.

    一.  安装PHPUnit需要使用Pear Installer安装, 加入phpunit频道到pear寻找频道

    D:\wamp\bin\php\php5.2.6>pear channel-discover pear.phpunit.de
    Adding Channel "pear.phpunit.de" succeeded
    Discovery of channel "pear.phpunit.de" succeeded

    安装PHPUnit
    D:\wamp\bin\php\php5.2.6>pear install phpunit/PHPUnit
    Did not download optional dependencies: pear/Image_GraphViz, pear/Log, use –all
    deps to download automatically
    phpunit/PHPUnit can optionally use package "pear/Image_GraphViz" (version >= 1.2
    .1)
    phpunit/PHPUnit can optionally use package "pear/Log"
    phpunit/PHPUnit can optionally use PHP extension "pdo_sqlite"
    phpunit/PHPUnit can optionally use PHP extension "xdebug" (version >= 2.0.0)
    downloading PHPUnit-3.3.4.tgz …
    Starting to download PHPUnit-3.3.4.tgz (268,962 bytes)
    ………………………………………………..done: 268,962 bytes
    install ok: channel://pear.phpunit.de/PHPUnit-3.3.4

    安装成功,在pear路径下即可看到PHPUnit文件夹,所有PHPUnit源码都在其中.

    成功安装之后,会在PHP主目录下生成一个PHPUnit.bat的文件, 这样我们编写测试用例之后可以在命名行下使用如下的语法即可自动进行测试:
    > PHPUnit test_begin.php
    test_begin.php为包含了测试用例的文件

    对每个测试,PHPUnit命令行测试工具打印一个字符表示进程:

      测试成功打印“.”。

      运行测试方法发生了断言失败打印“F”。

      运行测试方法发生了错误打印“E”。

    二.  开始一个简单的示例
    对于刚刚在开始中的示例(测试数组大小),我们可以使用PHPUnit来编写自动化测试代码了:

    <?php   

    //filename: test_begin.php   

      

    require_once(‘PHPUnit/Framework.php’);   

      

    class ArrayTest extends PHPUnit_Framework_TestCase   

    {       

      public function testNewArrayIsEmpty()       

      {           

        // 定义一个数组变量           

        $fixture array();            

        // 断言数组的大小为0.           

        $this->assertEquals(0, sizeof($fixture));       

      }        

         

      public function testArrayContainsAnElement()       

      {           

        // 定义一个数组变量           

        $fixture array();            

        // 为数组变量增加一个元素           

        $fixture[] = ‘Element’;            

        // 断言该数组大小为1           

        $this->assertEquals(1, sizeof($fixture));       

      }   

    }  

     

    > PHPUnit test_begin.php
    结果:
    PHPUnit 3.3.4 by Sebastian Bergmann.

    ..

    Time: 0 seconds

    OK (2 tests, 2 assertions)

    ..  表示两次测试成功

    这个例子显示了使用PHPUnit编写测试用例的基本步骤:
    1.  测试类名为ClassTest,其中Class为你的对象名
    2.  测试类ClassTest通常派生自PHPUnit_Framework_TestCase
    3.  测试通常是一些名称为test*的公共方法. 另一种方法是, 你可以在方法的注释说明中使用@test 标记来表明这是一个测试方法.
    4.  诸如assertEquals之类的方法用以测试一个实际值同预想值是否相对.

    一个测试方法可以接受任何的参数(任意类型和数量), 参数通过provider()方法来提供,或者同测试方法一下,使用@dataProvider注释标记来标明.关于provider()的返回参数也有一定要求: 要么是数组(每个数据作为一个参数, 数组中可以包含多组参数), 要么是实现了Iterator接口的对象

     

    <?php   

    class DataTest extends PHPUnit_Framework_TestCase   

    {   

        /**  

         * @dataProvider provider  

         */  

        public function testAdd($a$b$c)   

        {   

            $this->assertEquals($c$a $b);   

        }   

        

        public function provider()   

        {   

            return array(   

              array(000),   

              array(011),   

              array(101),   

              array(113)   

            );   

        }   

    }  

    ?>

     

     

    结果:
    PHPUnit 3.3.4 by Sebastian Bergmann.
    …F
    Time: 0 seconds
    There was 1 failure:
    1) testAdd(DataTest) with data set #3 (1, 1, 3)
    Failed asserting that matches expected value .
    D:\wamp\www\Test\php\unittest\data_provider.php:9

    FAILURES!
    Tests: 4, Assertions: 4, Failures: 1.

    …F  表示三个测试成功,一次测试失败.
    到此就可以简单的使用PHPUnit了,当然PHPUnit的功能远不止此,测试人员应该好好学习一下. 

     

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • upload.class.php的一点改进

    2007-04-27

    /**
    *
    * @version $Id: upload.class.php,v 1.4 2007/04/27 00:52 xm.zhuge Exp $
    * @copyright (c) 2007 Nandou Group
    * @license http://opensource.org/licenses/gpl-license.php GNU Public License
    */

    *优化了结果信息提示
    *更改了默认构造函数的实现,方便参数传递
    +增加文件保存路径统计,文件上传数目统计

    代码下载

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • upload.class.package.php 1.2.0(文件上传组件)

    2007-04-25

    upload.class.package.php 1.2.0(文件上传组件)
    /**
    *
    * @package NdPhp
    * @version $Id: upload.class.package.php ,v 1.2.0 2007/04/25 11:45:24 xm.zhuge Exp $
    * @copyright (c) 2007 Nandou Studio
    * @license http://opensource.org/licenses/gpl-license.php GNU Public License
    */
    +多文件上传表单生成
    +多文件上传处理
    +取消最终结果自动输出,方便同模板结合输出
    *重命名文件名修正
    ……

    代码下载

    作者:庆亮 | 分类目录:暂未分类 | 标签:
  • Pages: 1 2 下一页