PHP中用下標符號[]去讀取字符串的邏輯

PHP中 [(下標)] 符號不僅可以應用於數組和對象,還可以應用於字符串,如果不注意很容易出錯。

比如獲取一個網絡接口,正常情況下會返回一個數組結構的json,經過解析之後結果爲:

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


我們獲取到接口數據之後,通過以下語句來判斷content是否有值的話,就會有問題:

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

因爲但是如果服務器異常,可能會返回下面的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的數據,也就是 < 字符。

所以,嚴謹地來說,訪問一個數組下標的時候,要首先判斷一下這個類型是不是數組類型,才能保證萬無一失。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章