2011-12-24 40 views
5

PHP có một tính năng mà bạn có thể sử dụng increment operators trên chuỗi. Nó hoạt động tương tự như một đồng hồ đo, nơi mà khi bạn đạt đến cuối của một phạm vi, nó "cuộn qua".Ở đâu trong nguồn PHP là mã để tăng chuỗi?

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

Chỉ cần tò mò ở đâu trong mã nguồn PHP này. Tôi thường nhìn vào mã nguồn tại các hàm/phần mở rộng, nhưng một cái gì đó như thế này tôi không có ý tưởng nơi để tìm.

Liên kết tới tệp bằng cách sử dụng web based SVN của chúng sẽ thật tuyệt vời.

+0

tôi thời gian gần đây [phát hiện ra về vấn đề này] (http://stackoverflow.com/questions/ 3567180/increment-letters-like-numbers) và sử dụng nó để điền các ô trong một bảng tính excel. Tính năng lạ nếu bạn hỏi tôi nhưng nó chắc chắn có thể hữu ích. –

+0

bạn có tìm thấy nguồn mà nó tăng số không? – emaillenin

+2

https://github.com/php/php-src/blob/master/Zend/zend_operators.c#L1706 – mario

Trả lời

10

Việc thực hiện cho toán tử này tọa lạc thuận tiện trong zend_operators.c, trong một chức năng mà thậm chí còn thuận tiện hơn gọi 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

Và điều này được gọi từ [increment_function()] (http://svn.php.net/viewvc/php/php-src/trunk/Zend/zend_operators.c?view=markup#l1790), mà tôi cho là toán tử gia tăng. –

+0

@ Álvaro G. Vicario: Đúng vậy. – BoltClock

Các vấn đề liên quan