`

关于PHP的strtoupper函数

阅读更多

今天看到了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"。

 

到这里就明白了。^_^

3
1
分享到:
评论

相关推荐

    php大小写转换函数(strtolower、strtoupper)用法介绍

    strtoupper() 函数把字符串转换为大写而strtolower函数: 该函数将传入的字符串参数所有的字符都转换成小写,并以小定形式...下面通过本文给大家分享php大小写转换函数(strtolower、strtoupper)用法,需要的朋友参考下吧

    php实现兼容Unicode文字的字符串大小写转换的strtolower()和strtoupper()

    PHP的strtolower()和strtoupper()函数在安装非中文系统的服务器下可能会导致将汉字转换为乱码,请写两个替代的函数实现兼容Unicode文字的字符串大小写转换。

    如何使用PHP中的字符串函数

    前两个函数是输出字符串.字符串中如果有变量名则被替换成其值. 后两个函数类似于C的同名函数. (2)strchr,strlen,strtok,strrchr,strrev,strstr,strtolower, strtoupper,substr,ucfirst 这些是常用的字符串操作...

    php基础教程 php内置函数实例教程

    所以爱微网现在讲解先php内置函数 有大小写转换相关函数 文本html标签处理函数大小写有关函数 复制代码 代码如下: strtolower() strtoupper() ucfirst() ucword() HTML标签相关的字符串格式化函数 复制代码 代码如下...

    PHP闭包函数详解

    匿名函数也叫闭包函数(closures允许创建一个没有指定没成的函数,最经常用作回调函数参数的值。 闭包函数没有函数名称,直接在function()传入变量即可 使用时将定义的变量当作函数来处理 $cl = function($name){ ...

    php运行时动态创建函数的方法

    本文实例讲述了php运行时动态创建函数的方法。分享给大家供大家参考。具体分析如下: 一般的语言函数必须定义了在运行,而php支持在运行时动态创建函数,下面是一个简单的范例,在运动时根据不同的条件创建函数$a &...

    php中关于socket的系列函数总结

    本文列举了所有关于PHP语言中使用socket相关服务的一些函数。注意使用如下函数之前,你需要确保你的socket已打开,如果你没有打开,请编辑你的php.ini文件,去掉下面这行前面的注释(分号): 复制代码 代码如下: ...

    php的dl函数用法实例

    本文实例讲述了php的dl函数用法。分享给大家供大家参考。具体如下: PHP的dl函数官网说明如下: ... if (strtoupper(substr(PHP_OS, 0, 3)) === ‘WIN’) {  dl(‘php_sqlite.dll’);  } else {  

    使PHP自定义函数返回多个值

    PHP自定义函数只允许用return语句返回一个值,当return执行以后,整个函数的运行就会终止。有时候我们要求函数返回多个值时,用return是不可以把值一个接一个地输出的。但不可忽视的一点是,return语句可以返回任何...

    php定义一个参数带有默认值的函数实例分析

    本文实例分析了php定义一个参数带有默认值的函数用法。分享给大家供大家参考。具体分析如下: php的函数参数可以指定默认值,指定默认值后,调用时如果不给该参数赋值,则该参数就使用默认值 &lt;?php function ...

    php 常用的系统函数

    strtoupper:所有的字符都大写 strrev:字符串反转(只能反转英文:英文存储只有一个字节),按照字节进行反转 strpos:从字符串中找对应字符出现的位置(数字下标),从最左边开始找 strrpos:与strpos一样,只是从...

    Thinkphp模板中使用自定义函数的方法

    注意:自定义函数要放在项目应用目录/common/common.php中。 这里是关键。 模板变量的函数调用格式:{$varname|function1|function2=arg1,arg2,### } 说明: { 和 $ 符号之间不能有空格,后面参数的空格就没有问题...

    php2go:使用Golang来实现PHP的常见内置函数

    使用Golang来实现PHP的通用内置函数。 已经实现了约140多种功能。 安装 go get github.com/syyongx/php2go 要求 达到1.10或更高。 PHP函数 日期/时间功能 time() strtotime() date () checkdate () sleep () usleep...

    PHP lcfirst()函数定义与用法

    PHP lcfirst() 函数 实例 把 “Hello” 的首字符转换为小写。: &lt;?php echo lcfirst(Hello world!); ?&gt; 定义和用法 lcfirst()函数把字符串中的首字符转换为小写。 相关函数: ucfirst() – 把字符串中的首...

    php验证身份证号码正确性的函数

    身份证验证最简单的就是判断长度了,当然这种非常简单破了如果要更规则一点我们需要对身份证号码进行... $id = strtoupper($id); $regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/"; $arr_split = array(); if(!preg_matc

    PHP字符串和十六进制如何实现互相转换

    如果在TP下使用可以将下面函数放到common.php中 一,加密函数 &lt;?php /** *字符串转十六进制函数 *@pream string $str='abc'; */ function strToHex($str) { $hex = ; for ($i = 0;$i &lt; strlen($str);$i+...

    php ucwords() 函数将字符串中每个单词的首字符转换为大写(实现代码)

    php ucwords() 函数将字符串中每个单词的首字符转换为大写, 本文章向码农介绍php ucwords() 函数的基本使用方法和实例,感兴趣的码农可以参考一下。 定义和用法 ucwords() 函数把字符串中每个单词的首字符转换为...

    php将字符串全部转换成大写或者小写的方法

    主要介绍了php将字符串全部转换成大写或者小写的方法,涉及php中strtolower与strtoupper等函数的使用技巧,需要的朋友可以参考下

Global site tag (gtag.js) - Google Analytics