PHP的优化,缓冲,压缩实际的解决方案 Posted by admin on 8月 17th, 2008

本文提出了实用的PHP的优化,缓冲,压缩实际的解决方案。

作为流行的 Web 编程语言, PHP 的最大优势就是速度。 PHP4 已经在这方面做的非常好了,你几乎找不到比它更快的脚本编程语言了。但是如果你的应用负荷很大,而带宽又比较小,或者有其他的瓶颈影响你的服务器性能,那么,你不妨试试笔者为你开出的几个药方,看看是否灵验。

一、代码优化

一谈到代码优化,或许你想到的就是整齐明了的代码,但是本文的意思却不是在此,因为如果要寻求速度的话,就要对PHP 源码作相应的调整。一般说来就是去掉多余的注释,让代码不可读。但是这对于一个具有良好素养的程序员来说,简直就是不可思议的。好在Zend Technologies 公司发布了 Zend 优化引擎可以帮助你做到这一点。它现在是免费的,但是你必须遵循 Zend Optimizer 许可。这个产品可以对引擎产生的中间代码进行优化。

安装这个引擎比较简单,下载对应平台的版本以后,解开压缩文件,然后在 php.ini 文件里面加上下面两行,重新启动 Web 服务器,就搞定了。

zend_optimizer.optimization_level=15
zend_extension=”/path/to/ZendOptimizer.so”
zend_loader.enable=Off

如果是 Win32 平台的话就应该是:

zend_optimizer.optimization_level=15
zend_extension_ts=”C:path oendOptimizer.dll”
zend_loader.enable=Off

啊!没有搞错吧?怎么是三行?其实第三行是可选的。因为看起来把 zend_loader 关掉能提高一点速度,因此值得把这第三行放到 php.ini 。需要注意的是,关掉的前提条件是你没有在使用 Zend 加密程序。

二、缓冲

如果想要更进一步提升速度,我们就需要考虑采用缓冲技术了。有一些可选的解决方案,包括 Zend Cache (测试版本), APC, 以及 Afterburner Cache,另外还有 jpCache 等。

以上这些都是属于缓冲模块,他们把第一次对.php 文件请求产生的中间代码存储在 Web 服务器的内存中,然后对以后的请求返回“编译好”的版本。因为这样减少了磁盘读写,而且都在内存工作,所以这个过程能显著提升应用性能,

现成的这类产品比较多,到底选择谁呢?

Zend Cache 是一款不错的商业产品,在第一次加载那些很大的 PHP 页面后,你会明显感受到速度的提升,服务器会留出更多的资源。可惜这个产品是要花银子的,但是在有些情形下,你可不要吝啬这些银子。

Afterburner Cache 是 Bware Technologies 的产品,目前还处于 Beta 版本,看起来似乎和 Zend Cashe 一样,但是它不能达到 Zend Cache 那样好的效果,也不能和 Zend 优化引擎一起工作,但是它是免费的,所以我采用了这个模块。

APC (Alternative PHP Cache) 是 Community Connect 发布的又一个免费模块,看起来似乎可以用于生产环境了。

三、Web 内容压缩

对于日益拥挤的网络来说,节约带宽就像节约用水一样是十分值得提倡的。根据IETF 标准,大多数浏览器应该支持使用 gzip 压缩的内容。也就是说你可以把用 gzip 压缩的内容发送给浏览器,浏览器会透明的解压数据。

mod_gzip 是 Remote Communications 公司推出的免费 Apache 模块,能把静态的Web 内容压缩后发送给浏览器。对于大多数静态网页来说,这个模块十分合适。尽管

Remotecommunications 公司的人说这个模块支持所有那些 mod_php, mod_perl,mod 什么产生的动态内容,但是看起来还是不能工作,从 mod_gzip 的邮件列表来看,这个问题估计要到1.3.14.6f 才能解决。

如果要压缩动态内容的话,我们可以采用class.gzip_encode.php,一个在脚本开始和结束时使用的 PHP 类。对整个网站来说就是在 php.ini 的 auto_prepend 和 auto_append 中调用其中的函数。详细你可以阅读这个类的程序,这个程序注释得很好,作者几乎把什么都告诉你了。不过使用之前,你的 PHP 要编译为支持 zlib。

对于 PHP 4.0.4 来说,一个新的解决方案就是使用 ob_gzhandler,能达到和上面的类一样的效果,只要简单的在 php.ini 加入下面这句话就可以了:

output_handler = ob_gzhandler ;

这能让 PHP 激活输出缓冲,并压缩所有输出。如果有什么特殊的理由不想让所有的内容都压缩输出的话,可以采用在 .htaccess 文件中加入下面的行,对对应目录下的文件进行压缩。

php_value output_handler ob_gzhandler

也可以直接在 PHP 代码中加入:

ob_start(”ob_gzhandler”);

这项压缩技术十分有效,但是对 Netscape Communicator 用户来说,因为不能压缩图形文件,所以看上去没有完姆⑺停虼吮匦牍乇斩?jpeg 和 gif 文件的压缩,IE 没有这个问题。

结论:

采用本文所讨论的技术应该能改善你的网站性能,但是需要注意的是:

