在PHP中使用array_rand(),我得到一个超出范围的错误

时间:2017-08-22 07:28:06

标签: php arrays class methods

我是PHP的新手,我在我的代码中遇到了逻辑问题(array_rand($ arrCards,1)在它应该出现之前就已经用完了,我认为)。所以我已经完成了数组的var_dump并得到了这个输出(简短摘录):

    array (size=52)
  0 => 
    object(Card)[2]
      private 'suit' => string 'heart' (length=5)
      private 'rank' => string 'a' (length=1)
  1 => 
    object(Card)[3]
      private 'suit' => string 'heart' (length=5)
      private 'rank' => string '2' (length=1)
  2 => 
    object(Card)[4]
      private 'suit' => string 'heart' (length=5)
      private 'rank' => string '3' (length=1)

这是我的卡类:

class Card {
    //properties
    private $suit;
    private $rank;

    //constructor
    public function __construct($r, $s) {
        $this->rank = $r;
        $this->suit = $s;
    }

    //methods
    public function getSuit() {
        return $this->suit;
    }

    public function getRank() {
        return $this->rank;
    }

}

以下是我如何创建每张卡并将其推入每个数组(这是Deck类构造函数):

//constructor
    public function __construct() {
        $this->arrCards = array();

        $objCard = new Card("a", "heart");
        array_push($this->arrCards, $objCard);
        $objCard = new Card("2", "heart");
        array_push($this->arrCards, $objCard);
        $objCard = new Card("3", "heart");
blah blah continued...

(我已经向我指出,我可以使用两个for循环构建Deck,但我现在已经输入了所有内容,这可能无关紧要。)

以下是Deck课程中的相关方法:

//methods
    public function dealCard() {
        if ($this->hasCard()) {
            echo $this->intCount . PHP_EOL;
            $index = array_rand($this->arrCards, 1);
            $card = array_splice($this->arrCards,$index);
            return $card[0];
        } else {
            return Null;
        }
    }

    protected function hasCard() {
        if ($this->intCount > 0) {
            return true;
        } else {
            return false;
        }
    }

这是我得到的错误(前面是echo $this->intCount;(注意它实际上并没有像我想要的那样从卡片中取出卡片):

52 52 52 52 
( ! ) Warning: array_rand(): Second argument has to be between 1 and the number of elements in the array in C:\wamp64\www\ofc\ofc_classes.php on line 162
Call Stack
#   Time    Memory  Function    Location
1   0.0000  240704  {main}( )   ...\main.php:0
2   0.0010  348080  Deck->dealCard( )   ...\main.php:11
3   0.0010  348176  array_rand ( )  ...\ofc_classes.php:162

2 个答案:

答案 0 :(得分:2)

array_rand将从输入数组中返回一个随机密钥,而
偏移为正的{​​{3}}将从数组的开头开始从数组中删除那么多元素。

示例:

$deck = ['A','K','Q','J','10','9','8','7','6','5','4','3','2','1'];
$card = array_rand($deck,1);

print $card . PHP_EOL;
// let's assume it outputs 9, this is the key from the array
// array_rand returns a random key from the input array

$remainingDeck = array_splice($deck,$card);
print_r($remainingDeck) . PHP_EOL;
// will output
Array
(
    [0] => 5
    [1] => 4
    [2] => 3
    [3] => 2
    [4] => 1
)

这不是你所期望的,我们从牌组中淘汰了9张牌,而不只是一张。

你得到的警告告诉你,在几张发牌后,你的套牌是空的。 您可以通过在处理每张卡后打印出count $this->arrCards来轻松验证这一点,而不是依赖于$this->intCount,这些卡在交易卡后无法更新。

答案 1 :(得分:1)

我可能会更改dealCard()hasCard()方法:

public function dealCard()
{
    $result = null;
    if ($this->hasCard()) {
        $index = array_rand($this->arrCards, 1);
        $card = array_splice($this->arrCards, $index, 1);
        $result = $card[0];
    }
    return $result;
}

public function hasCard()
{
    $result = (!empty($this->arrCard));
    return $result;
}

什么和为什么:

  • 我喜欢使用$result作为方法/函数 - 您总是知道$result是您希望返回的内容
  • 初始化$result - 如果代码没有按照您的预期行事 你将永远得到回报
  • 使用带有长度参数的source code函数 - 您只需要来自套牌的1张卡
  • 1方法的退出点 - 这是一个简单的方法,但是有多个退出(return)点的更复杂的方法以后很难调试
  • 使用array_splice()功能检查是否有更多卡片 - 它可以节省使用/维护卡片中的卡片计数器