php 的一些小众的用法,很多php老司机,使用时也会出问题。
今天就聊一聊php的自增运算符。
bool 值
对于bool值无效。
1 2
| # php -r '$a=false; $a++; var_dump($a);'; bool(false)
|
null 值
null 值,自增后为整型1.
1 2
| # php -r '$a=null; $a++; var_dump($a);'; int(1)
|
数字运算
字符运算
继承自perl的字符自增运算符。
以字符结尾
1 2 3 4 5 6 7 8 9 10
| # php -r '$a="a"; $a++; var_dump($a);'; string(1) "b" # php -r '$a="z"; $a++; var_dump($a);'; string(2) "aa" # php -r '$a="A"; $a++; var_dump($a);'; string(1) "B" # php -r '$a="Z"; $a++; var_dump($a);'; string(2) "AA" # php -r '$a="zzz"; $a++; var_dump($a);'; string(4) "aaaa"
|
数字结尾
1 2 3 4
| # php -r '$a="Z1"; $a++; var_dump($a);'; string(2) "Z2" # php -r '$a="Z9"; $a++; var_dump($a);'; string(3) "AA0"
|
php 源码中,字符串自增运算符的算法说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| #define LOWER_CASE 1 #define UPPER_CASE 2 #define NUMERIC 3
static void ZEND_FASTCALL increment_string(zval *str) { int carry=0; size_t pos=Z_STRLEN_P(str)-1; char *s; zend_string *t; int last=0; int ch;
if (Z_STRLEN_P(str) == 0) { zval_ptr_dtor_str(str); ZVAL_INTERNED_STR(str, ZSTR_CHAR('1')); return; }
if (!Z_REFCOUNTED_P(str)) { Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0); Z_TYPE_INFO_P(str) = IS_STRING_EX; } else if (Z_REFCOUNT_P(str) > 1) { Z_DELREF_P(str); Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0); } else { zend_string_forget_hash_val(Z_STR_P(str)); } s = Z_STRVAL_P(str);
do { ch = s[pos]; if (ch >= 'a' && ch <= 'z') { if (ch == 'z') { s[pos] = 'a'; carry=1; } else { s[pos]++; carry=0; } last=LOWER_CASE; } else if (ch >= 'A' && ch <= 'Z') { if (ch == 'Z') { s[pos] = 'A'; carry=1; } else { s[pos]++; carry=0; } last=UPPER_CASE; } else if (ch >= '0' && ch <= '9') { if (ch == '9') { s[pos] = '0'; carry=1; } else { s[pos]++; carry=0; } last = NUMERIC; } else { carry=0; break; } if (carry == 0) { break; } } while (pos-- > 0);
if (carry) { t = zend_string_alloc(Z_STRLEN_P(str)+1, 0); memcpy(ZSTR_VAL(t) + 1, Z_STRVAL_P(str), Z_STRLEN_P(str)); ZSTR_VAL(t)[Z_STRLEN_P(str) + 1] = '\0'; switch (last) { case NUMERIC: ZSTR_VAL(t)[0] = '1'; break; case UPPER_CASE: ZSTR_VAL(t)[0] = 'A'; break; case LOWER_CASE: ZSTR_VAL(t)[0] = 'a'; break; } zend_string_free(Z_STR_P(str)); ZVAL_NEW_STR(str, t); } }
|
php 自增运算符 Doc
路漫漫其修远兮,吾将上下而求索。