文档章节

php7.0对于敏感词扩展库的兼容

mickelfeng
 mickelfeng
发布于 2017/07/13 16:32
字数 1419
阅读 42
收藏 0

在PHP7.0以后的版本,因为有些方法被废弃,有些方法的参数变掉了,导致,原有的基于PHP5.3版本的敏感词库编译不能通过,因为项目中需要用到敏感词,这几天恶补了下PHP7.0的源码,把敏感词扩展库自己修改了下,目前验证通过了。现在记录下来。

1、php_trie_filter_dtor

static void php_trie_filter_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC){

  Trie *trie = (Trie *)rsrc->ptr;

  trie_free(trie);

}

改成了

static void php_trie_filter_dtor(zend_resource *rsrc TSRMLS_DC)
{
   Trie *trie = (Trie *)rsrc->ptr;
   trie_free(trie);
}

我们发现该函数的参数类型是 zend_resource 。这是 PHP7 新增的数据结构,在 PHP 5 则是 zend_rsrc_list_entry

2、trie_filter_load

PHP_FUNCTION(trie_filter_load)
{
	Trie *trie;
	char *path;
	int path_len;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) {
		RETURN_NULL();
	}

	trie = trie_new_from_file(path);

	if (!trie) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load %s", path);
		RETURN_NULL();
	}
	ZEND_REGISTER_RESOURCE(return_value, trie, le_trie_filter);
}

改成了

PHP_FUNCTION(trie_filter_load)
{
	Trie *trie;
	char *path;
	int path_len;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) {
		RETURN_NULL();
	}

	trie = trie_new_from_file(path);
	if (!trie) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load %s", path);
		RETURN_NULL();
	}
	RETURN_RES(zend_register_resource(trie, le_trie_filter));
}

在 PHP 7 中删除了原来的 ZEND_REGISTER_RESOURCE 宏,直接使用 zend_register_resource 函数

ZEND_API zend_resource* zend_register_resource(void *rsrc_pointer, int rsrc_type)
参数 解释
rsrc_pointer 资源数据指针
rsrc_type 注册资源类型时获得的资源类型 id

3、trie_search_all

static int trie_search_all(Trie *trie, const AlphaChar *text, zval *data)
{
	TrieState *s;
	const AlphaChar *p;
	const AlphaChar *base;
	zval *word = NULL;
	base = text;

	if (! (s = trie_root(trie))) {
		return -1;
	}

	while (*text) {
		p = text;
		if(! trie_state_is_walkable(s, *p)) {
			trie_state_rewind(s);
			text++;
			continue;
		}
		while(*p && trie_state_is_walkable(s, *p) && ! trie_state_is_leaf(s)) {
			trie_state_walk(s, *p++);
			if (trie_state_is_terminal(s)) {

				MAKE_STD_ZVAL(word);
				array_init_size(word, 3);
				add_next_index_long(word, text - base);
				add_next_index_long(word, p - text);
				add_next_index_zval(data, word);
			}
		}
		trie_state_rewind(s);
		text++;
	}
	trie_state_free(s);
	return 0;
}

改成了

static int trie_search_all(Trie *trie, const AlphaChar *text, zval *data)
{

	TrieState *s;
	const AlphaChar *p;
	const AlphaChar *base;
	zval word;
	base = text;
	if (! (s = trie_root(trie))) {
		return -1;
	}
	while (*text) {
		p = text;
		if(! trie_state_is_walkable(s, *p)) {
			trie_state_rewind(s);
			text++;
			continue;
		}

		while(*p && trie_state_is_walkable(s, *p) && ! trie_state_is_leaf(s)) {
			trie_state_walk(s, *p++);
			if (trie_state_is_terminal(s)) {
				array_init_size(&word, 3);
				add_next_index_long(&word, text - base);
				add_next_index_long(&word, p - text);
				add_next_index_zval(data, &word);
			}
		}

		trie_state_rewind(s);
		text++;
	}
	trie_state_free(s);
	return 0;
}

这里几个函数暂时未搞明白什么意思

4、trie_filter_search

PHP_FUNCTION(trie_filter_search)