- PHP 可能不是导致瓶颈的原因,仔细检查其他原因(例如:数据库

- 你不可能把服务器性能调节到最高状态。因此在埋怨 PHP 及其缓冲之前,考虑是否该升级服务器了,或者采用动态负载平衡技术(那可是一大笔银子哦)。

- 不要低估内容压缩,在你 100 Mb 的内部网上面看到 PHP 应用的速度提升时,不要忘记使用调制解调器的用户在哪里埋怨你的 100Kb 的 HTML 页面。

走进Zend Framework框架编程(五):Zend_Controller进阶 Posted by admin on 8月 15th, 2008

在前边的例子中,我们的index.php引导文件所在的文件夹与控制器、视图等所在的文件夹是不同的,这并不符合一般网站项目的文件夹的组织习惯。从本部分开始,我们把他们放在同一个文件夹中,这是因为ZF提供了灵活的文件夹组织和配置能力。
    我们新的文件夹结构如下:
  …/htdocs
    library
      Zend
    Phpchina2.com
      controllers
      models
      views
      index.php
      .htaccess
    即把原来app_phpchina1.com文件夹下的子文件夹Controllers、models、views转移到文件夹phpchina1.com下,与index.php和.htaccess文件放在一起。为了不覆盖原来的代码,我们把原来的phpchina1.com文件夹拷贝一份,命名为phpchina2.com。
    为了测试,我们建立一个新的虚拟主机phpchina2.com。这可以仿照前面的phpchina1.com来完成,即在httpd.conf中添加:
    <VirtualHost *:8080>
        ServerAdmin any@any.com
        DocumentRoot “C:/Program Files/Apache Software Foundation/Apache2.2/htdocs/phpchina2.com”
        ServerName phpchina2.com
        ErrorLog “logs/phpchina2.com-error.log”
        CustomLog “logs/phpchina2.com-access.log” common
    </VirtualHost>
    重新启动Apache服务。
    然后再在hosts文件中加一条
    <服务器IP>      phpchina1.com
    以后即可以以http://phpchina2.com:8080/*.*的形式访问新的网站。但现在暂时还不能像前边的例子一样运行原来的示例代码,因为还需要对index.php里的路径配置进行调整。
    我们把语句PATH_SEPARATOR . ‘../App_phpchina1.com/models/’修改为:
    PATH_SEPARATOR . ‘models/’
    把语句”default”=>’../app_phpchina1.com/controllers’修改为:
    “default”=>’controllers’

    然后用浏览器打开地址http://phpchina2.com:8080,就可以看到和原来一样,显示了字符串“Hello PHPChina1.com!”。也可以打开http://phpchina2.com:8080/news显示“Welcome to News!”字符串。

    下一步我们对Controllers进行扩展改造。比如我们有这样的需求:如果一个网站项目很大,有多个模块,Controllers文件夹下将有大量的控制器文件,我们打算通过按模块建立子文件夹对其进行分类存放,IndexController.php控制器文件存放在index文件夹下,news控制器文件存放在news文件夹下。
    首先修改index.php文件,把
      $fc->setControllerDirectory(array(
          “default”=>’controllers’,
        ));
    处的”default”=>’controllers’修改为
    “default”=>’controllers/index’
    这时http://phpchina2.com:8080地址就可以打开了,显示结果与原来相同。
    但要访问news文件夹下的NewsController.php控制器,必须把news添加到搜索路径,并为其命名,我们这里命名为other模块,这样我们就添加以下语句:
    $fc->addControllerDirectory(’controllers/news’, ‘other’);
    然后打开地址http://phpchina2.com:8080/news,看不到原来的结果。
    再打开地址http://phpchina2.com:8080/otherhttp://phpchina2.com:8080/other/news,也看不到原来的结果。
    原来,需要修改NewsController.php中的语句
    Class NewsController extends Zend_Controller_Action为
    class other_NewsController extends Zend_Controller_Action
    即在类名前加“other_”字符串。然后访问地址
    http://phpchina2.com:8080/other/news
    即可得到正确的结果。
    这里有一个新问题,即http://phpchina2.com:8080/other/news和index默认文件夹的
    OtherController控制器中的newsAction方法访问路径是相同的,如果index文件夹下同时还有文件OtherController.php,内容为:
    <?php
    class OtherController extends Zend_Controller_Action
    {
      function newsAction()
      {
        echo “This is OtherController.php ==> newAction”;
      }
    }
    ?>
    那么http://phpchina2.com:8080/other/news会不会显示
    This is OtherController.php ==> newAction
    字符串的结果呢?不会的,因为按模块搜索访问方式优先。有了other搜素路径名,就不能再访问默认文件夹下的other控制器中的任何方法了,即使搜素路径下没有任何对应的控制器文件,也不能访问。即,即使没有news文件夹下的NewsController.php文件,http://phpchina2.com:8080/other/news也不会获得index文件夹下OtherController.php中newsAction方法的结果。
    这里的搜素路径和Web服务器的虚拟路径有点相似。但是因为可以用代码指定,所以更灵活一些。后面,我们根据这一点可以灵活的组织网站项目的文件夹结构。
    我们对前边ZF中请求URL的格式做一些补充,原URL格式
    http://host_name/controller_name/action_name/param1/ value1/param2/ value2…
    可以扩展为:
    http://host_name/路径/controller_name/action_name/param1/ value1/param2/ value2…
    路径名需要作为“路径名_”字符串的形式加在
    代码“Class controller_name”的实现代码的前边,成为“Class路径名_controller_name”的形式。明白了这点,在分析ZF的源代码的时候,就不会被路径问题所迷惑了。

作者“张庆”文章出处phpchina。

走进Zend Framework框架编程(四):Zend_Controller和引导文件 Posted by admin on 8月 15th, 2008

1,理解Zend_Controller
    Zend_Controller是ZF的MVC体系的核心部份。
    Front Controller(前端控制器)设计模式具体是由Zend_Controller_Front静态类实现的,所有的请求都必须通过前端控制器,并基于请求的URL被分发(dispatch)到不同的控制器去来处理。
    Zend_Controller体系具有可扩展性,可以通过继承已有的类,或者通过实现各种接口和继承抽象类来写自己的扩展类,也可以编写插件或者助手类(helper)来增强系统的功能。
    Zend_Controller_Front类的声明和所有初始化工作,以及执行dispatch()方法等都是在Bootstrap文件即入口程序中完成的,在ZF中,通常就是指index.php文件。因为用户的所有请求都是从index.php进入的,所以需要配置Web服务器,把所有请求导向到index.php文件中,这些我们在前边已经完成了,而这里我们已经对其原因有了更深入的理解。
    2,理解ZF是如何处理HTTP请求的:
    例如有一个URL请求地址http://host_name/controller_name/action_name
    其中host_name一般是一个域名,例如www.why100000.com。默认情况下,该URL的第一个部份controller_name会映射到一个控制器,第二个部份action_name则映射到控制器类中的Action(控制器类内部的一个方法)。在本例中,其服务器路径为/controller_name/action_name,则会映射到controller_name控制器和action_name这个Action。如果不存在该action,则会默认调用index这个action。如果控制器不存在,则会默认自动调用index控制器(按照Apache的命名惯例,将自动映射到DirectoryIndex文件)。
    接下来,Zend_Controller的dispatcher会根据控制器的名称找到具体的控制器类。通常它会把控制器名称加上Controller。因此,上例中controller_name控制器与controller_name Controller类相对应。
    类似地,action会映射到控制器类中的一个方法。默认情况下,会被转成小写字母,然后加上“Action”字符串。因此,上例中action_name这个action与 action_name Action相对应。于是最终我们访问URL调用的是
    controller_name Controller-> action_name Action()
    方法。
    控制器类保存为controller文件夹下的一个php文件中,文件名前缀约定与controller类的名字相同。例如Controller_nameController.php。
    现在我们根据以上约定创建一个控制器和Action方法:
    <?php
    class Controller_nameController extends Zend_Controller_Action
    {
      function action_nameAction()
      {
    ……
    }
    }
    ?>
    以上代码需要以文件名Controller_nameController.php保存,并存放到controllers文件夹下。
    ZF有一个约定,就是当url中不指定控制器名时,默认为index控制器;当不指定action名时,默认为index action。于是,当控制器名和action都不指定时,就执行index控制器类的indexAction方法,这时类文件形如:
    <?php
    class IndexController extends Zend_Controller_Action
    {
      function indexAction()
      {
    ……
    }
    }
    ?>
    该代码保存为IndexController.php文件名。
    一般的控制器类都有一个indexAction函数,作为控制器的默认方法。
    注意在url中,控制器名和action可以同时省略:即形如http://host_name/
    也可以省略action名,执行indexAction方法,形如http://host_name/controller_name/
    但不能省略控制器名而指定action名,即
    http://host_name//action_name
    是不正确的。
    形如http://host_name/xxx的地址,xxx被认为是控制器名。
    对于我们上一节的示例,当用浏览器打开地址http://phpchica1.com:8080,其实执行的是IndexController控制器类的indexAction方法,执行了语句
    echo “Hello PHPChina1.com!”;
    而我们在IndexController控制器类中再建立一个成员函数:
      function otherAction()
      {
        echo “this is other Action.”;
      }
    在浏览器地址栏输入http://phpchica1.com:8080/index/other,将会输出字符串“this is other Action.”。
    3,对引导(bootstrap)文件index.php的解释
    error_reporting(E_ALL|E_STRICT);语句打开了错误输出开关,用于代码调试,正式发布的代码应该屏蔽错误信息。
    date_default_timezone_set(’Asia/Shanghai’);设定时区,该语句不能省略。
    set_include_path(……);很关键的语句。用于设定类库的包含路径,ZF的系统类库就是在这里指定的。注意如果php.ini文件里的include_path包含了ZF类库的路径,这里就可以不用包含../library路径。但是在自己的代码里指定ZF类库路径更方便一些,一般推荐这么做。../App_phpchina.com/models/路径下包含我们自己开发的自定义类文件。没有自定义类文件,可以不用包含该路径。get_include_path再取得php.ini的其他包含路径,一同指定我们的应用程序使用。
    include “Zend/Loader.php”;语句装载ZF的类加载器。Zend/Loader.php正是从../library路径下取得的。
    Zend_Loader::registerAutoload();自动加载类。该语句可以分别用以下两段代码代替,效果相同:
    第一段代码:
      function __autoload($class)
      {  Zend_Loader::loadClass($class);  }
    第二段代码:
      Zend_Loader::loadClass(’Zend_Controller_Front’);
    $fc = Zend_Controller_Front::getInstance();取得Zend_Controller_Front类实例。
    $fc->setControllerDirectory(……);指定一组控制器文件路径,参数是数组。让前端控制器知道从哪里去找我们的控制器类。如果仅有一个控制器文件夹,也可以写成:
    $fc->setControllerDirectory(’../App_www.mydomain.com/controllers’);
    $fc->throwExceptions(true);设置抛出错误信息。
    $fc->setParam(’xxx’, true);格式的语句用于设置一些参数。
    其中$fc->setParam(’noViewRenderer’, true);指明不使用视图,false 是默认值。
    $fc->dispatch();语句开始执行分发,导向到请求的控制器执行后续代码。
    这是一个功能较少的、典型的bootstrap引导文件,每个ZF应用中,该文件大同小异,只是个别参数设置不同。这个文件可以作为一个模板,拷贝到其他ZF应用中使用。这个文件与ZF应用的文件夹结构有直接关系,配置时一定要仔细。调整一些参数后可以使ZF有一些其他的额外功能。这点我们以后还会接触到。
    4,ZF中请求URL的格式
    Zend Framework的控制器 Zend_Controller使网站支持“干净的URL”。它把对控制器、方法的请求和参数的传递变形为对文件夹的访问形式。URL的完整格式为:
    http://host_name/controller_name/action_name/param1/ value1/param2/ value2…
    除过前边的host_name外,controller_name和action_name为控制器和方法名,后边的残出和值必须一一对应。
    传递的参数,在action方法中以 $this->_getParam(”参数名”);的方法来取得其值。
    因为有严格的对应关系,一般在有参数传递的情况下,控制器和action的名字都不能省略,否则会出现歧义。
    我们现在在
    C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\app_phpchina1.com
    \controllers
    文件夹下建立一个NewsController.php文件,内容为:

复制内容到剪贴板

PHP代码:

<?php

      class NewsController extends Zend_Controller_Action

      {

        function indexAction()

        {

          echo “Welcome to News!”;

        }

        function pageAction()

        {

          $id $this->_getParam(“id”);

          echo “ID: ”.$id.“<BR>”;

          $type $this->_getParam(“type”);

          echo “TYPE: ”.$type.“<BR>”;

        }

      }

    ?>

然后我们以http://phpchina1.com:8080/news/page/id/001/type/typename地址访问该文件,会得到以下显示结果,可以看到已经正确的获得了传递的参数:
    ID: 001
    TYPE: typename
    我们看到,ZF访问框架内的控制器方法,不是通过从url中访问控制器类php文件来实现的,而是在index.php中前端控制器的控制下对对应的控制器及其方法进行访问,一切过程和细节都被ZF框架屏蔽了,我们只要写出正确的url就能访问到对应的程序逻辑。
    我们可以试着访问http://phpchina1.com:8080/index.php地址,实际上执行的还是IndexController控制器的indexAction方法,输出字符串“Hello PHPChina1.com!”。而想直接访问IndexController.php和NewsController.php文件,我们甚至连它们的url路径是什么都无法知道。

作者“张庆”文章出处phpchina

做一个合格的程序员 Posted by admin on 8月 7th, 2008

1:团队精神和协作能力     
  把它作为基本素质,并不是不重要,恰恰相反,这是程序员应该具备的最基本的,也是最重要的安身立命之本。把高水平程序员说成独行侠的都是在呓语,任何个人 的力量都是有限的,即便如linus这样的天才,也需要通过组成强大的团队来创造奇迹,那些遍布全球的为linux写核心的高手们,没有协作精神是不可想 象的。独行侠可以作一些赚钱的小软件发点小财,但是一旦进入一些大系统的研发团队,进入商业化和产品化的开发任务,缺乏这种素质的人就完全不合格了。      
   
  2:文档习惯     
  说高水平程序员从来不写文档的肯定是乳臭未干的毛孩子,良好的文档是正规研发流程中非常重要的环节,作为代码程序员,30%的工作时间写技术文档是很正常 的,而作为高级程序员和系统分析员,这个比例还要高很多。缺乏文档,一个软件系统就缺乏生命力,在未来的查错,升级以及模块的复用时就都会遇到极大的麻 烦。     
   
  3:规范化,标准化的代码编写习惯     
  作为一些外国知名软件公司的规矩,代码的变量命名,代码内注释格式,甚至嵌套中行缩进的长度和函数间的空行数字都有明确规定,良好的编写习惯,不但有助于代码的移植和纠错,也有助于不同技术人员之间的协作。     
  有些coding   fans叫嚣高水平程序员写的代码旁人从来看不懂,这种叫嚣只能证明他们自己压根不配自称程序员。代码具有良好的可读性,是程序员基本的素质需求。     
  再看看整个linux的搭建,没有规范化和标准化的代码习惯,全球的研发协作是绝对不可想象的。     
  4:需求理解能力     
  程序员需要理解一个模块的需求,很多小朋友写程序往往只关注一个功能需求,他们把性能指标全部归结到硬件,操作系统和开发环境上,而忽视了本身代码的性能 考虑,有人曾经放言说写一个广告交换程序很简单,这种人从来不知道在百万甚至千万数量级的访问情况下的性能指标是如何实现的,对于这样的程序员,你给他深 蓝那套系统,他也做不出太极链的并访能力。性能需求指标中,稳定性,并访支撑能力以及安全性都很重要,作为程序员需要评估该模块在系统运营中所处的环境, 将要受到的负荷压力以及各种潜在的危险和恶意攻击的可能性。就这一点,一个成熟的程序员至少需要2到3年的项目研发和跟踪经验才有可能有心得。     
   
  5:复用性,模块化思维能力     
  经常可以听到一些程序员有这样的抱怨,写了几年程序,变成了熟练工,每天都是重复写一些没有任何新意的代码,这其实是中国软件人才最大浪费的地方,一些重复性工作变成了熟练程序员的主要工作,而这些,其实是完全可以避免的。     
  复用性设计,模块化思维就是要程序员在完成任何一个功能模块或函数的时候,要多想一些,不要局限在完成当前任务的简单思路上,想想看该模块是否可以脱离这 个系统存在,是否可以通过简单的修改参数的方式在其他系统和应用环境下直接引用,这样就能极大避免重复性的开发工作,如果一个软件研发单位和工作组能够在 每一次研发过程中都考虑到这些问题,那么程序员就不会在重复性的工作中耽误太多时间,就会有更多时间和精力投入到创新的代码工作中去。     
  一些好的程序模块代码,即便是70年代写成的,拿到现在放到一些系统里面作为功能模块都能适合的很好,而现在我看到的是,很多小公司软件一升级或改进就动辄全部代码重写,大部分重复性工作无谓的浪费了时间和精力。     
   
  6:测试习惯     
  作为一些商业化正规化的开发而言,专职的测试工程师是不可少的,但是并不是说有了专职的测试工程师程序员就可以不进行自测;软件研发作为一项工程而言,一 个很重要的特点就是问题发现的越早,解决的代价就越低,程序员在每段代码,每个子模块完成后进行认真的测试,就可以尽量将一些潜在的问题最早的发现和解 决,这样对整体系统建设的效率和可靠性就有了最大的保证。     
  测试工作实际上需要考虑两方面,一方面是正常调用的测试,也就是看程序是否能在正常调用下完成基本功能,这是最基本的测试职责,可惜在很多公司这成了唯一 的测试任务,实际上还差的远那;第二方面就是异常调用的测试,比如高压力负荷下的稳定性测试,用户潜在的异常输入情况下的测试,整体系统局部故障情况下该 模块受影响状况的测试,频发的异常请求阻塞资源时的模块稳定测试等等。当然并不是程序员要对自己的每段代码都需要进行这种完整测试,但是程序员必须清醒认 识自己的代码任务在整体项目中的地位和各种性能需求,有针对性的进行相关测试并尽早发现和解决问题,当然这需要上面提到的需求理解能力。     
   
  7:学习和总结的能力     
  程序员是人才很容易被淘汰,很容易落伍的职业,因为一种技术可能仅仅在三两年内具有领先性,程序员如果想安身立命,就必须不断跟进新的技术,学习新的技能。     
  善于学习,对于任何职业而言,都是前进所必需的动力,对于程序员,这种要求就更加高了。但是学习也要找对目标,一些小coding   fans们,他们也津津乐道于他们的学习能力,一会学会了asp,一会儿学会了php,一会儿学会了jsp,他们把这个作为炫耀的资本,盲目的追逐一些肤 浅的,表面的东西和名词,做网络程序不懂通讯传输协议,做应用程序不懂中断向量处理,这样的技术人员,不管掌握了多少所谓的新语言,永远不会有质的提高。      
  善于总结,也是学习能力的一种体现,每次完成一个研发任务,完成一段代码,都应当有目的的跟踪该程序的应用状况和用户反馈,随时总结,找到自己的不足,这样逐步提高,一个程序员才可能成长起来。     
  一个不具备成长性的程序员,即便眼前看是个高手,建议也不要选用,因为他落伍的时候马上就到了。     
  具备以上全部素质的人,应当说是够格的程序员了,请注意以上的各种素质都不是由IQ决定的,也不是大学某些课本里可以学习到的,需要的仅仅是程序员对自己工作的认识,是一种意识上的问题。

第二节 PHP5 的对象模型 Posted by admin on 8月 7th, 2008

PHP5有一个单重继承的,限制访问的,可以重载的对象模型. 本章稍后会详细讨论的”继承”,包含类间的父-子关系. 另外,PHP支持对属性和方法的限制性访问. 你可以声明成员为private,不允许外部类访问. 最后,PHP允许一个子类从它的父类中重载成员.

PHP5的对象模型把对象看成与任何其它数据类型不同,通过引用来传递. PHP不要求你通过引用(reference)显性传递和返回对象. 在本章的最后将会详细阐述基于引用的对象模型. 它是PHP5中最重要的新特性.

有了更直接的对象模型,就拥有了附加的优势: 效率提高, 占用内存少,并且具有更大的灵活性.

在PHP的前几个版本中,脚本默认复制对象.现在PHP5只移动句柄,需要更少的时间. 脚本执行效率的提升是由于避免了不必要的复制. 在对象体系带来复杂性的同时,也带来了执行效率上的收益. 同时,减少复制意味着占用更少的内存,可以留出更多内存给其它操作,这也使效率提高.

Zand引擎2具有更大的灵活性. 一个令人高兴的发展是允许析构–在对象销毁之前执行一个类方法. 这对于利用内存也很有好处,让PHP清楚地知道什么时候没有对象的引用,把空出的内存分配到其它用途.

==========================================================
补充:
PHP5的内存管理
对象传递
PHP5 使用了Zend 引擎II ,对象被储存于独立的结构Object Store 中,而不像其它一般变量那样储存于Zval 中( 在PHP4 中对象和一般变量一样存储于Zval) 。在Zval 中仅存储对象的指针而不是内容(value) 。当我们复制一个对象或者将一个对象当作参数传递给一个函数时,我们不需要复制数据。 仅仅保持相同的对象指针并由另一个zval 通知现在这个特定的对象指向的Object Store 。由于对象本身位于Object Store, 我们对它所作的任何改变将影响到所有持有该对象指针的zval 结构—- 表现在程序中就是目标对象的任何改变都会影响到源对象。. 这使PHP 对象看起来就像总是通过引用(reference) 来传递,因此PHP 中对象默认为通过”引用”传递,你不再需要像在PHP4 中那样使用& 来声明。
垃圾回收机制
某些语言,最典型的如C,需要你显式地要求分配内存当你创建数据结构。一旦你分配到内存,就可以在变量中存储信息。同时你也需要在结束使用变量时释放内存,这使机器可以空出内存给其它变量,避免耗光内存。
PHP可以自动进行内存管理,清除不再需要的对象。PHP使用了引用计数(reference counting)这种单纯的垃圾回收(garbage collection)机制。每个对象都内含一个引用计数器,每个reference连接到对象,计数器加1。当reference离开生存空间或被设为NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将不再需要使用这个对象,释放其所占的内存空间。
例如:

复制内容到剪贴板

PHP代码:


<?php 

class Person{ } 

function sendEmailTo(){ } 

$haohappy = new Person( ); 

// 建立一个新对象: 引用计数Reference count = 1 

$haohappy2 $haohappy

// 通过引用复制: Reference count = 2 

unset($haohappy); 

// 删除一个引用:Reference count = 1 

sendEmailTo($haohappy2); 

// 通过引用传递对象:

// 在函数执行期间:

// Reference count = 2 

// 执行结束后: 

// Reference count = 1 

unset($haohappy2); 

// 删除引用: Reference count = 0 自动释放内存空间

?>

第一节 面向对象编程 Posted by admin on 8月 7th, 2008

面向对象编程被设计来为大型软件项目提供解决方案,尤其是多人合作的项目. 当源代码增长到一万行甚至更多的时候,每一个更动都可能导致不希望的副作用. 这种情况发生于模块间结成秘密联盟的时候,就像第一次世界大战前的欧洲.

//haohappy注:喻指模块间的关联度过高,相互依赖性太强.更动一个模块导致其它模块也必须跟着更动.

想像一下,如果有一个用来处理登录的模块允许一个信用卡处理模块来分享它的数据库连接. 当然出发点是好的,节省了进行另一个数据库连接的支出.然而有时,登录处理模块改变了其中一个变量的名字,就可能割断了两者间的协议.导致信用卡模块的处理出错,进而导致处理发票的模块出错. 很快地,体系中所有无关的模块都可能由此出错.

因此,我觉得有点戏剧性地,绝大多数程序员都对耦合和封装心存感激. 耦合是两个模块间依赖程度的量度. 耦合越少越好.我们希望能够从已有的项目中抽走一个模块并在另一个新项目中使用.

我们也希望在某个模块内部大规模的更动而不用担心对其他模块的影响. 封装的原则可以提供这个解决方案.模块被看待成相对独立,并且模块间的数据通信通过接口来进行. 模块不通过彼此的变量名来窥探另一个模块,它们通过函数来礼貌地发送请求.

封装是你可以在任何编程语言中使用的一个原则. 在PHP和许多面向过程的语言中,可以偷懒是很有诱惑的.没有什么可以阻止你通过模块来构建一个假想的WEB. 面向对象编程是使程序员不会违背封装原则的一种方法.

在面向对象编程中,模块被组织成一个个对象. 这些对象拥有方法和属性. 从抽象的角度来看,方法是一个对象的所做的动作,而属性是对象的特性.从编程角度来看,方法就是函数而属性是变量. 在一个理想化的面向对象体系中,每个部份都是一个对象. 体系由对象及对象间通过方法来形成的联系构成.

一个类定义了对象的属性. 如果你在烘烤一组甜饼对象,那么类将会是甜饼机. 类的属性和方法是被调用的成员. 人们可以通过说出数据成员或者方法成员来表达.

每种语言提供了不同的途径来访问对象. PHP从C++中借用概念,提供一个数据类型用来在一个标识符下包含函数和变量。最初设计PHP的时候,甚至PHP3被开发出时,PHP并不打算提供开发超过10万行代码的大型项目的能力。随着PHP和Zend引擎的发展,开发大型项目变得有可能,但无论你的项目规模多大,用类来书写你的脚本将可以让代码实现重用。这是一个好主意,特别当你愿意与别人分享你的代码的时候。

有关对象的想法是计算机科学上最令人兴奋的概念之一。开始很难掌握它,但我可以保证,一旦你掌握了它,用它的思维来思考将会非常自然。

框架–敏捷开发的利器 Posted by admin on 8月 4th, 2008

最近一段时间,敏捷开发在中国被炒的很火,各个公司的开发团队都在向敏捷开发上靠拢。何谓敏捷开发呢?敏捷开发(agile development)是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。简言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。任何一个大型项目的开发都不可能是一两个人就可以完成的,必然是由一个团队来共同开发,这就涉及到效率和效果的问题。团队的敏捷性意味着团队能够快速和敏捷地对内部问题、外部威胁和不断变化的客户需求作出反应。

这几年MVC设计思想在Web开发中已经得到了充分的运用,PHP中各种框架的普及和应用使得MVC设计达到鼎盛,一时间MVC似乎成了判断是非好坏的标准。不少PHP实现的站点采用Framework框架生成静态HTML以加快页面响应速度。随着PHP5的普及,标志着PHP正式进入企业级市场。要进军企业级市场,一个必须要解决的问题是,使用一种什么样的工程方法来使大量的已经习惯于独自编写代码PHP程序员协作起来,并保持较高的工作效率。作为PHP程序员,我们也要利用这个机会,把自己从一个单纯会编码的coder提升为一个了解软件工程,能和团队有效沟通和协作的开发者。而PHP最好的选择就是敏捷开发:把人当成软件开发的核心;维持设计的简单性;用测试驱动开发;用重构保持架构的健壮;用面向对象的设计原则和设计模式来指导设计,使软件保持灵活,能适应需求的变动。有了敏捷开发作为指导,我们就可以使用PHP快速、高效、低成本的完成强大、稳定、能适应需求变化的应用。——这个就叫做如虎添翼。这不是空想,在一些开发者的推动下,已经逐步成为一个正在实现中的事实。PEAR中,已经为PHP5的开发者准备好了一个用于单元测试的包:PHPUNIT2;越来越多的PHP开发者开始在自己的工作中或多或少的加入敏捷开发的要素;而支持重构PHPIDE相信不久就会出现。如果成功的话,这个计划将会有效的提高PHP开发社区的水平,帮助PHP程序员们写出更好更强的程序,从而有力的推进PHP在企业级市场的步伐。

敏捷不是一个过程,是一类过程的统称,它们有一个共性,就是符合敏捷价值观,遵循敏捷的原则。最后我认为作为一个PHP程序员,是需要了解敏捷开发的——既然你选择了PHP,那么,你应该喜欢敏捷开发。

敏捷开发 Posted by admin on 8月 4th, 2008

敏捷开发agile development)是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。简言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。

      敏捷开发是全新理论吗?答案莫衷一是。细心的人们可以发现,敏捷开发其实借鉴了大量软件工程中的方法。迭代与增量开发,这两种在任何一本软件工程教材中都会被提到的方法,在敏捷开发模式中扮演了很重要的角色。再向前追溯,我们还也可见到瀑布式与快速原型法的影子,也许还有更多。

      改善,而非创新。敏捷开发可理解为在原有软件开发方法基础上的整合——取其精华,去其糟粕。因此敏捷开发继承了不少原有方法的优势。“在敏捷软件开发的过程中,我们每两周都会得到一个可以工作的软件,”Fowler介绍,“这种非常短的循环,使终端客户可以及时、快速地看到他们花钱构建的软件是一个什么样的结果。”

      也许是因为时间关系,Fowler只说出了这些优势中的一部分。允许开发过程中的需求变化、通过早期迭代可以较早发现风险、使代码重用变得可行、减少项目返工……借鉴了众多先进方法和丰富经验,拥有的众多优势使得敏捷开发看来已经成为解决软件危机的标准答案。

      问题与思考
      然而,我们不得不面对的现实却是,模式与方法的优化并不意味着问题的终结。作为一种开发模式,敏捷开发同样需要面对众多挑战。

      大项目的拆分意味着更多子项目的出现,协调这些同步或异步推进的子项目,合理的资源调配都将变得更加复杂。另外,在当前项目和项目组普遍“增容”的情况下,遇到的问题同样成倍增长。人的重要性被提到了更高的高度,而缺乏有效协调手段,减少人员流动和项目变更对整个项目造成的影响也将成为一大挑战……新方法带来众多便利的同时,也相应引发了几乎同样多的问题。

 

      敏捷开发(agile development)概念从2004年初开始广为流行。Bailar非常支持这一理论,他采取了”敏捷方式”组建团队:Capital One的”敏捷团队”包括3名业务人员、两名操作人员和5~7名IT人员,其中包括1个业务信息指导(实际上是业务部门和IT部门之间的”翻译者”);另外,还有一个由项目经理和至少80名开发人员组成的团队。这些开发人员都曾被Bailar送去参加过”敏捷开发”的培训,具备相关的技能。
      每个团队都有自己的敏捷指导(Bailar聘用了20个敏捷指导),他的工作是关注流程并提供建议和支持。最初提出的需求被归纳成一个目标、一堆记录详细需要的卡片及一些供参考的原型和模板。在整个项目阶段,团队人员密切合作,开发有规律地停顿–在9周开发过程中停顿3~4次,以评估过程及决定需求变更是否必要。在Capital One,大的IT项目会被拆分成多个子项目,安排给各”敏捷团队”,这种方式在”敏捷开发”中叫”蜂巢式(swarming)”,所有过程由一名项目经理控制。
      为了检验这个系统的效果,Bailar将项目拆分,从旧的”瀑布式”开发转变为”并列式”开发,形成了”敏捷开发”所倡导的精干而灵活的开发团队,并将开发阶段分成30天一个周期,进行”冲刺”–每个冲刺始于一个启动会议,到下个冲刺前结束。

      在Bailar将其与传统的开发方式做了对比后,他感到非常兴奋–”敏捷开发”使开发时间减少了30%~40%,有时甚至接近50%,提高了交付产品的质量。”不过,有些需求不能用敏捷开发来处理。” Bailar承认,”敏捷开发”也有局限性,比如对那些不明确、优先权不清楚的需求或处于”较快、较便宜、较优”的三角架构中却不能排列出三者优先级的需求。此外,他觉得大型项目或有特殊规则的需求的项目,更适宜采用传统的开发方式。尽管描述需求一直是件困难的事,但经过阵痛之后,需求处理流程会让CIO受益匪浅。

      敏捷开发是由一些业界专家针对一些企业现状提出了一些让软件开发团队具有快速工作、响应变化能力的价值观和原则,并于2001初成立了敏捷联盟。他们正在通过亲身实践以及帮助他人实践,揭示更好的软件开发方法。通过这项工作,他们认为:

  • 个体和交互 胜过 过程和工具
  • 可以工作的软件 胜过 面面俱到的文档
  • 客户合作 胜过 合同谈判
  • 响应变化 胜过 遵循计划

