php 的自增運算符

php 的一些小衆的用法,不少php老司機,使用時也會出問題。
今天就聊一聊php的自增運算符。php

bool 值

對於bool值無效。算法

# php -r '$a=false; $a++; var_dump($a);';
   bool(false)

null 值

null 值,自增後爲整型1.shell

# php -r '$a=null; $a++; var_dump($a);';
  int(1)

數字運算

  • 正常範圍的整數:.net

    #  php -r '$a=1; $a++; var_dump($a);';
    int(2)
  • 最大值的整數,整數直接變成浮點數:code

    # php -r '$a=9223372036854775807; $a++; var_dump($a);'
      float(9.2233720368548E+18)
      # php -r '$a=9223372036854775806; $a++; var_dump($a);'
      int(9223372036854775807)
  • 浮點數的計算:

若在精度範圍內,則自增長1,若不在精度範圍內,則忽略。blog

字符運算

繼承自perl的字符自增運算符。

  • 以字符結尾繼承

    # 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"
  • 數字結尾rem

    # php -r '$a="Z1"; $a++; var_dump($a);';
    string(2) "Z2"
    # php -r '$a="Z9"; $a++; var_dump($a);';
    string(3) "AA0"

php 源碼中,字符串自增運算符的算法說明:

#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; /* Shut up the compiler warning */
  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') { // 當末端是z 時,須要進位,修改成a
              s[pos] = 'a';
              carry=1;
          } else {
              s[pos]++;
              carry=0;
          }
          last=LOWER_CASE;
      } else if (ch >= 'A' && ch <= 'Z') {
          if (ch == 'Z') { // 同理,當末端是Z時,須要進位,修改成A
              s[pos] = 'A';
              carry=1;
          } else {
              s[pos]++;
              carry=0;
          }
          last=UPPER_CASE;
      } else if (ch >= '0' && ch <= '9') {
          if (ch == '9') { // 當末端時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) {  // 須要進位, 則須要多分配一個byte
      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) {   //考慮上一位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

來源:https://blog.lpflpf.cn/passag...字符串

相關文章
相關標籤/搜索