Php 按值向数组添加对象

Php 按值向数组添加对象,php,arrays,Php,Arrays,我有一个单例类,用于一副卡片,应该在构造函数中创建52张卡片。看起来是这样的: protected function __construct() { global $instance; $suits = array("clubs", "spades", "hearts", "diamonds"); settype($instance->deck, "array"); foreach ($suits as $suit) { for ($

我有一个单例类,用于一副卡片,应该在构造函数中创建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相当陌生

编辑:下面是我正在测试的卡片、卡片组和文件的完整定义。不是最好或最理想的代码,而是用于快速的学校作业。我还尝试将$instance->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();
?>

谢谢。可能是一些愚蠢的事情或是我的愚蠢。

这里有两个问题阻碍了这项工作的正常进行,在技术上,只有先解决第一个问题,才能让卡片显示出来,但为了更好的基础应用,让我们来解决这两个问题

第一个问题是Card类的处理方式,特别是通过使用global关键字。全局从全局范围中提取变量定义;在本例中,它在Card类之外寻找$suit、$cardVal和$imageName的定义,而不是该类的成员变量。您要使用的是$this操作符:

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;
    }
}

为什么要使用克隆,而不仅仅是将新卡直接添加到阵列中?粘贴类组的定义是否声明了静态属性$instance?你的卡片构造器只是以防万一,在卡片和卡片组类中显示你的代码。另外@newfurniture是正确的。在这里克隆对象没有意义。直接将卡添加到阵列$instance->deck[]=new card$suit,$i;,既便宜又快捷;。完美的非常感谢。作用域的处理方式与我熟悉的C、objective-C、java等其他语言非常不同。。。我想我需要做更多的研究。纠正的例子也很壮观。
<?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>';
        }
    }
}