{

Trie *trie;

zval *trie_resource;

unsigned char *text;

int text_len;

int offset = -1, i, ret;

TrieData length = 0;

AlphaChar *alpha_text;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &trie_resource, &text, &text_len) == FAILURE) {

RETURN_FALSE;

}

array_init(return_value);

if (text_len < 1 || strlen(text) != text_len) {

php_error_docref(NULL TSRMLS_CC, E_NOTICE, "input is empty");

return;

}

ZEND_FETCH_RESOURCE(trie, Trie *, &trie_resource, -1, PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

alpha_text = emalloc(sizeof(AlphaChar) * text_len + 1);

for (i = 0; i < text_len; i++) {

alpha_text[i] = (AlphaChar) text[i];

}

alpha_text[text_len] = TRIE_CHAR_TERM;

ret = trie_search_one(trie, alpha_text, &offset, &length);

efree(alpha_text);

if (ret == 0) {

return;

} else if (ret == 1) {

add_next_index_long(return_value, offset);

add_next_index_long(return_value, length);

} else {

RETURN_FALSE;

}

}

改成了

PHP_FUNCTION(trie_filter_search)

{

Trie *trie;

zval *trie_resource;

unsigned char *text;

int text_len;

int offset = -1, i, ret;

TrieData length = 0;

AlphaChar *alpha_text;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &trie_resource, &text, &text_len) == FAILURE) {

RETURN_FALSE;

}

array_init(return_value);

if (text_len < 1 || strlen(text) != text_len) {

php_error_docref(NULL TSRMLS_CC, E_NOTICE, "input is empty");

return;

}

trie = (Trie *)zend_fetch_resource(Z_RES_P(trie_resource), PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

alpha_text = emalloc(sizeof(AlphaChar) * (text_len + 1));

for (i = 0; i < text_len; i++) {

alpha_text[i] = (AlphaChar) text[i];

}

alpha_text[text_len] = TRIE_CHAR_TERM;

ret = trie_search_one(trie, alpha_text, &offset, &length);

efree(alpha_text);

if (ret == 0) {

return;

} else if (ret == 1) {

add_next_index_long(return_value, offset);

add_next_index_long(return_value, length);

} else {

RETURN_FALSE;

}

}

使用资源

ZEND_API void *zend_fetch_resource(zend_resource *res, const char *resource_type_name, int resource_type)

在 PHP 7 中删除了原有的 ZEND_FETCH_RESOURCE 宏,直接使用函数 zend_fetch_resource ,而且解析方式也变得简单了很多,想比 PHP 5 要高效很多,后面我们再通过图片分析对比。

参数 含义
res 资源指针
resource_type_name 该类资源的字符串别名
resource_type 该类资源的类型 id

5、Trie_filter_search_all

PHP_FUNCTION(trie_filter_search_all)

{

Trie *trie;

zval *trie_resource;

unsigned char *text;

int text_len;

int i, ret;

AlphaChar *alpha_text;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &trie_resource, &text, &text_len) == FAILURE) {

RETURN_FALSE;

}

array_init(return_value);

if (text_len < 1 || strlen(text) != text_len) {

php_error_docref(NULL TSRMLS_CC, E_NOTICE, "input is empty");

return;

}

ZEND_FETCH_RESOURCE(trie, Trie *, &trie_resource, -1, PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

alpha_text = emalloc(sizeof(AlphaChar) * text_len + 1);

for (i = 0; i < text_len; i++) {

alpha_text[i] = (AlphaChar) text[i];

}

alpha_text[text_len] = TRIE_CHAR_TERM;

ret = trie_search_all(trie, alpha_text, return_value);

efree(alpha_text);

if (ret == 0) {

return;

} else {

RETURN_FALSE;

}

}

改成了

PHP_FUNCTION(trie_filter_search_all)

{

Trie *trie;

zval *trie_resource;

unsigned char *text;

int text_len;

int i, ret;

AlphaChar *alpha_text;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &trie_resource, &text, &text_len) == FAILURE) {

RETURN_FALSE;

}

array_init(return_value);

if (text_len < 1 || strlen(text) != text_len) {

php_error_docref(NULL TSRMLS_CC, E_NOTICE, "input is empty");

return;

}

