從源碼角度看 PHP 字符串類型轉換

        PHP 的類型轉換是比較方便的,可是越是容易使用的東西,底層的實現越是複雜,並且在使用中像我這樣的新手也每每不清楚轉換後的結果究竟是什麼。有時候,對於 Java 這種強類型的語言,使用的時候須要強制進行轉換,這樣多半轉換後的結果是能夠預料的,至少本身是想這麼作的。php

 

經過實例看轉換微信

        寫個關於 PHP 類型轉換的代碼測試一下吧,看看你們是否能知道輸出結果。各類數據類型 都轉換爲 字符串類型試試。測試

 

 1 <?php
 2 
 3 $var = false;
 4 echo '$var:', $var, "\r\n";
 5 
 6 $var = null;
 7 echo '$var:', $var, "\r\n";
 8 
 9 $var = true;
10 echo '$var:', $var, "\r\n";
11 
12 $var = 1;
13 echo '$var:', $var, "\r\n";
14 
15 $var = 1.1;
16 echo '$var:', $var, "\r\n";
17 $var1 = &$var;
18 echo '$var:', $var1, "\r\n";
19 
20 $var1 = 'string111';
21 echo '$var:', $var1, "\r\n";
22 
23 $var = [1, 2, 3];
24 echo '$var:', $var, "\r\n";
25 
26 class Obj
27 {
28     private $field;
29 }
30 
31 $var = new Obj();
32 echo '$var:', $var, "\r\n";

 

        代碼很簡單,你們能夠猜猜輸出結果,而後再和運行結果比對一下,運行結果以下:spa

 

 1 $ php string.php
 2 $var:
 3 $var:
 4 $var:1
 5 $var:1
 6 $var:1.1
 7 $var:1.1
 8 $var:string111
 9 $var:
10 Notice: Array to string conversion in C:\Users\Administrator\Desktop\string.php
11 on line 24
12 
13 Call Stack:
14     0.0010     405568   1. {main}() C:\Users\Administrator\Desktop\string.php:0
15 
16 Array
17 $var:
18 Catchable fatal error: Object of class Obj could not be converted to string in C
19 :\Users\Administrator\Desktop\string.php on line 32
20 
21 Call Stack:
22     0.0010     405568   1. {main}() C:\Users\Administrator\Desktop\string.php:0

 

 

 

 

        不知道是否實際的運行結果和猜想的結果是否一致。
code

 

 

 

PHP 源碼中各種型轉換爲字符串類型的處理blog

 

        對於各類類型之間的賦值,並轉換爲字符串,使用真的是很是的方便。可是,實際的功勞都是 PHP 底層的複雜處理。看一下關於各類類型轉換爲字符串類型的源代碼的處理。ci

 

 1 ZEND_API zend_string* ZEND_FASTCALL _zval_get_string_func(zval *op) /* {{{ */
 2 {
 3 try_again:
 4   switch (Z_TYPE_P(op)) {
 5     case IS_UNDEF:
 6     case IS_NULL:
 7     case IS_FALSE:
 8       return ZSTR_EMPTY_ALLOC();
 9     case IS_TRUE:
10       return ZSTR_CHAR('1');
11     case IS_RESOURCE: {
12       char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
13       int len;
14 
15       len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
16       return zend_string_init(buf, len, 0);
17     }
18     case IS_LONG: {
19       return zend_long_to_str(Z_LVAL_P(op));
20     }
21     case IS_DOUBLE: {
22       return zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
23     }
24     case IS_ARRAY:
25       zend_error(E_NOTICE, "Array to string conversion");
26       return zend_string_init("Array", sizeof("Array")-1, 0);
27     case IS_OBJECT: {
28       zval tmp;
29       if (Z_OBJ_HT_P(op)->cast_object) {
30         if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_STRING) == SUCCESS) {
31           return Z_STR(tmp);
32         }
33       } else if (Z_OBJ_HT_P(op)->get) {
34         zval *z = Z_OBJ_HT_P(op)->get(op, &tmp);
35         if (Z_TYPE_P(z) != IS_OBJECT) {
36           zend_string *str = zval_get_string(z);
37           zval_ptr_dtor(z);
38           return str;
39         }
40         zval_ptr_dtor(z);
41       }
42       zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", ZSTR_VAL(Z_OBJCE_P(op)->name));
43       return ZSTR_EMPTY_ALLOC();
44     }
45     case IS_REFERENCE:
46       op = Z_REFVAL_P(op);
47       goto try_again;
48     case IS_STRING:
49       return zend_string_copy(Z_STR_P(op));
50     EMPTY_SWITCH_DEFAULT_CASE()
51   }
52   return NULL;
53 }
54 /* }}} */

 

        從上面的源碼中能夠看出,對於類型的轉換,PHP 底層的源碼使用了 switch ... case 的結構,在進行轉換的時候須要對逐個的類型進行匹配後,再進行轉換。固然,從源碼的角度去看待上面的 PHP 類型轉換的代碼就很是的清晰明瞭了。
字符串

 

最後get

        讀 PHP 的源碼有一段時間了,進度比較慢,說實話,對於寫 PHP 的代碼沒有什麼提升,或者對我來講沒有遇到什麼讓我提升的地方。單純的出於對知識求甚解的緣由吧。源碼

 


 

個人微信公衆號:「碼農UP2U」

相關文章
相關標籤/搜索