Tag: php

  • Elements of same name in Zend_Form

    It is a rigid rule that Zend_Form can not have elements of same names. If I add a second element with the same name, the first one will be overwritten.

    When I started to use Zend_Form, I thought this rule makes life difficult. For example, if the form have “Next” and “Previous” buttons, I must give them different names. How can I tell which button is clicked? I must go through all names. I thought if these buttons could have same name but different value, it was easier to tell which button was clicked.

    It was before long I started to enjoy this rigid rule. Take the above example for example, it is NOT a good practice to judge which button was clicked by its value. Because for an internationalised program, the value may change and that is out of the programmers’ control.

    What if I want to add 5 text fields for people to fill in information like team members’ name? Two solutions. The first one looks stupid but I did not come across the second one at first.

    Solution 1:

    class MyNamespace_MyText extends Zend_Form_Element_Text {
    	protected $_name = "text";
    
    	public function init() {
    		static $sequence = 0;
    		$this->id = $this->_name . '_' . $sequence;
    		$this->_label = "Label " . ($sequence + 1);
    		$this->_name = $this->_name . '[' . $sequence . ']';
    		$sequence ++;
    	}
    }
    

    Solution 2:

    for ($sequence = 0; $sequence < 5; ++$sequence) {
    	$element = Mage::getModel('moduleName/modelName', "$sequence")
    				->setBelongsTo('text'); //my form is inside Magento
    }
    
  • Drupal on php 5.3.0

    今天想安装 drupal,装了N遍终于成功。一开始想装6.14版,安装过程开始时,我按提示把 sites/default 目录设置可写,把 default.settings.php 改名为 settings.php(提示不准确!),同时设置可写,结果在数据库安装页面反复过不去。

    我联想到 Magento,猜想可能是因为 drupal 6.14 与 php 5.3.0 不兼容。

    那再试试 drupal 5.20 吧。数据库安装页面倒过去了,安装能结束,但抛出一大屏错误。试着进入后台,每个页面都抛出错误,有些功能执行不了,比如修改口令。这样怎么行?继续研究。

    我又看到 drupal 6.14 release notes,说 drupal 从 6.14 起 compatible with php 5.3.0 out of box。啊?说得这么斩钉截铁,那我重新再试。

    终于发现有人提到 drupal 6.14,sites/default 目录下不可没有 default.settings.php,也不可没有 settings.php。压缩包里只有 default.settings.php,所以提示说把它改名 settings.php 是误导,正确的做法是,新建一个 settings.php(可以是空文件),或者拷贝 default.settings.php。这下安装通过了,但还是抛出一堆错误,并不比 drupal 5.20 少。

    想了一下,可能是因为我没有给 drupal 6.14 一个全新的数据库,它是覆盖在原 5.20 的数据库上的,看来 6.14 安装过程不能自动升级数据库。于是再来一遍,这样终于成了(少数页面仍有小量错误)。

  • PDT path mapping

    今天折腾了一个晚上,终于明白一个道理:PDT 下,入口文件不能使用 path mapping,服务器上必须有入口文件才能 debug on server。入口文件所调用的文件才能 path map。

  • Known issues with PDT

    我对 PDT 还不熟,碰到很多问题,都分不清究竟是我不会用,还是 PDT 本身的错。其中一个安装在 Fedora 上的 PDT 已经用了有些日子了,配置被我改来改去,所以更加分不清是谁的错。今天狠狠心,全新下载安装了 PDT Galileo SR1 for win32 版。本来想离 Windows 远一些的,无奈,相对来说,我在 Windows 下用 PDT 比 Fedora 下更久一些,出了问题也更容易定位是什么问题。

    几个小时折腾下来,终于有了结论:

    1. PHP for Windows 本来是集成 odbc 支持的,但 PDT 带来的四个 PHP 解释器不知怎么搞的,就是不支持 odbc,我也不知道去哪里 enable odbc,因为 PHP 手册上说 windows odbc 是内置的。要在 PDT 使用 odbc,那就自己安装一个原版的 PHP 吧。
    2. 在 PDT 下安装 PHP 解释器,对话框有让我填一个 php 启动配置文件,通常是 php.ini。但如果原目录下有一个 php.ini,我想做一个专门用于调试的配置文件,取名叫 php-with-zenddebugger.ini,PDT 根本就不理我填入的文件名,直接去找 php.ini,真是浪费感情。
    3. 既然是自己的 PHP 解释器,ZendDebugger.dll 也得用原版的。当时我图省事,直接把 PDT 带来的 ZendDebugger.dll 拷到我的 PHP 解释器的目录下,不能用,后来比较了原版的,文件大小都相差好多,不知道 PDT 给的是什么版。
  • Zend Framework in Magento

    The library of Zend Framework included in Magento under lib folder is not the genuine Zend Framework. Although I don’t know why Magento did that, I do know:

    • If I replace Magento lib/Zend with genuine ZF, Magento throws errors.
    • If I put geninue ZF in php include_path, Magento appends it to its own include_path, and Magento runs into fussy status. I notice email facility stops working. There may be more functionalities affected.
    • I have loads of code extending Zend_Form. I was intended to reuse them in Magento without rewriting. However, Zend_Form depends on Zend_View, which is not handy in Magento.

    As one of caveats I’ve got from Magento, is whenever possible, avoid touching Zend classes directly.

  • SERVER_NAME vs HTTP_HOST

    If server_name is something like “*.mydomain.com”, $server_name is exactly “*.mydomain.com”. If $server_name is passed on to fastcgi_param as SERVER_NAME, in the program, for example, php $_SERVER[‘SERVER_NAME’] will be exactly “*.mydomain.com”. However, _SERVER[“HTTP_HOST”] shows the value most of us would expect, i.e. the host name in the address bar.

    In Nginx, I have set up a mechanism to install some popular scripts once, and use in multiple websites. I do not want people to find these websites are run under one roof. But if I write multiple websites in one line:

    
    server_name domain1.com domain2.com domain3.com;
    
    

    $_SERVER[‘SERVER_NAME’] is always assigned domain1.com no matter the host is domain2.com or domain3.com.

    To avoid that, I have to break three websites into three server block in nginx.

    $_SERVER[‘HTTP_HOST’] is always the host. But I can not control how people write the script. Breaking hosts into separate server blocks is recommended.

  • Speed bottleneck of the web server

    非常典型的多层架构:
    第一层 Nginx
    第二层 php fastcgi
    第三层 memcached
    第四层 MySql

    Apache 有个 mod_php,相当于合并了第一层和第二层,Nginx 没有 module for php,这不是什么问题,分层更利于扩展。第三层的加入完全是为了减轻数据库压力,提高性能。目前第2,3,4层之间的优化差不多到极限了(或者说到我能力的极限了),但第1,2层之间尚有潜力可挖。

    not_in_use.php 和 not_in_use.html 都是一个静态文件,没有数据库操作。但 php 文件必须由 Nginx 经由 php fastcgi (使用 unix socket)产生,html 则由 Nginx 直接访问文件系统,就单因素分析,php fastcgi 是普通文件系统速度的34%,所以要想办法绕开 php fastcgi。以下测试在数据中心主机上直接运行 ApacheBench。

    测试一:
    $ ab -kc 100 -n 500 http://magento/not_in_use.php
    This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Copyright 2006 The Apache Software Foundation, http://www.apache.org/

    Benchmarking magento (be patient)
    Completed 100 requests
    Completed 200 requests
    Completed 300 requests
    Completed 400 requests
    Finished 500 requests

    Server Software: nginx/0.6.36
    Server Hostname: magento
    Server Port: 80

    Document Path: /not_in_use.php
    Document Length: 7686 bytes

    Concurrency Level: 100
    Time taken for tests: 0.336355 seconds
    Complete requests: 500
    Failed requests: 0
    Write errors: 0
    Keep-Alive requests: 0
    Total transferred: 4089329 bytes
    HTML transferred: 4004406 bytes
    Requests per second: 1486.52 [#/sec] (mean)
    Time per request: 67.271 [ms] (mean)
    Time per request: 0.673 [ms] (mean, across all concurrent requests)
    Transfer rate: 11871.39 [Kbytes/sec] received

    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 11 17.8 3 58
    Processing: 13 49 17.9 50 94
    Waiting: 3 45 18.8 46 88
    Total: 25 60 14.2 61 94

    Percentage of the requests served within a certain time (ms)
    50% 61
    66% 70
    75% 72
    80% 74
    90% 79
    95% 80
    98% 84
    99% 86
    100% 94 (longest request)

    =======================================================
    测试二:
    $ ab -kc 100 -n 500 http://magento/not_in_use.html
    This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Copyright 2006 The Apache Software Foundation, http://www.apache.org/

    Benchmarking magento (be patient)
    Completed 100 requests
    Completed 200 requests
    Completed 300 requests
    Completed 400 requests
    Finished 500 requests

    Server Software: nginx/0.6.36
    Server Hostname: magento
    Server Port: 80

    Document Path: /not_in_use.html
    Document Length: 7686 bytes

    Concurrency Level: 100
    Time taken for tests: 0.115725 seconds
    Complete requests: 500
    Failed requests: 0
    Write errors: 0
    Keep-Alive requests: 500
    Total transferred: 3959000 bytes
    HTML transferred: 3843000 bytes
    Requests per second: 4320.59 [#/sec] (mean)
    Time per request: 23.145 [ms] (mean)
    Time per request: 0.231 [ms] (mean, across all concurrent requests)
    Transfer rate: 33406.78 [Kbytes/sec] received

    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 3 7.3 0 22
    Processing: 7 17 4.1 18 23
    Waiting: 7 16 4.0 17 23
    Total: 7 20 9.9 18 41

    Percentage of the requests served within a certain time (ms)
    50% 18
    66% 20
    75% 22
    80% 37
    90% 39
    95% 40
    98% 41
    99% 41
    100% 41 (longest request)

  • php always takes apache as its session owner

    今天用 yum update php 到 5.2.10 版,发现升级了以后 /var/lib/php/session 的 ownship 又成了 root:apache。这有点恼人,难道每次升级我都要手工改一次 chown nginx:nginx /var/lib/php/session? 或是以后用 apache 的身份来跑 nginx? 我觉得都不太好,太多的场合只认 apache as an only http server,搞得 nginx 很孤立 :(

  • Yum update php to 5.2.x on CentOS

    The current php version with CentOS is 5.1.6. Even epel repository’s php is 5.1.6. I am disappointed with epel slow up-to-date, but I found three 3rd party repositories to update php. Installation of these repositories are slightly diffferent.

    • remi repo has php 5.2.9. To install, just run

      rpm -Uvh http://rpms.famillecollet.com/enterprise/5/remi/x86_64/remi-release-5-7.el5.remi.noarch.rpm

    • atomic repo has php 5.2.9. To install, download this script and run it

      wget http://www.atomicorp.com/installers/atomic.sh

    • james’ utterramblings repo has php 5.2.6. To install, import GPG key first

      rpm --import http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

      create a repo file manually with the following content

      [utterramblings]
      name=Jason's Utter Ramblings Repo
      baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
      enabled=1
      gpgcheck=1
      gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

  • 一语惊醒梦中人

    由于某种原因,我删掉了 /usr/bin/php, /etc/php.ini 等文件,我指望 yum reinstall php 能把这些文件重新装回去。但是 yum install / remove / reinstall 交替使用了 n 次,还是没见这些文件。

    于是我又在想,可能 Fedora 把我以前的安装信息保存在某个地方,毕竟直接去删 /usr/bin/php, /etc/php.ini 等文件不是卸载 package 的正当做法,所以再次用 yum 安装时,它不会把这些文件送回来。怎么让 Fedora 认为我是要象第一次安装 php 那样把这些文件都给装上去呢?我想了好久不得要领,只好去 Fedora forum 提问,由于我的提问也没切中要害,一开始得到的回答也不得要领。

    直到突然一个好心人告诉我,/usr/bin/php 是在 php-cli package 里,/etc/php.ini 是在 php-common package 里。一语惊醒梦中人——怎么我总以为这些文件是由一个 php 全包了呢?