并提出了以下遵循的原则:

  • 我们最优先要做的是通过尽早的、持续的交付有价值的软件来使客户满意。
  • 即使到了开发的后期,也欢迎改变需求。敏捷过程利用变化来为客户创造竞争优势。
  • 经常性地交付可以工作的软件,交付的间隔可以从几个星期到几个月,交付的时间间隔越短越好。
  • 在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。
  • 围绕被激励起来的个体来构建项目。给他们提供所需的环境和支持,并且信任他们能够完成工作。
  • 在团队内部,最具有效果并富有效率的传递信息的方法,就是面对面的交谈。
  • 工作的软件是首要的进度度量标准。
  • 敏捷过程提倡可持续的开发速度。责任人、开发者和用户应该能够保持一个长期的、恒定的开发速度。
  • 不断地关注优秀的技能和好的设计会增强敏捷能力。
  • 简单是最根本的。
  • 最好的构架、需求和设计出于自组织团队。
  • 每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。

 

 

 

 

 

顶尖的PHP开源框架 Posted by admin on 8月 3rd, 2008

ror出来之后,PHP也出来了很多有创意的模仿MVC的框架作者分别介绍了

Symfony

CakePHP

Prado

CodeIgniter

Kohana

Zend Framework

Agavi

 

这Kohana和Agavi没听过。其它几个框架都是国外比较流行的PHP框架,Symfony和Cakephp以及官方的Zend Framework都是对ror的创新模仿的作品,用户量都比较多。Prado实际上是国人出品,当年ZEND大奖获得者,是位博士好像,这博士貌似对ASP.NET也很熟悉,所以开发了这款以组件为基础,以及事件驱动的PHP WEB框架,如果会ASP.NET的学起来会发现相当的自然,很多组件命名都类似,里面的SQLMAP也有ASP.NET对应的IBATIS.NET,熟悉IB的JAVAER和ASP.NET开发者都会很亲切

