今天看到了PHP实现的标准扩展函数这一段,第一个挑了string相关的函数来看,毕竟这个是用的最多的。
看到了strtoupper函数的实现。如下:
char *php_strtoupper(char *s, size_t len) { unsigned char *c, *e; c = (unsigned char *)s; e = (unsigned char *)c+len; while (c < e) { *c = toupper(*c); c++; } return s; }
第一感觉就是返回值和传入值是一个东西,而且经过该函数的处理,实参也会被修改,也就是说传入的字符串也会被upper。
但这个和平时使用的感觉不对,立马来试下:
<?php $s = "helloworld"; echo strtoupper($s); echo $s; ?>
运行结果是:
HELLOWORLD
helloworld
和直觉上是一样的,但和上面的C代码中的逻辑不符啊。咋回事呢?
********************************************************
问题出在这里:
其实上述C代码中的参数并不是直接来自于strtoupper($s)中的$s.
PHP内部获取$s之后的处理过程为:
PHP_FUNCTION(strtoupper) { char *arg; int arglen; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arglen) == FAILURE) { return; } arg = estrndup(arg, arglen); php_strtoupper(arg, arglen); RETURN_STRINGL(arg, arglen, 0); }
不难发现,即使通过zend_parse_parameters获取的arg是指向$s字符串的。后面在调用php_strtoupper函数之前还需要:
arg=estrndup(arg,arglen);
那这个函数是干什么的呢?
顺疼莫瓜,找到了这个东西:
#define estrndup(s, length) _estrndup((s), (length) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
和这个东西:
ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { char *p; p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); if (UNEXPECTED(p == NULL)) { return p; } memcpy(p, s, length); p[length] = 0; return p; }
注意哲理的_emalloc函数,这个重新分配了一段内存空间。然后memcpy(p,s,lenth)。
经过这个过程PHP中的$s已经在内部被“偷梁换柱”成这个“p”了。
到这里就不难理解,php_strtoupper函数中的参数其实不是$s,而是这个*p。这个p指向的字符串的每个字符都会被upper。然后在php_strtoupper中直接返回这个p也就正常了。
结合上面的例子,$s始终都是"helloworld",PHP内部创建的p一开是也是"helloworld",然后会变为"HELLOWORLD"。
最后strtoupper($s)这个也就是PHP在内部创建的这个p了。也就是"HELLOWORLD"。
到这里就明白了。^_^
相关推荐
字符串处理在PHP中至关重要,如`strlen()`获取字符串长度,`trim()`去除字符串首尾空白,`str_replace()`替换字符串中的部分文本,`strstr()`查找子串首次出现的位置,`strpos()`检测子串是否存在于字符串中,`...
strtoupper() 函数把字符串转换为大写而strtolower函数: 该函数将传入的字符串参数所有的字符都转换成小写,并以小定形式...下面通过本文给大家分享php大小写转换函数(strtolower、strtoupper)用法,需要的朋友参考下吧
这个章节详细介绍了PHP中用于处理字符串的各种函数,如`strlen()`用于计算字符串长度,`str_replace()`用于替换字符串中的特定字符或子串,`strpos()`用于查找子串在字符串中的位置,`strtolower()`和`strtoupper()`...
if(strtoupper(substr(PHP_OS,0,3)) == 'WIN'){ dl('php_sqlite.dll'); } else { dl('sqlite.so'); } ``` 3. **使用`PHP_SHLIB_SUFFIX`常量**:从PHP 4.3.0开始,可以通过`PHP_SHLIB_SUFFIX`常量来确定库文件...
1. **字符串处理**:PHP提供了如`strlen()`用于获取字符串长度,`strpos()`用于查找子串位置,`str_replace()`用于替换字符串中的特定部分,以及`strtolower()`和`strtoupper()`用于转换字符串大小写等功能。...
Strtoupper 函数用于将字符串转换为大写,例如,Strtoupper("hello world") 将字符串 "hello world" 转换为 "HELLO WORLD"。 9. Strtolower 函数 Strtolower 函数用于将字符串转换为小写,例如,Strtolower("HELLO...
- **`implode()`**、**`explode()`**、**`strlen()`**、**`md5()`**、**`substr()`**、**`strtolower()`**、**`strtoupper()`**、**`strrev()`** 和 **`strpos()`** 等函数提供了丰富的字符串操作功能。 示例: ...
在PHP编程语言中,函数是预定义的代码块,用于执行特定任务,它们极大地提高了代码的重用性和效率。PHP提供了丰富的内置函数库,涵盖了数组处理、数学计算、字符串操作、目录管理、时间日期处理、文件系统交互以及...
PHP的strtolower()和strtoupper()函数在安装非中文系统的服务器下可能会导致将汉字转换为乱码,请写两个替代的函数实现兼容Unicode文字的字符串大小写转换。
3. **字符串处理**:函数如`strlen()`用于获取字符串长度,`str_replace()`进行字符串替换,`explode()`和`implode()`用于字符串拆分与合并,`strpos()`查找子串位置,以及`strtolower()`和`strtoupper()`等用于大小...
PHP函数大全集合了PHP中的各种内置函数,为开发者提供了丰富的工具箱,使得编写代码更加高效和灵活。这份"即用即查PHP函数参考手册"正是为了帮助开发者快速查找和理解这些函数而编写的。 PHP函数是PHP编程的基础,...
在PHP编程语言中,函数是实现特定功能的代码块,可以重复使用,极大地提高了开发效率。这个"php常用函数合集"包含七个PDF文档,旨在为开发者提供PHP的基础及常用的函数参考。以下将对这些常见函数进行详尽的介绍。 ...
1. **字符串函数**:在`php_字符串函数.pdf`中,你将了解到如`strlen()`用于计算字符串长度,`str_replace()`用于替换字符串中的特定部分,`strpos()`查找字符串中特定字符的位置,以及`strtolower()`和`strtoupper...
### PHP常用函数详解 #### 一、PHP数据库函数(基于mysqli) 在PHP中,与数据库交互是非常常见的需求,尤其是在Web开发领域。为了更好地理解和使用这些函数,我们将对以下几个常用的数据库函数进行详细介绍: ###...
在PHP编程中,函数是构建强大且可复用代码的核心元素。PHP提供了丰富的内置函数库,涵盖了许多领域,包括数组处理、数学运算、字符串操作、目录管理、日期和时间处理以及文件I/O等。以下是对这些关键领域的详细阐述...
本文将深入探讨PHP中的字符串函数,帮助你更好地理解和运用这些工具。 首先,PHP提供了丰富的内置函数来操作和处理字符串。例如: 1. `strlen()` 函数用于计算字符串的长度,不包含末尾的空格。例如,`strlen(...
在PHP编程语言中,函数是预定义的代码块,用于执行特定任务。它们极大地提高了代码的可重用性和效率。本篇文章将深入探讨PHP中的常用函数,这些函数在日常开发中非常常见且实用。 1. **字符串处理函数**: - `...
根据提供的信息,我们可以总结并扩展出以下几个关于PHP函数的重要知识点: ### 1. 函数的定义和调用 - **定义**: 在PHP中,函数是一组执行特定任务的语句集合。函数可以由系统内建或者由用户自定义。一个典型的...