2014-09-22 131 views
0

我有一套卡片的單例類,應該在構造函數中創建52張卡片。它看起來像這樣:按值向數組添加對象

protected function __construct() { 

    global $instance; 

    $suits = array("clubs", "spades", "hearts", "diamonds"); 

    settype($instance->deck, "array"); 

    foreach ($suits as $suit) { 
     for ($i = 1; $i <= 13; $i++) { 
      $card = new Card($suit, $i); 
      $instance->deck[] = clone $card; 
     } 
    } 
} 

我所得到的是所有充滿了鑽石王的物體。克隆關鍵字不應該阻止這個嗎?對不起,如果這是比我能找到更基本的,我很新的PHP。

編輯:這是Card,Deck和我正在測試的文件的完整定義。不是最好的或最優化的代碼,而是快速的學校作業。我還曾試圖分配$實例 - >甲板[]直接到新卡的對象,但隨後試圖克隆關鍵字後

Card.php

<?php 
class Card { 

var $suit; 
var $cardVal; 
var $imageName; 

function __construct($suitName, $val) { 
    global $suit, $cardVal; 

    $suitName = strtolower($suitName); 
    if (gettype($val) === "string") { 
     $val = strtolower($val); 
    } 

    switch ($suitName) { 
     case 'hearts': 
      $suit = 'Hearts'; 
      break; 
     case 'clubs': 
      $suit = 'Clubs'; 
      break; 
     case 'diamonds': 
      $suit = 'Diamonds'; 
      break; 
     case 'spades': 
      $suit = 'Spades'; 
      break; 
     case 'heart': 
      $suit = 'Hearts'; 
      break; 
     case 'club': 
      $suit = 'Clubs'; 
      break; 
     case 'diamond': 
      $suit = 'Diamonds'; 
      break; 
     case 'spade': 
      $suit = 'Spades'; 
      break; 
     default: 
      $suit = 'Hearts'; 
    } 

    switch ($val) { 
     case 1: 
      $cardVal = "Ace"; 
      break; 
     case 2: 
      $cardVal = "2"; 
      break; 
     case 3: 
      $cardVal = "3"; 
      break; 
     case 4: 
      $cardVal = "4"; 
      break; 
     case 5: 
      $cardVal = "5"; 
      break; 
     case 6: 
      $cardVal = "6"; 
      break; 
     case 7: 
      $cardVal = "7"; 
      break; 
     case 8: 
      $cardVal = "8"; 
      break; 
     case 9: 
      $cardVal = "9"; 
      break; 
     case 10: 
      $cardVal = "10"; 
      break; 
     case 11: 
      $cardVal = "Jack"; 
      break; 
     case 12: 
      $cardVal = "Queen"; 
      break; 
     case 13: 
      $cardVal = "King"; 
      break; 
     case '1': 
      $cardVal = "Ace"; 
      break; 
     case '2': 
      $cardVal = "2"; 
      break; 
     case '3': 
      $cardVal = "3"; 
      break; 
     case '4': 
      $cardVal = "2"; 
      break; 
     case '5': 
      $cardVal = "3"; 
      break; 
     case '6': 
      $cardVal = "2"; 
      break; 
     case '7': 
      $cardVal = "3"; 
      break; 
     case '8': 
      $cardVal = "2"; 
      break; 
     case '9': 
      $cardVal = "3"; 
      break; 
     case '10': 
      $cardVal = "2"; 
      break; 
     case 'jack': 
      $cardVal = "Jack"; 
      break; 
     case 'queen': 
      $cardVal = "Queen"; 
      break; 
     case 'king': 
      $cardVal = "King"; 
      break; 
     case 'j': 
      $cardVal = "Jack"; 
      break; 
     case 'q': 
      $cardVal = "Queen"; 
      break; 
     case 'k': 
      $cardVal = "King"; 
      break; 
     default: 
      $cardVal = "Ace"; 
    } 

    $this->setImageName(); 
} 

function SetImageName() { 
    global $imageName, $cardVal, $suit; 
    $imageName = $cardVal . "Of" . $suit . ".gif"; 
} 

public function GetImageName() { 
    global $imageName; 

    return $imageName; 
} 

public function GetSuit() { 
    global $suit; 

    return $suit; 
} 

public function GetCardVal() { 
    global $cardVal; 

    return $cardVal; 
} 
} 
?> 

Deck.php

<?php 
class Deck { 

private static $instance; 
public $deck = array(); 

// The singleton method 
public static function singleton() 
{ 
    if (!isset(self::$instance)) { 
     $class = __CLASS__; 
     self::$instance = new $class; 
    } 
    return self::$instance; 
} 

protected function __construct() { 

    global $instance; 

    $suits = array("clubs", "spades", "hearts", "diamonds"); 

    settype($instance->deck, "array"); 

    foreach ($suits as $suit) { 
     for ($i = 1; $i <= 13; $i++) { 
      $card = new Card($suit, $i); 
      $instance->deck[] = clone $card; 
     } 
    } 
} 

function PrintDeck() { 
    global $instance; 

    foreach ($instance->deck as $card) { 
     echo $card->GetImageName() . '<br>'; 
    } 
} 
} 
?> 

