来源: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