zendapi

PHP7源码之array_unique函数分析

依然范特西╮ 提交于 2021-01-13 14:59:06
以下源码基于 PHP 7.3.8 array array_unique ( array $array [, int $sort_flags = SORT_STRING ] ) (PHP 4 >= 4.0.1, PHP 5, PHP 7) array_unique — 移除数组中重复的值 参数说明: array:输入的数组。 sort_flag:(可选)排序类型标记,用于修改排序行为,主要有以下值: SORT_REGULAR - 按照通常方法比较(不修改类型) SORT_NUMERIC - 按照数字形式比较 SORT_STRING - 按照字符串形式比较 SORT_LOCALE_STRING - 根据当前的本地化设置,按照字符串比较。 array_unique 函数的源代码在 /ext/standard/array.c 文件中。由于 PHP_FUNCTION(array_unique){ // code... } 篇幅过长,完整代码不在这里贴出来了,可以参见 GitHub 贴出的源代码。 定义变量 zval *array; uint32_t idx; Bucket *p; struct bucketindex *arTmp, *cmpdata, *lastkept; unsigned int i; zend_long sort_type = PHP_SORT_STRING; //

PHP7源码之array_unique函数分析

血红的双手。 提交于 2021-01-13 11:00:26
以下源码基于 PHP 7.3.8 array array_unique ( array array[,intarray[,intsort_flags = SORT_STRING ] ) (PHP 4 >= 4.0.1, PHP 5, PHP 7) array_unique — 移除数组中重复的值 参数说明: array:输入的数组。 sort_flag:(可选)排序类型标记,用于修改排序行为,主要有以下值: SORT_REGULAR - 按照通常方法比较(不修改类型) SORT_NUMERIC - 按照数字形式比较 SORT_STRING - 按照字符串形式比较 SORT_LOCALE_STRING - 根据当前的本地化设置,按照字符串比较。 array_unique 函数的源代码在 /ext/standard/array.c 文件中。由于 PHP_FUNCTION(array_unique){ // code... } 篇幅过长,完整代码不在这里贴出来了,可以参见 GitHub 贴出的源代码。 定义变量 zval *array; uint32_t idx; Bucket *p; struct bucketindex *arTmp, *cmpdata, *lastkept; unsigned int i; zend_long sort_type = PHP_SORT_STRING;

PHP系列之钩子

て烟熏妆下的殇ゞ 提交于 2020-10-02 12:53:48
PHP 提供的钩子 PHP 和 Zend Engine 为扩展提供了许多不同的钩子,这些扩展允许扩展开发人员以 PHP userland 无法提供的方式控制 PHP 运行时。 本章将展示各种钩子和从扩展钩子到它们的常见用例。 钩子到 PHP 功能的一般模式是 PHP 核心提供的扩展覆盖函数指针。然后扩展函数通常执行自己的工作并调用原始 PHP 核心函数。使用此模式,不同的扩展可以覆盖同一个钩子而不会导致冲突。 挂钩到函数的执行 userland和内部函数的执行由Zend引擎中的两个函数处理,您可以用自己的实现替换这两个函数。覆盖此钩子的扩展的主要用例是通用函数级评测、调试和面向方面的编程。 钩子在 Zend/zend_execute.h 中定义: ZEND_API extern void (*zend_execute_ex)(zend_execute_data *execute_data);ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value); 如果要覆盖这些函数指针,则必须在 Minit 中执行此操作,因为 Zend Engine 中的其他决策是根据指针是否被覆盖这一事实提前做出的。 覆盖的通常模式是这样的: static void (

[php-src] Php扩展开发的琐碎注意点、细节

元气小坏坏 提交于 2020-08-07 21:07:35
内容均以php-5.6.14为例. 函数中接收的字符串参数长度不包含结尾的0,在 zend_update_property 中,长度的参数是 int len,一般都使用 ZEND_STRL(NAME)自动填充字符串和长度,它的长度实现是 sizeof(NAME) - 1,它也不需要结尾的0; #undef MIN #undef MAX #define MAX(a, b) (((a)>(b))?(a):(b)) #define MIN(a, b) (((a)<(b))?(a):(b)) #define ZEND_STRL(str) (str), (sizeof(str)-1) #define ZEND_STRS(str) (str), (sizeof(str)) #define ZEND_NORMALIZE_BOOL(n) \ ((n) ? (((n)> 0 ) ? 1 : - 1 ) : 0 ) #define ZEND_TRUTH(x) ((x) ? 1 : 0) #define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b)) 而在 zend_hash_exists, zend_hash_find, add_assoc_stringl_ex 这些 zend_hash_*,add_assoc_* 系列函数的参数 uint key

[php-src] Php内核的有趣高频宏

可紊 提交于 2020-08-07 18:58:52
内容均以php-5.6.14为例. 1. EXPECTED 和 UNEXPECTED 宏,用在判断条件的时候。 ./Zend/zend.h:390 #if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) # define EXPECTED(condition) __builtin_expect(condition, 1 ) # define UNEXPECTED(condition) __builtin_expect(condition, 0 ) #else # define EXPECTED(condition) (condition) # define UNEXPECTED(condition) (condition) #endif 上面 __buildtin_expect 是针对 gcc 的优化,第一参数是判断条件,第二参数表示成立可能性大小,1 大,0 小. 例子,可以这样用: char *p = ( char *) malloc ( 1024 ); if (UNEXPECTED(p == NULL)) {    return p; } (p == NULL) 的可能性较小,第二参数传 0 的话,使用 UNEXPECTED。 2.

【PHP源码】PHP 函数调用

落花浮王杯 提交于 2020-04-08 21:48:47
想法 我以前对于 C 语言的印象是有很强的确定性,而 PHP 在执行的时候会被翻译为 C 语言执行,所以一直很好奇 PHP 怎么调用底层函数。 换句话说就是已知函数名字的情况下如何调用 C 语言中对应名字的函数? 解决这个问题前,首先根据过往的经验做出假设,然后再去验证。 之前在写《用 C 语言实现面向对象》的时候,就意识到使用 void 指针实现很多功能,包括指向任意的函数。接着在写《PHP 数组底层实现》的时候,了解了 HashTable 的实现,即在 C 语言层面通过字符串 key 找到任意类型值。 现在把两者结合起来,是否就能解决以上问题了?比如说把函数名作为 HashTable 的 key,函数指针作为 HashTable 的 value,这样就可以通过函数名获取函数指针来调用函数了。 接下来通过查看 PHP 的源码来看这个假设与真实情况有多少差距。 总体分为三个步骤: 从 PHP 层进入 C 语言层 找到字符串函数名与函数的关系 函数的调用 注:这篇博客的源码对应的版本是 PHP 7.4.4 。 https://github.com/php/php-src/tree/php-7.4.4 从 PHP 层进入 C 语言层 首先要找到 C 语言层调用函数的地方。怎么找? 经常使用 PHP 的同学看到前面的问题描述很容易联想到 PHP