2011-12-24 131 views
5

PHP有一個功能,您可以在字符串上使用increment operators。它的行爲與里程錶類似,一旦你達到一個範圍的末尾,它就會「翻滾」。PHP源代碼中增加字符串的代碼在哪裏?

<?php 
$str = 'zy'; 
$str++; 
echo "$str\n"; // zz 
$str++; 
echo "$str\n"; // aaa 

只是好奇在PHP源代碼這是什麼。我經常查看函數/擴展的源代碼,但是像這樣的東西,我不知道在哪裏看。

使用它們的web based SVN鏈接到文件將會很棒。

+0

我最近[發現了這個(http://stackoverflow.com/questions/ 3567180/increment-letters-like-numbers)並用它來填充Excel電子表格中的單元格。奇怪的功能,如果你問我,但肯定會有用。 – 2011-12-24 17:51:23

+0

你有沒有找到它增加數字的來源? – emaillenin 2011-12-24 17:58:14

+2

https://github.com/php/php-src/blob/master/Zend/zend_operators.c#L1706 – mario 2011-12-24 17:59:03

回答

10

這個操作符的實現是座落在zend_operators.c,在這更方便地稱爲increment_string()功能:

static void increment_string(zval *str) /* {{{ */ 
{ 
    int carry=0; 
    int pos=Z_STRLEN_P(str)-1; 
    char *s=Z_STRVAL_P(str); 
    char *t; 
    int last=0; /* Shut up the compiler warning */ 
    int ch; 

    if (Z_STRLEN_P(str) == 0) { 
     STR_FREE(Z_STRVAL_P(str)); 
     Z_STRVAL_P(str) = estrndup("1", sizeof("1")-1); 
     Z_STRLEN_P(str) = 1; 
     return; 
    } 

    if (IS_INTERNED(s)) { 
     s = (char*) emalloc(Z_STRLEN_P(str) + 1); 
     memcpy(s, Z_STRVAL_P(str), Z_STRLEN_P(str) + 1); 
     Z_STRVAL_P(str) = s; 
    } 

    while (pos >= 0) { 
     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; 
     } 
     pos--; 
    } 

    if (carry) { 
     t = (char *) emalloc(Z_STRLEN_P(str)+1+1); 
     memcpy(t+1, Z_STRVAL_P(str), Z_STRLEN_P(str)); 
     Z_STRLEN_P(str)++; 
     t[Z_STRLEN_P(str)] = '\0'; 
     switch (last) { 
      case NUMERIC: 
       t[0] = '1'; 
       break; 
      case UPPER_CASE: 
       t[0] = 'A'; 
       break; 
      case LOWER_CASE: 
       t[0] = 'a'; 
       break; 
     } 
     STR_FREE(Z_STRVAL_P(str)); 
     Z_STRVAL_P(str) = t; 
    } 
} 
/* }}} */ 
+3

這是從[increment_function()](http://svn.php.net/viewvc/php/php-src/trunk/Zend/zend_operators.c?view=markup#l1790)調用的,我想這是增量運算符。 – 2011-12-24 18:05:37

+0

@ÁlvaroG. Vicario:是的。 – BoltClock 2011-12-24 18:06:25