ext_skel生成骨架
./ext_skel --extname=array_median
修改config.m4
解开注释
dnl PHP_ARG_WITH(array_median, for array_median support,
dnl Make sure that the comment is aligned:
dnl [ --with-array_median Include array_median support])
添加函数显示
const zend_function_entry array_median_functions[] = {
PHP_FE(confirm_array_median_compiled, NULL) /* For testing, remove later. */
PHP_FE(array_median, NULL)
PHP_FE_END /* Must be the last line in array_median_functions[] */
};
编写函数
示例
实现一个函数,获取一个数组的中位数
float array_median(array $arr)
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_array_median.h"
#include "zend_hash.h"
#include "ext/standard/php_array.h"
#include "zend_types.h"
#include "Zend/zend_operators.h"
static int php_array_data_compare_numeric(const void *a, const void *b) /* {{{ */
{
Bucket *f;
Bucket *s;
zval *first;
zval *second;
f = (Bucket *) a;
s = (Bucket *) b;
first = &f->val;
second = &s->val;
if (UNEXPECTED(Z_TYPE_P(first) == IS_INDIRECT)) {
first = Z_INDIRECT_P(first);
}
if (UNEXPECTED(Z_TYPE_P(second) == IS_INDIRECT)) {
second = Z_INDIRECT_P(second);
}
return numeric_compare_function(first, second);
}
PHP_FUNCTION(array_median)
{
zval *array;
zval *ret;
zval *ret2;
double median;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
return;
}
// 排序
if (zend_hash_sort(Z_ARRVAL_P(array), php_array_data_compare_numeric, 1) == FAILURE) {
RETURN_FALSE;
}
// 数组大小
int length = zend_hash_num_elements(Z_ARRVAL_P(array));
if(length % 2 == 0) {
ret = zend_hash_index_find(Z_ARRVAL_P(array), (length /2));
ret2 = zend_hash_index_find(Z_ARRVAL_P(array), (length / 2) - 1);
median = (double)(zval_get_long(ret) + zval_get_long(ret2)) / 2;
} else {
ret = zend_hash_index_find(Z_ARRVAL_P(array), (length / 2));
median = (double)zval_get_long(ret);
}
ZVAL_DOUBLE(return_value, median);
}
const zend_function_entry array_median_functions[] = {
PHP_FE(confirm_array_median_compiled, NULL) /* For testing, remove later. */
PHP_FE(array_median, NULL)
PHP_FE_END /* Must be the last line in array_median_functions[] */
};
var_dump(array_median([1, 5, 5, 2]));
// float(3.5)
var_dump(array_median([1, 5, 5]));
// float(5)