PHP 语法字符串函数 strcmp、strlen 使用及实现
PHP 实现 函数 字符串 语法 strlen 使用 strcmp
2023-09-14 08:57:43 时间
说明
这里基于 php7.2.5 进行测试,php7 之后内部结构变化应该不是太大,但与 php5.X 有差别。
函数分类
用户自定义函数
say(); function say() { echo "周杰伦"; }
php hello.php 周杰伦
cli 模式下我们执行这个代码之后就会输出函数调用的结果,简单来说这个过程经历了下面的步骤
我们可以先理解为要经历编译、执行两步。也就是我们每次执行这段代码都要经历这样的一个过程。
内置函数
也就是我们在手册中看到的函数,太多了,这里我们用字符串函数来举例说明。与用户自定义函数不同,内置函数不需要经历编译,直接定义注册就可以。
所以内置函数的效率相对是高一些。
函数如何实现的
strlen
strlen("hello"); // 这个语法不说了,返回字符串长度
// 看一下具体实现 // Zend/zend_builtin_functions.c ZEND_FUNCTION(strlen) // 定义函数 strlen是函数名 { zend_string *s; // 这是参数字符串 ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STR(s) ZEND_PARSE_PARAMETERS_END(); // 主要看这里 给返回值设置的是 s的长度 RETVAL_LONG(ZSTR_LEN(s)); } // 来看下ZSTR_LEN是啥 // zend_string.h // 很巧返回的是zend_value.zend_string.len 记得吗 #define ZSTR_LEN(zstr) (zstr)->len // RETVAL_LONG 函数 给返回值赋值也就是 len 字符串的长度,并把返回值的类型设置为 IS_LONG
小结
可以看到 strlen 其实是直接获取了 zval.zend_value.zend_string.len, 最后一步是把 len 赋值给函数返回值。
这里需要说明的是:
- ZEND_FUNCTION 是函数声明的通用格式,知道就行。
- 函数返回值也是一个变量,函数执行完返回它。
strcmp
strcmp($str1, $str2); //这个函数是比较两个字符串的大小,如果str1>str2则大于0,如果str1<str2则小于0,如果str1=str2则等于0 strcmp("ha", "h");// 1 多一个字符 strcmp("ha","hA");// 32 这个32是咋来的呢,实际上如果字符数量相等则比较第二个字符的ASII值,看下面 echo ord("A"); // 65 echo PHP_EOL; echo ord("a"); // 97
// 来看实现 // 定义函数 ZEND_FUNCTION(strcmp) { // 参数 s1=ha, s2=h zend_string *s1, *s2; // 这里设置参数 ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STR(s1) Z_PARAM_STR(s2) ZEND_PARSE_PARAMETERS_END(); // 这里进行比较, 调用zend_binary_strcmp进行比较 // 参数为s1的值也就是ha, s1的长度也就是2, s2的值h, s2的长度 1 // ZEND_LEN就是返回s2的长度,看上面的内容 RETURN_LONG(zend_binary_strcmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2))); } // 来看zend_binary_strcmp ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */ { // 返回值 int retval; // 如果完全相等就是0, == 在任何语言都适合 if (s1 == s2) { return 0; } // 调用c内置函数memcmp比较 // min(len1, len2) 是获取最短的那个长度 // 如min("ha", "h") 就比较前1个字符 retval = memcmp(s1, s2, MIN(len1, len2)); // 如果=0则再min长度内是相等的,返回值就是哪个长就返回多出来的字符数 if (!retval) { return (int)(len1 - len2); } else { // 如果<>0,则就返回那个值 return retval; } } // 关于memcmp 在c官方手册看到 , 比较两个字符串,s1>s2返回大于0,s1<s2返回小于0, s1=s2返回0 // 参考 // 就是把每个字符都比较一遍 int memcmp(const void *s1, const void *s2, size_t n){ const unsigned char *su1, *su2; for(su1 = s1, su2 = s2; 0 < n; ++su1, ++su2, --n) if(*su1 != *su2) return ((*su1 < *su2) ? -1 : +1); return 0; }
小结
strcmp 的实现是基于 C 内置函数 memcmp 实现的,规则就是 memcmp 的语法。
总结
内置函数不需要经历编译过程,执行速度比自定义函数要快,实现上跟我们写 PHP 代码是一样的,也要定义、调用等步骤。
相关文章
- php-实现微信回复天气情况
- PHP DFA算法实现敏感词过滤包 php-dfa-sensitive
- 【代码笔记】php操作MySQL,实现一列数据求和
- PHP is_array():判断是否为数组
- PHP中实现Redis队列的挑战与实践(php队列redis)
- PHP扩展开发:实现Redis读写数据(php扩展redis)
- Oracle与PHP:实现服务器端程序互通(oracle和php)
- PHP如何连接MSSQL数据库?(php连接mssql)
- PHP实现Redis监控的简便方法(php监控redis)
- 使用PHP连接MySQL数据库实现数据操作(php连接mysql类)
- 在Redis与PHP之间实现高效机制(redisphp机制)
- PHP与MSSQL的结合:实现无缝连接(php调用mssql)
- PHP连接MSSQL:一个新的开发方式(php 联接mssql)
- PHP实现连接MS SQL数据库的实战指南(php 打开mssql)
- PHP图片上传至MySQL:实现快速可靠的数据存储(php图片上传mysql)
- MySQL和PHP中的目录结构说明(mysql中php的目录)
- 基于Redis和PHP技术的投票系统优化(投票 redis php)
- PHP编实现程动态图像的创建代码
- PHP模拟$_PUT实现代码
- 让的PHP代码飞起来的40条小技巧(提升php效率)
- php缩略图实现函数代码
- php入门学习知识点七PHP函数的基本应用
- php实现rc4加密算法代码
- 改写函数实现PHP二维/三维数组转字符串
- PHP小教程之实现链表
- 使用lua实现php的print_r()函数功能
- php实现两表合并成新表并且有序排列的方法
- 使用ob系列函数实现PHP网站页面静态化
- php中用memcached实现页面防刷新功能
- PHP采用自定义函数实现遍历目录下所有文件的方法