按值向数组添加对象

时间:2014-09-22 14:15:04

标签: php arrays

我有一个卡片组的单例类,应该在构造函数中创建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;
        }
     }
}

我所得到的是所有充满钻石之王的物品。 clone关键字不应该阻止这个吗?对不起,如果这比我能找到的更基本,我对php很新。

编辑:这是Card,Deck和我正在测试的文件的完整定义。不是最好的或最优的代码,而是快速的学校作业。我还尝试将$ instance-&gt; deck []直接分配给一个新的Card对象,但之后尝试了clone关键字

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 个答案:

答案 0 :(得分:0)

这里有两个问题阻止它按照你期望的方式工作(技术上只修复第一个将显示卡片,但让我们修复它们以获得更好的基础应用程序。)

第一个问题是Card类正在处理variable scope的方式,特别是通过使用global关键字。 global从全局范围中提取变量定义;在这种情况下,它正在查找$suit类之外的$cardVal$imageNameCard的定义,而不是类的成员变量。您要使用的是$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>';
        }
    }
}