2013-05-04 16 views
9

我不知道標題應該是什麼,但代碼應該更好地解釋它:增量的「__toString」

class Group { 
    private $number = 20; 

    public function __toString() { 
     return "$this->number"; 
    } 
} 

$number = new Group(); 
echo $number, PHP_EOL; 
echo ++ $number, PHP_EOL; 

echo PHP_EOL; 

$number = "20"; 
echo $number, PHP_EOL; 
echo ++ $number, PHP_EOL; 

echo PHP_EOL; 

$number = 20; 
echo $number, PHP_EOL; 
echo ++ $number, PHP_EOL; 

輸出:

20 
20    <--- Expected 21 

20 
21 

20 
21 

任何想法,爲什麼我得到20代替21?即使這樣下面的代碼工作:

$i = null ; 
echo ++$i ; // output 1 

我知道Group是實現__toString一個對象,我預計++__toString或至少throw an error

+0

PHP提供了一種方式來重載增量運算符嗎?由於你的類不容易轉換爲數字類型,你可能不得不告訴PHP你想要做什麼。 – dlp 2013-05-04 14:34:01

+1

如果您在Group類中聲明$ number不是私有的,然後嘗試使用echo ++ $ number-> number,PHP_EOL;作品? – LuckyStarr 2013-05-04 14:37:17

+0

沒有..但是這是字符串增加,即使否則..我應該得到一個錯誤 – Baba 2013-05-04 14:37:34

回答

12

在操作發生的順序很重要:

  1. 變量將是牽強,因爲一個對象,它不會被強制轉換爲一個整數(或別的東西)。

  2. 這個++運算符遞增zvallval(長整數值),但通常沒有別的。對象指針保持不變。內部(fast_)increment_function將與zval調用,它有一個指向該對象的指針,該對象首先檢查類型。如果它是一個對象,它什麼也不做。所以當你的zval是一個對象時,它和無操作一樣有用。這不會輸出任何警告。

  3. 只有當echo指令對其參數執行字符串轉換時:調用__toString方法並返回20

  4. 20將被輸出。

9

與字符串工作要回答你帶着一點點質疑的代碼。

$number = new Group(); 
echo gettype($number); 

$number = "20"; 
echo gettype($number); 

$number = 20; 
echo gettype($number); 

會導致

object 
string 
integer 

的三種情況:

  • 你不能做任何整數操作的對象,那爲什麼你的代碼沒有你所期望的。 __toString方法將調用非常晚,當您嘗試對它進行數學運算失敗後,將會計算出實際輸出。
  • 您可以到數學與字符串,因爲PHP在內部轉換回數字
  • 很明顯,你可以做數學整數

獎勵:

這將工作:

$number = new Group(); 
echo 1 + "$number"; // 21 

它把你對象轉換爲字符串,它可能被轉換成編號爲數學運算。

+0

顯式添加一個到變量表達式實際上打​​開了添加數量的方法,非常簡單。應該避免增量前或後增量操作。你永遠不會知道會發生什麼。 [道格拉斯克羅克福德不喜歡他們。](http://stackoverflow.com/questions/971312/why-avoid-increment-and-decrement-operators-in-javascript) - 在PHP中,它更容易使用簡短版本'$ i + = 1 ^'而不是'$ i ++' - 只是一個字符。並嘗試增加2 ... :) – Sven 2013-06-22 20:22:44

2

我認爲這可能是隻改變變量的名字,如更清楚:

class Group { 
    private $number = 20; 

    public function __toString() { 
     return "$this->number"; 
    } 
} 

$group = new Group(); 
echo $group;//print 20 as per your __toString function 

++ $group; 

現在看來很明顯:什麼是應該做一個「+」操作符類型分組的對象??

1

爲什麼不乾脆:

class Group { 
    private $number = 0; 
    public function __construct($number = 0){ 
     $this->number = intval($number); 
    } 
    public function __toString() { 
     return number_format(++$this->number); // pre-increment 
    } 
} 
$g = new Group(); 
echo $g; // 1 
echo $g; // 2 

我使用的表像這樣的東西格式偏移。

0

這實際上是比你想象的更可行的 - 只需要多做一點點的類型轉換,如下所示:

<?php 

class Group { 
private $number = 20; 

    public function __toString() { 
     return (string) $this->number; // replace "" w/string cast 
    } 
} 

$number = (int)(string) new Group(); 
echo $number, PHP_EOL; 
echo ++$number, PHP_EOL; 

您不必使用的字符串投當然在魔術__toString(),但我個人更喜歡閱讀代碼的方式,而不是看到引號 - 但我認爲這只是一種文體偏好。

將新創建的對象作爲字符串進行投射會導致魔法__toString方法自動執行,並返回一個數字字符串,該字符串在投射到int時允許您顯示數字,將其增加並再次顯示。

順便說一句,++和$ number之間的空格是可以的;我把它關閉了B/C,這是我習慣於像C這樣的其他語言。