2015年7月2日 星期四

PHPNG(PHP 7) + xhProf 實作

php 編譯

# 安裝 git
sudo yum install git -y

# 建立暫存目錄, 抓取 phpng
mkdir ~/tmp
cd ~/tmp
git clone https://git.php.net/repository/php-src.git

# 安裝相依套件 gcc,bison,libxml2-devel,openssl-devel,bzip2-devel,curl-devel,libpng-devel,libjpeg-devel,libXpm-devel,freetype-devel,gmp-devel,mysql-devel,aspell-devel,recode-devel,t1lib-devel,unixODBC-devel
sudo yum install autoconf gcc bison libxml2-devel openssl-devel bzip2-devel curl-devel libpng-devel libjpeg-devel libXpm-devel freetype-devel gmp-devel epel-release libmcrypt-devel mysql-devel aspell-devel recode-devel t1lib-devel unixODBC-devel -y

# 進行編譯
./buildconf
./configure \
    --prefix=$HOME/tmp/usr \
    --with-config-file-path=$HOME/tmp/usr/etc \
    --enable-mbstring \
    --enable-zip \
    --enable-bcmath \
    --enable-pcntl \
    --enable-ftp \
    --enable-exif \
    --enable-calendar \
    --enable-sysvmsg \
    --enable-sysvsem \
    --enable-sysvshm \
    --enable-wddx \
    --with-curl \
    --with-mcrypt \
    --with-iconv \
    --with-gmp \
    --with-pspell \
    --with-gd \
    --with-jpeg-dir=/usr \
    --with-png-dir=/usr \
    --with-zlib-dir=/usr \
    --with-xpm-dir=/usr \
    --with-freetype-dir=/usr \
    --with-t1lib=/usr \
    --enable-gd-native-ttf \
    --enable-gd-jis-conv \
    --with-openssl \
    --with-mysql=/usr \
    --with-pdo-mysql=/usr \
    --with-gettext=/usr \
    --with-zlib=/usr \
    --with-bz2=/usr \
    --with-recode=/usr \
    --with-mysqli=/usr/bin/mysql_config

# 安裝(上面編譯會出現 t1lib 跟 mysql 的 warning, 已有回報bug, 目前無解)
make
sudo make install

# 設定 php.ini
vi $HOME/tmp/usr/etc/php.ini

# php.ini 內容
max_execution_time=600
memory_limit=128M
error_reporting=0
display_errors=0
log_errors=0
user_ini.filename=
realpath_cache_size=2M
cgi.check_shebang_line=0

zend_extension=opcache.so
opcache.enable_cli=1
opcache.save_comments=0
opcache.fast_shutdown=1
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.use_cwd=1
opcache.max_accelerated_files=100000
opcache.max_wasted_percentage=5
opcache.memory_consumption=128
opcache.consistency_checks=0

# 建立軟連結
ln -s /root/tmp/usr/bin/php /usr/bin/php
ln -s /root/tmp/usr/bin/phpize /usr/bin/phpize

# 安裝 re2c
rpm -Uvh http://mirrors.karan.org/epel7/Packages/re2c/20131231011915/0.13.5-1.el6.x86_64/re2c-0.13.5-1.el7.x86_64.rpm

# 安裝 xhprof
git clone https://github.com/Yaoguais/phpng-xhprof.git /root/tmp/php-src/ext/xhprof
cd /root/tmp/php-src/ext/xhprof
phpize
./configure --with-php-config=/root/tmp/usr/bin/php-config
make && make install

# 設定 extension
[xhprof]
extension = xhprof.so
xhprof.output_dir = /tmp/xhprof 


參考連結
phpng(php7): https://wiki.php.net/phpng
xhprof(phpng版): https://github.com/Yaoguais/phpng-xhprof

2015年6月3日 星期三

PHP extension 開發

系統

  • CentOS 7
  • PHP 5.4.16

下載 PHP原始檔

可至 http://php.net/downloads.php 下載最新版本, 我是使用 5.4.41 版
http://windows.php.net/downloads/releases/php-5.4.41-src.zip  將檔案解壓縮, 上傳到 CentOS 的 /root/php-5.4.41

安裝套件

因為我的 CentOS 選擇最小安裝, 所以在編譯 extension 之前, 需要安裝以下的套件
sudo yum install httpd php php-devel gcc

修改權限

沒修改權限, 會出現 permission denied, 可能是因為我用 windows 下載檔案的關係吧?
chmod 744 /root/php-5.4.41/ext/ext_skel

建立skel檔

vi /root/php-5.4.41/ext/lucars.skel
內容如下
string lucars(string str)

建立extension所需要的檔案

/root/php-5.4.41/ext/ext_skel --extname=lucars --proto=lucars.skel
執行後會在 /root/php-5.4.41/ext 底下建立一個叫做 lucars 的目錄, 裡面包含:
  • config.m4
  • config.w32
  • lucars.c
  • php_lucars.c

編輯 php_lucars.h

vi /root/php-5.4.41/ext/lucars/php_lucars.h
可能是因為 --proto 的關係, 預設會幫忙建立一個 lucars() 的 function.
為了額外宣告另外一個function lucars2(), 所以修改 php_lucars.h, 加上底下這行
PHP_FUNCTION(lucars2);

編輯 lucars.c

vi /root/php-5.4.41/ext/lucars/lucars.c 改寫 PHP_FUNCTION(lucars)
PHP_FUNCTION(lucars)
{
char *str = NULL;
int argc = ZEND_NUM_ARGS();
int str_len;
char *result;
if (zend_parse_parameters(argc TSRMLS_CC, "s", &str, &str_len) == FAILURE)
return;
str_len = spprintf(&result,0,"Hello \"%.78s\"",str);
RETURN_STRINGL(result,str_len,0);
並新增 PHP_FUNCTION(lucars2)
PHP_FUNCTION(lucars2)
{
char *str = NULL;
int argc = ZEND_NUM_ARGS();
int str_len;
char *result;
if (zend_parse_parameters(argc TSRMLS_CC, "s", &str, &str_len) == FAILURE)
                return;
str_len = spprintf(&result, 0,"<a href=\"%.78s\">Link</a>",str);
RETURN_STRINGL(result, str_len,0);
}

修改 config.m4

有人說 PHP_ARG_WITH 跟 PHP_ARG_ENABLE 選一個把註解拿掉就好, 我最後是把 PHP_ARG_ENABLE 的註解(dnl)拿掉, 在 16 ~18 行
PHP_ARG_ENABLE(lucars, whether to enable lucars support,
Make sure that the comment is aligned:
[  --enable-lucars           Enable lucars support])

 進行編譯

使用 phpize 進行編譯, 參考  php-config 的設定(位置請依照主機的設定)
/usr/bin/phpize ./configure --with-php-config=/usr/bin/php-config 進行編譯, 測試, 安裝
make
make test
make install clean

啟用 extension

編譯好的 lucars.so 檔放在 /usr/lib64/php/modules, 修改 php.ini
vi /etc/php.ini 加入 lucars.so
extension=/usr/lib64/php/modules/lucars.so 結束編輯之後, 重啟 Apache
systemctl restart httpd  就可以直接使用 lucars() 跟 lucars2() 這兩個 function 了