trie = (Trie *)zend_fetch_resource(Z_RES_P(trie_resource), PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

alpha_text = emalloc(sizeof(AlphaChar) * (text_len + 1));

for (i = 0; i < text_len; i++) {

alpha_text[i] = (AlphaChar) text[i];

}

alpha_text[text_len] = TRIE_CHAR_TERM;

ret = trie_search_all(trie, alpha_text, return_value);

efree(alpha_text);

if (ret == 0) {

return;

} else {

RETURN_FALSE;

}

}

6、Trie_filter_new

PHP_FUNCTION(trie_filter_new)

{

Trie *trie;

AlphaMap *alpha_map;

int ret;

alpha_map = alpha_map_new();

if (! alpha_map) {

RETURN_NULL();

}

if (alpha_map_add_range(alpha_map, 0x00, 0xff) != 0) {

/* treat all strings as byte stream */

alpha_map_free(alpha_map);

RETURN_NULL();

}

trie = trie_new(alpha_map);

alpha_map_free(alpha_map);

if (! trie) {

RETURN_NULL();

}

ZEND_REGISTER_RESOURCE(return_value, trie, le_trie_filter);

}

改成了

PHP_FUNCTION(trie_filter_new)

{

Trie *trie;

AlphaMap *alpha_map;

int ret;

alpha_map = alpha_map_new();

if (! alpha_map) {

RETURN_NULL();

}

if (alpha_map_add_range(alpha_map, 0x00, 0xff) != 0) {

/* treat all strings as byte stream */

alpha_map_free(alpha_map);

RETURN_NULL();

}

trie = trie_new(alpha_map);

alpha_map_free(alpha_map);

if (! trie) {

RETURN_NULL();

}

RETURN_RES(zend_register_resource(trie, le_trie_filter));

}

资源的注册

在 PHP 7 中删除了原来的 ZEND_REGISTER_RESOURCE 宏,直接使用 zend_register_resource 函数

ZEND_API zend_resource* zend_register_resource(void *rsrc_pointer, int rsrc_type)
 
参数 解释
rsrc_pointer 资源数据指针
rsrc_type 注册资源类型时获得的资源类型 id

7、Trie_filter_store

PHP_FUNCTION(trie_filter_store)

{

Trie *trie;

zval *trie_resource;

unsigned char *keyword, *p;

int keyword_len, i;

AlphaChar alpha_key[KEYWORD_MAX_LEN+1];

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &trie_resource, &keyword, &keyword_len) == FAILURE) {

RETURN_FALSE;

}

if (keyword_len > KEYWORD_MAX_LEN || keyword_len < 1) {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "keyword should has [1, %d] bytes", KEYWORD_MAX_LEN);

RETURN_FALSE;

}

ZEND_FETCH_RESOURCE(trie, Trie *, &trie_resource, -1, PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

p = keyword;

i = 0;

while (*p && *p != '\n' && *p != '\r') {

alpha_key[i++] = (AlphaChar)*p;

p++;

}

alpha_key[i] = TRIE_CHAR_TERM;

if (! trie_store(trie, alpha_key, -1)) {

RETURN_FALSE;

}

RETURN_TRUE;

}

改成了

PHP_FUNCTION(trie_filter_store)

{

Trie *trie;

zval *trie_resource;

unsigned char *keyword, *p;

int keyword_len, i;

AlphaChar alpha_key[KEYWORD_MAX_LEN+1];

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &trie_resource,&keyword, &keyword_len) == FAILURE) {

RETURN_FALSE;

}

if (keyword_len > KEYWORD_MAX_LEN || keyword_len < 1) {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "keyword should has [1, %d] bytes", KEYWORD_MAX_LEN);

RETURN_FALSE;

}

trie = (Trie *)zend_fetch_resource(Z_RES_P(trie_resource), PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

p = keyword;

i = 0;

while (*p && *p != '\n' && *p != '\r') {

alpha_key[i++] = (AlphaChar)*p;

p++;

}

alpha_key[i] = TRIE_CHAR_TERM;

if (! trie_store(trie, alpha_key, -1)) {

RETURN_FALSE;

}

RETURN_TRUE;

}