2008年中国软件技术英雄会:上海会英雄 Posted by admin on 8月 2nd, 2008

2008年9月5日CSDN将举办上海站中国软件技术英雄会,现已开始接受网上报名。

自2007年以来,CSDN每年春天均在北京举办中国软件技术英雄会,软件才俊齐聚,展示IT时代技术英雄的力量。此次将大会选址到上海,也必会为华东软件技术界带来一台热闹的好戏。

上海站英雄会内容覆盖互联网、游戏、电子商务等热门领域,将汇聚百名技术社区专家、百名专业级作者、百名技术总监和技术经理,围绕“创业、创新、创富、传知”主题展开互动交流。

按照大会预设议程,UML之父Ivar Jacobson博士将首先登场。届时不但可以领略这位被公认为软件方法论一面“旗帜”的世界级大师的魅力,更可从中体会他对整个软件工业的深刻理解。其后,SAP中国研究院总裁芮祥麟和51.com的CEO庞升东等众多嘉宾,都将陆续呈献各自擅长领域的精彩演讲。

本次上海站英雄会,与会者除了能一睹业界大腕和技术大牛们的风采,历届英雄会受到好评的环节也将再次为大家呈现: 如 “电梯游说”、“CTO论坛”和“创业论坛”等环节。其中,颇具挑战性的“电梯游说”已成为备受期待的大会亮点之一,演说者需在5分钟内用简洁但极具吸引力的语言来描述自己的项目,以期说服对方进行投资或合作。

据记者最新了解,此次上海站的英雄会,将采取别出心裁的现场互动——“叽歪大屏幕”:与会者可以通过手机短信,在投影屏幕上发表自己的看法。

据悉,上海站的英雄会将邀请到巨人网络、Intel、DoNews、51.com、盛大、金蝶、TechExcel、、ShopEx、淘宝和SAP等众多IT企业精英,以及Gobi、Unisun等众多投资公司代表的参与。

此外,整个大会都将在互联网上实时播放。

第三届中国软件技术英雄会官方网站:http://hero2008.sh.csdn.net

历年回顾

2007年4月 北京

2008年3月 北京

 

CSS Template by Rambling Soul | Free WordPress Theme by Theme Lab