PHP中用下标符号[]去读取字符串的逻辑

PHP中 [(下标)] 符号不仅能够应用于数组和对象,还能够应用于字符串,假设不注意非常easy出错。

比方获取一个网络接口,正常情况下会返回一个数组结构的json,经过解析之后结果为:

array(
‘content‘ => ‘This is returned by interface‘
)

我们获取到接口数据之后,通过下面语句来推断content是否有值的话,就会有问题:

if (!empty($result[‘content‘]))
    echo $result[‘content‘];

由于可是假设server异常。可能会返回以下的HTML字符串:

<html>
    <head>
        <title>505</title>
    </head>
    <body>
        Service Internal Error
    </body>
</html>

这样的情况下。经过json_decode解析我们假设使用上面的语句,就会获得一个 < 字符,这是为什么呢?

我们来看一下 PHP5.2.5 中 [] 作用于字符串的逻辑:

.......
        case IS_STRING: {
                zval tmp; 

                if (dim == NULL) {
                    zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
                }    

                if (Z_TYPE_P(dim) != IS_LONG) {
                    switch(Z_TYPE_P(dim)) {
                        /* case IS_LONG: */
                        case IS_STRING:
                        case IS_DOUBLE:
                        case IS_NULL:
                        case IS_BOOL:
                            /* do nothing */
                            break;
                        default:
                            zend_error(E_WARNING, "Illegal offset type");
                            break;
                    }    

                    tmp = *dim;
                    zval_copy_ctor(&tmp);
                    convert_to_long(&tmp);
                    dim = &tmp;
                }
                switch (type) {
                    case BP_VAR_R:
                    case BP_VAR_IS:
                    case BP_VAR_UNSET:
                        /* do nothing... */
                        break;
                    default:
                        SEPARATE_ZVAL_IF_NOT_REF(container_ptr);
                        break;
                }
                if (result) {
                    container = *container_ptr;
                    result->str_offset.str = container;
                    PZVAL_LOCK(container);
                    result->str_offset.offset = Z_LVAL_P(dim);
                    result->var.ptr_ptr = NULL;
                    if (type == BP_VAR_R || type == BP_VAR_IS) {
                        AI_USE_PTR(result->var);
                    }
                }
                return;
            }
            break;
......

上面源代码中:dim 表示下标;

首先,推断是不是[]操作符中没有下标。假设是就报错。

由于没有下标的话,是要新增一个字数组,这对于字符串来说肯定要出错。

然后推断下标是不是数字型的,请注意 1234 和 "1234" ,PHP都会觉得是数字型。假设不是数字类型的。就会将下标转换为数字型。这样的转换规则下,字符串都会被转换为0。

所以,上面那个样例中。訪问下标为 content 的数据时。就会返回下标为0的数据,也就是 < 字符。

所以。严谨地来说,訪问一个数组下标的时候,要首先推断一下这个类型是不是数组类型,才干保证万无一失。

时间: 2024-07-30 05:03:23

PHP中用下标符号[]去读取字符串的逻辑的相关文章

A + B------HDOJ杭电1228(读取字符串练基础)

Problem Description 读入两个小于100的正整数A和B,计算A+B. 需要注意的是:A和B的每一位数字由对应的英文单词给出. Input 测试输入包含若干测试用例,每个测试用例占一行,格式为"A + B =",相邻两字符串有一个空格间隔.当A和B同时为0时输入结束,相应的结果不要输出. Output 对每个测试用例输出1行,即A+B的值. Sample Input one + two = three four + five six = zero seven + eig

关于C中scanf()函数读取字符串的问题

1 #include <stdio.h> 2 3 int main(void) 4 { 5 char s_name[20]; 6 7 scanf("%s", s_name); 8 printf("Hello, %s!\n", s_name); 9 10 return 0; 11 } 对于这段简单的代码,如果输入一个名字如:Stephen,很容易知道,其输出为: Hello, Stephen! 这个很容易理解,但是输入更完整的名字如:Stephen Pra

scanf() & gets() & fgets() 读取字符串的区别

scanf()和gets()读取字符串的区别 主要的差别在于它们如何决定字符串何时结束 scanf()更基于获取单词(get word)而不是获取字符串(get string): gets()会读取所有的字符,直到遇见第一个换行符为止. scanf()使用两种方法决定输入结束. 如果使用%s格式,字符串读到(但不包括)下一个空白字符(比如空格.制表符或换行符) 如果指定了字段宽度,比如%10s,scanf()就会读入10个字符或者直到遇见第一个空白字符,由二者中最先满足的那一个终止输入 注:无论

使用Properties去读取配置文件,并获得具体内容值

有时候,写了一个配置文件,需要知道读出来的内容对不对,我们需要测试一下,看看读出来的跟我们要的是不是一样.这里写了一个工具类,用来读取配置文件里面的内容. 1.新建一个java工程,导入需要的jar包,新建一个配置文件 如下图: 2.配置文件的内容: 1 driver=com.mysql.jdbc.Driver 2 url=jdbc:mysql://localhost:3306/csdn 3 user=root 4 pwd=123456 5 initsize=1 6 maxactive=1 7

scanf与gets读取字符串的区别

对于编程初学者很多人对gets和scanf都没做过深入的了解,本文为大家详细说明gets和scanf的区别 gets 1.函数:gets(字符指针) 2.头文件:stdio.h(c中),c++不需包含此头文件 3.原型:char*gets(char*buffer); 4.功能:从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中.注意:(换行符不作为读取串的内容,读取(接受)的换行符被转换为null值,并由此来结束字符串.) 5.返回

scanf 和 gets 读取字符串

深入了解scanf()/getchar()和gets()等函数 scanf与gets函数读取字符串的区别 今天看到一段话,大致是说gets比scanf()快,有点吃惊,搜了一下,scanf()和gets的区别大致有着几条: 1.scanf() 会忽略行开头的所有空格,并以空格.换行符结束输入: 使用getchar()读取scanf语句执行后,缓冲区留下的换行符, gets读入以任何字符开始的字符串,以换行符结束,但之后会丢弃换行符并以'\0'代替: 2. 在数据大量的情况下,用gets读取快于s

java基础---&gt;文件---&gt;从标准输入读取字符串作为文件名----&gt;解决“文件名乱码”问题

概述:程序中有时会需要从标准输入读取字符串作为文件的名字,其具体实现方法有许多种.我第一次尝试编写这方面的程序时遇到了"乱码问题",后来使用了新的写法解决了乱码问题. /*原码,使用这种方法编写的代码会出现"乱码问题" 乱码原因分析:从标准输入读取的数据先被存放至byte[]中,之后又将byte数组转成String,这个过程中就会出现编码不一致的问题 如标准输入"file1",但是最终fileName=buffer.toString()的结果却是

scanf和gets读取字符串

最关键的是scanf返回值是整数型,while(scanf()!=EOF) 而gets返回的是指针while(gets()!=NULL) 1. scanf 函数是有返回值的,它的返回值可以分成三种情况  1) 正整数,表示正确输入参数的个数.例如执行 scanf("%d %d", &a, &b);       如果用户输入"3 4",可以正确输入,返回2(正确输入了两个变量):      如果用户输入"3,4",可以正确输入a,无

使用jQuery匹配文档中所有的li元素,返回一个jQuery对象,然后通过数组下标的方式读取jQuery集合中第1个DOM元素,此时返回的是DOM对象,然后调用DOM属性innerHTML,读取该元素 包含的文本信息

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head> <meta htt