打電話來自:

<?php 

include './models/Deck.php'; 
include './models/Card.php'; 

$deck = Deck::singleton(); 

$deck->printDeck(); 
?> 

謝謝。可能有些愚蠢或我很愚蠢。

+1

爲什麼使用'clone'而不是直接將新卡添加到陣列? – newfurniturey 2014-09-22 14:17:08

+0

粘貼類Deck的定義(你是否聲明瞭'static'屬性''instance'')和你的卡片構造函數(以防萬一) – Kleskowy 2014-09-22 14:20:00

+0

在'Card'和'Deck'類中顯示你的代碼。 @newfurniturey也是對的。在這裏克隆對象沒有任何意義。將卡直接添加到陣列('$ instance-> deck [] =新卡($ suit,$ i);')會更便宜,速度更快。 – 2014-09-22 18:38:45

回答

0

這裏有兩個問題妨礙它按照您的期望工作(技術上只固定第一個將顯示卡,但讓我們修復它們以獲得更好的基本應用)。

第一個問題是Card課程處理variable scope的方式,特別是通過使用global關鍵字。 global從全球範圍拉取變量定義;在這種情況下,它正在尋找Card類之外的$suit,$cardVal$imageName的定義,而不是類的成員變量。什麼你要改用的是$this操作:

Card.php(注:我清理switch語句也一點點地節省空間/可讀性)

<?php 
class Card { 
    var $suit = ''; 
    var $cardVal = ''; 
    var $imageName = ''; 

    function __construct($suitName, $val) { 
     $suitName = strtolower($suitName); 
     $val = is_string($val) ? strtolower($val) : $val; 

     switch ($suitName) { 
      case 'clubs': 
      case 'club': 
       $this->suit = 'Clubs'; 
       break; 
      case 'diamonds': 
      case 'diamond': 
       $this->suit = 'Diamonds'; 
       break; 
      case 'spades': 
      case 'spade': 
       $this->suit = 'Spades'; 
       break; 
      case 'hearts': 
      case 'heart': 
      default: 
       $this->suit = 'Hearts'; 
     } 

     if (($val >= 2) && ($val <= 10)) { 
      $this->cardVal = $val; 
     } else { 
      switch ($val) { 
       case 11: 
       case 'jack': 
       case 'j': 
        $this->cardVal = "Jack"; 
        break; 
       case 12: 
       case 'queen': 
       case 'q': 
        $this->cardVal = "Queen"; 
        break; 
       case 13: 
       case 'king': 
       case 'k': 
        $this->cardVal = "King"; 
        break; 
       case 1: 
       case 'ace': 
       default: 
        $this->cardVal = "Ace"; 
      } 
     } 

     $this->setImageName(); 
    } 

    private function SetImageName() { 
     $this->imageName = $this->cardVal . "Of" . $this->suit . ".gif"; 
    } 

    public function GetImageName() { 
     return $this->imageName; 
    } 

    public function GetSuit() { 
     return $this->suit; 
    } 

    public function GetCardVal() { 
     return $this->cardVal; 
    } 
} 

通過使上面的更改,卡應全部顯示。但是,還有一個基本問題,就是Deck類的單例設計。在整個過程中,它指的是self::$instance->deck,其中它應該應該而不是$this->deck訪問它。靜態/單一想法僅適用於$instance;之外的對象的使用將調用成員函數,然後訪問單件的屬性(在此情況下,全局$deck):

Deck.php(注:我也除去clone呼叫 - 這是不必要的)

<?php 
class Deck { 
    private static $instance; 
    public $deck = array(); 

    public static function singleton() { 
     if (!static::$instance) { 
      $class = __CLASS__; 
      static::$instance = new $class; 
     } 
     return static::$instance; 
    } 

    protected function __construct() { 
     $suits = array("clubs", "spades", "hearts", "diamonds"); 

     foreach ($suits as $suit) { 
      for ($i = 1; $i <= 13; $i++) { 
       $this->deck[] = new Card($suit, $i); 
      } 
     } 
    } 

    public function PrintDeck() { 
     foreach ($this->deck as $card) { 
      echo $card->GetImageName() . '<br>'; 
     } 
    } 
} 
+0

完美。非常感謝。範圍與我熟悉的其他語言(C#,objective-c,java等)處理方式有所不同,我想我需要做更多的研究。更正的例子也很棒。 – cjpoppe 2014-09-23 04:36:57