说明

这里基于 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 语法字符串函数 strcmp、strlen 使用及实现的更多相关文章

  1. 实现字符串函数,strlen(),strcpy(),strcmp(),strcat()

    实现字符串函数,strlen(),strcpy(),strcmp(),strcat() #include<stdio.h> #include<stdlib.h> int my_ ...

  2. 字符串函数---strcmp()与strncmp()具体解释及实现

    一.strcmp()与strncmp() strcmp():strcmp(s1,s2);            比較两个字符串.        strncmp():strncmp(s1,s2);   ...

  3. 字符串函数---strcmp()与strncmp()详解及实现【转】

    本文转载自:http://blog.csdn.net/lanzhihui_10086/article/details/39829623 一.strcmp()与strncmp() strcmp():st ...

  4. PHP基础语法: echo,var_dump, 常用函数:随机数:拆分字符串:explode()、rand()、日期时间:time()、字符串转化为时间戳:strtotime()可变参数的函数:PHP里数组长度表示方法:count($attr[指数组]);字符串长度:strlen($a)

    PHP语言原理:先把代码显示在源代码中,再通过浏览器解析在网页上 a. 1.substr;  //用于输出字符串中,需要的某一部分 <?PHP $a="learn php"; ...

  5. Linux C 字符串函数 strlen()、strcat()、strncat()、strcmp()、strncmp()、strcpy()、strncpy() 详解

      strlen(返回字符串长度) 表头文件 #include <string.h> 定义函数 size_t strlen(const char *s); 函数说明 strlen()用来计 ...

  6. Strcmp(字符串1,字符串2)函数 Sizeof && strlen() Substr(a,b)

    Strcmp(字符串1,字符串2)函数 { strcmp函数是比较两个字符串的大小,返回比较的结果.一般形式是:  i=strcmp(字符串,字符串); 其中,字符串1.字符串2均可为字符串常量或变量 ...

  7. 字符串函数(strcpy字符串拷,strcmp字符串比较,strstr字符串查找,strDelChar字符串删除字符,strrev字符串反序,memmove拷贝内存块,strlen字符串长度)

    1.strcpy字符串拷贝拷贝pStrSource到pStrDest,并返回pStrDest地址(源和目标位置重叠情况除外) char *strcpy(char *pStrDest, const ch ...

  8. 内存及字符串操作篇strlen strchar strcmp strcoll strcpy strdup strstr strtok strspn strrchr bcmp bcopy bzero index memccpy memset

    bcmp(比较内存内容) 相关函数 bcmp,strcasecmp,strcmp,strcoll,strncmp,strncasecmp 表头文件 #include<string.h> 定 ...

  9. C语言-字符串函数的实现(一)之strlen

    C语言中的字符串函数有如下这些 获取字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数 strncpy strncat strncmp ...

随机推荐

  1. k8s可视化工具kubernetes-dashboard部署——小白教程

    参考资料: kubernetes官方文档 官方GitHub 创建访问用户 解决chrome无法访问dashboard 官方部署方法如下: kubectl apply -f https://raw.gi ...

  2. 16.如何查找所需的maven的依赖

    http://mvnrepository.com/ 1.先打开上面的网址 搜索需要的依赖,点进去 2.选择需要的版本 3.红框中的就是依赖的地址 此外也有其他自动化构建工具所需要的地址

  3. python—time模块

    timetime模块提供各种时间相关的功能,与时间相关的模块有:time,datetime,calendar等. 时间有三种表示方式,一种是时间戳.一种是格式化时间.一种是时间元组.时间戳和格式化时间 ...

  4. SSH免密配置

    1. 在三个节点生成秘钥cd ~/.sshssh-keygen -t rsa 2.合并三个节点的密码cat id_rsa.pub >> authorized_keysssh postgre ...

  5. AI学习笔记:特征工程

    一.概述 Andrew Ng:Coming up with features is difficult, time-consuming, requires expert knowledge. &quo ...

  6. SWUSTOJ 960A题总结,又完成一个讨厌的题,内含链表操作启发

    今天debug了一个nice代码,先码在这里,SWUST OJ960 双向链表的操作问题 1000(ms) 10000(kb) 2994 / 8244 建立一个长度为n的带头结点的双向链表,使得该链表 ...

  7. C语言:static关键字用法

    参考博客:https://blog.csdn.net/guotianqing/article/details/79828100 看个例子: #include <stdio.h> void ...

  8. background-clip 和 background-origin 有什么区别? -[CSS] - [属性]

    这两个属性在W3S上的示例,给人的感觉好像效果是一样的:

  9. spark 独立应用编程之 Java 编程

    文章更新于:2020-04-03 按照惯例,文件附上链接放在文首. 文件名:apache-maven-3.6.3-bin.tar.gz 文件大小:9.1 MB 下载链接:https://www.lan ...

  10. std::string::append函数

    string& append (const string& str); string& append (const string& str, size_t subpos ...