2014-09-22 87 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