来源:http://www.114code.cn/article/99563F9961.html
php扩展实现求一个数组的平方和,php实现如下:
<?php
function array_square_sum($data){
$sum = 0;
foreach($data as $value){
$sum += $value * $value;
}
return $sum;
}
1.用ext_skel生成扩展骨架
cd php-5.5.8/ext/
./ext_skel --extname=array_square_sum
会输出以下内容:
Creating directory array_square_sum
Creating basic files: config.m4 config.w32 .svnignore array_square_sum.c php_array_square_sum.h CREDITS EXPERIMENTAL tests/001.phpt array_square_sum.php [done].
To use your new extension, you will have to execute the following steps:
$ cd ..
$ vi ext/array_square_sum/config.m4
$ ./buildconf
$ ./configure --[with|enable]-array_square_sum
$ make
$ ./php -f ext/array_square_sum/array_square_sum.php
$ vi ext/array_square_sum/array_square_sum.c
$ make
Repeat steps 3-6 until you are satisfied with ext/array_square_sum/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
据需进行
2.配置文件config.m4
这是./configure时能够调用enable-sample选项的最低要求.PHP_ARG_ENABLE的第二个参数将在./configure处理过程中到达这个扩展的配置文件时显示. 第三个参数将在终端用户执行./configure --help时显示为帮助信息
修改如下:
dnl PHP_ARG_WITH(array_square_sum, for array_square_sum support,
dnl Make sure that the comment is aligned:
dnl [ --with-array_square_sum Include array_square_sum support])
去掉dnl
PHP_ARG_WITH(array_square_sum, for array_square_sum support,
Make sure that the comment is aligned:
[ --with-array_square_sum Include array_square_sum support])
3.修改头文件
修改php_array_square_sum.h
PHP_FUNCTION(confirm_array_square_sum_compiled);
改成
PHP_FUNCTION(array_square_sum);
4.源代码
修改 array_square_sum.c
const zend_function_entry array_square_sum_functions[] = {
PHP_FE(confirm_array_square_sum_compiled, NULL) /* For testing, remove later. */
PHP_FE_END /* Must be the last line in array_square_sum_functions[] */
};
改成
const zend_function_entry array_square_sum_functions[] = {
PHP_FE(array_square_sum, NULL) /* For testing, remove later. */
PHP_FE_END /* Must be the last line in array_square_sum_functions[] */
};
5.然后最为关键的一个步骤,重写confirm_array_square_sum
PHP_FUNCTION(confirm_array_square_sum_compiled)
重写为
PHP_FUNCTION(array_square_sum)
{
zval* array_data;
HashTable *ht_data;
int ret;
char* key;
uint index;
zval **pdata;
double sum = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array_data) == FAILURE) {
return;
}
ht_data = Z_ARRVAL_P(array_data);
zend_hash_internal_pointer_reset(ht_data);
while ( HASH_KEY_NON_EXISTANT != (ret = zend_hash_get_current_key(ht_data, &key, &index, 0)) ) {
ret = zend_hash_get_current_data(ht_data, &pdata);
if( Z_TYPE_P(*pdata) == IS_LONG){
sum += Z_LVAL_P(*pdata) * Z_LVAL_P(*pdata);
}else {
RETURN_FALSE;
}
zend_hash_move_forward(ht_data);
}
zend_hash_internal_pointer_end(Z_ARRVAL_P(array_data));
RETVAL_DOUBLE(sum);
}
6.生成configure文件
执行:/usr/local/php/bin/phpize
Configuring for:
PHP Api Version: 20121113
Zend Module Api No: 20121212
Zend Extension Api No: 220121212
可以发现array_square_sum出现可执行脚本configure
7.编译安装
./configure --with-php-config=/usr/local/php/bin/php-config
编译如果成功,终端会有如下提示:
creating libtool
appending configuration tag "CXX" to libtool
configure: creating ./config.status
config.status: creating config.h
config.status: config.h is unchanged
make && make install
8.将so文件加到php配置中
vim /etc/php.ini
添加:
extension=/usr/local/php/lib/php/extensions/debug-non-zts-20121212/array_square_sum.so
9.检查是否有扩展
php -m | grep array_square_sum
已安装完成
10.测试扩展和php执行代码的速度
<?php
#$a = new Redis();
#echo $a;
#$a = array(1,2,3);
#$b = array_square_sum($a);
#print $b;
$arr=array();
$sum = 0;
for($i=1;$i<1000;$i++){
array_push($arr,$i);
}
$timeS = time();
for($j=0;$j<50000;$j++){
$sum = 0;
foreach($arr as $val){
$sum += $val*$val;
}
}
echo $sum;
echo "\n";
$timeE=time();
echo "time:".($timeE-$timeS)."\n";
for($j=0;$j<50000;$j++){
$sum = array_square_sum($arr);
}
$timeL = time();
echo $sum;
echo "\ntime:".($timeL-$timeE)."\n";
?>
输出:
[root@localhost_C ~/test]# php test.php
332833500
time:10
332833500
time:2
扩展比php快5-10倍甚至更多。
转载自:http://www.114code.cn/article/99563F9961.html