8、Trie_filter_save

PHP_FUNCTION(trie_filter_save)

{

Trie *trie;

zval *trie_resource;

unsigned char *filename;

int filename_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &trie_resource, &filename, &filename_len) == FAILURE) {

RETURN_FALSE;

}

if (filename_len < 1 || strlen(filename) != filename_len) {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "save path required");

RETURN_FALSE;

}

ZEND_FETCH_RESOURCE(trie, Trie *, &trie_resource, -1, PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

if (trie_save(trie, filename)) {

RETURN_FALSE;

}

RETURN_TRUE;

}

改成

PHP_FUNCTION(trie_filter_save)

{

Trie *trie;

zval *trie_resource;

unsigned char *filename;

int filename_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs",&trie_resource, &filename, &filename_len) == FAILURE) {

RETURN_FALSE;

}

if (filename_len < 1 || strlen(filename) != filename_len) {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "save path required");

RETURN_FALSE;

}

trie = (Trie *)zend_fetch_resource(Z_RES_P(trie_resource), PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

if (trie_save(trie, filename)) {

RETURN_FALSE;

}

RETURN_TRUE;

}

9、Trie_filter_free

PHP_FUNCTION(trie_filter_free)

{

Trie *trie;

zval *trie_resource;

int resource_id;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &trie_resource) == FAILURE) {

RETURN_FALSE;

}

ZEND_FETCH_RESOURCE(trie, Trie *, &trie_resource, -1, PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

resource_id = Z_RESVAL_P(trie_resource);

if (zend_list_delete(resource_id) == SUCCESS) {

RETURN_TRUE;

}

RETURN_FALSE;

}

改成

PHP_FUNCTION(trie_filter_free)

{

Trie *trie;

zval *trie_resource;

int resource_id;



if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &trie_resource) == FAILURE) {

RETURN_FALSE;

}

trie = (Trie *)zend_fetch_resource(Z_RES_P(trie_resource), PHP_TRIE_FILTER_RES_NAME, le_trie_filter);

resource_id = Z_RES_P(trie_resource);

if (zend_list_delete(resource_id) == SUCCESS) {

RETURN_TRUE;

}

RETURN_FALSE;

}

 

本文转载自:http://blog.csdn.net/xiaoai5324/article/details/62422779

mickelfeng

mickelfeng

粉丝 237
博文 2784
码字总数 604219
作品 0
成都
高级程序员
私信 提问
ubuntu安装PHP7.0以及memcache,redis等常用扩展

添加第三方源 由于ubuntu各个版本目前都没有官方的PHP7.0的源,所以我们只能自己添加第三方的源 更新源,安装PHP 添加源之后,我们需要更新源。然后正式开始安装PHP7.0 最后安装常用扩展 目前...

fangjinzhen
2016/03/06
1K
0
日请求亿级的QQ会员AMS平台PHP7升级实践

版权声明:本文由PHP7升级项目组原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/74 来源:腾云阁 https://www.qcloud.com/community QQ会员活动运营平台...

偶素浅小浅
2016/11/01
29
0
ECMALL 新增对 PHP 7.0 的支持

经过长达1星期的开发与测试,我们已完成了ECMALL与深度定制版代号为(ECMOS)的PHP更新版本升级。目前已经可以支持PHP7.0。ECMALL可以完美运行在PHP7.0系统上。 本次开发是基于ECMOS(ECMALL深度...

bornlau
2017/04/11
1K
10
PHP 7.0 安装使用与性能监测!

PHP 7.0发布,网上关于新版的介绍很多,介于 7.0 在正式发布之前已经发过若干个 Beta、8个 RC,应该不会出现重大问题。今日我将一台机器升级至 PHP 7.0 并将有关信息记录如下。 本人使用 Ub...

OneAPM蓝海讯通
2015/12/31
98
0
PHP7 LevelDB 扩展--PHP 7.0-LevelDB

LevelDB 是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了。 在这个数量级别下还有着非常高的性能,主要归功于它的良好的设计。特别是LSM算法。php7.0-le...

Will-Pan
2017/06/12
722
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
5
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
6
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
昨天
6
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
7
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部