2011-12-24 133 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