1

我希望标题有意义,我正在学习使用 PHP 类并且我理解得很好,我试图超越我已经阅读/观看的教程并使用数组来返回值。

我纯粹只是在试验,想知道为什么我做错了(我没有添加我的 foreach 尝试,希望有人能指出在该getTheGameType()方法上运行 foreach 的位置)以及正确的方法。

//Just a manual array containing key/value pairs of games with their genres 
$array = array(
        "Grand Theft Auto" => "Action",
        "NBA 2k14" => "Sports",
        "COD" => "Shooting",
);

//My object
class videoGames {


    public $title;
    public $genere;

    public function setTheGameType($title,$genere) {

        $this->title = $title;
        $this->genere = $genere;
    }

    public function getTheGameType() {

            return 'The game genre for '.$this->title.' is:' . $this->genere;

    }

}

//New instance of `videoGames` class
$list = new videoGames();

//Here I set the game title with its genere
foreach ($array as $title => $genere) {
    $list-> setTheGameType($title,$genere);
}

//Echo the value passed into getTheGameType() function
    echo $list->getTheGameType();

以上返回COD的游戏类型为:获取数组最后一个值的射击。

如何返回本质上循环该getTheGameType()方法的所有键/值对?

编辑: 我通过添加 echo $list->getTheGameType();到 foreach 循环中使其工作。

对方法有疑问?这是不好的做法吗?

   foreach ($array as $title => $genere) {
    $list-> setTheGameType($title,$genere);
    echo $list->getTheGameType();
}
4

4 回答 4

8

在此示例中,您并没有真正正确地使用类。一个对象应该建模一个对象:

class VideoGame {          // Singular title (not gameS)

    private $title;        // Make these private - information hiding
    private $genre;        // spell this correctly!  :-)

    // Use a constructor to initialize fields in the class!
    public function __construct($title,$genre) {
        $this->title = $title;
        $this->genre = $genre;
    }

    // Here are "getters" for the two fields.
    // Note that I have not provided "setters" - so these fields will
    // always have their initial value (as set in the constructor).
    // Types like this (with no setters) are often called "immutable".
    public function getTitle() {
        return $this->title;
    }

    public function getGenre() {
        return $this->genre;
    }

    public function getDescriptiveString() {
        return $this->title . ' is a ' . $this->genre . ' game.\n';
    }

}

创建这些:

// This array has three instances of the VideoGame object.
// Often, this would actually be the result of a database query.
$game_array = array(
    new VideoGame("Grand Theft Auto", "Action"),
    new VideoGame("NBA 2k14", "Sports"),
    new VideoGame("COD", "Shooting")
);

遍历它们:

// We get the descriptive string from each game and print it.
foreach ($game_array as $game) {
    echo $game->getDescriptiveString();
}

也可以看看:

于 2013-09-13T23:38:25.530 回答
2

您正在实例化该类的单个实例并重写类型。我假设您希望每个游戏都有自己的类实例:

$games = array();

//Here I set the game title with its genere
foreach ($array as $title => $genere) {
    //New instance of `videoGames` class
    $list = new videoGames();
    $list->setTheGameType($title,$genere);
    $games[] = $list;
}

foreach($games AS $game)
{
    echo $game->getTheGameType();
}

但是,请参阅 jonathon 关于类架构的回答。这个答案只是为了说明为什么你会得到现在的结果。

于 2013-09-13T23:40:03.367 回答
2

好吧,现在,您的videoGames班级确实没有正确命名。目前它只能存储一个视频游戏。当您运行循环时,您只是在对象上重置标题和流派的类属性。

如果你真的想在 OOP 中工作,你可能需要两个类,一个用于视频游戏,一个用于表示视频游戏的集合。因此,让我们假设您保持当前课程不变,但重命名它video_game(单数)。

然后你可能想添加一个类来存储这样的视频游戏:

class video_game_collection {
    protected $collection = array();

    // allow construction of collection by passing array of video_games (though not required)
    public __construct($game_array = null) {
        // validate all array elements are proper objects if the array is set
        if(is_array($game_array)) {
            foreach ($array as $game) {
                if ($game instanceof video_game === false) {
                    throw new Exception('You sent a date array element.');
                } else {
                    $this->collection[] = $game;
                }
            }
        }
    }

    public add_video_game($game) {
        if ($game instanceof video_game === false) {
            throw new Exception ('This is not a game.');
        }
        $this->collection[] = $game;
    }

    public get_collection() {
        return $this->collection;
    }
}

您可能不应该有这样的逻辑在您的类中回显消息(将类限制为单一目的 - 表示数据对象)。所以我建议你只在 getGameType 方法中返回游戏类型,而不是让它实际回显文本。把消息留给课外的东西。

把它放在一起,你可以做类似的事情

$collection = new video_game_collection();

//Just a manual array containing key/value pairs of games with their genres 
$array = array(
        "Grand Theft Auto" => "Action",
        "NBA 2k14" => "Sports",
        "COD" => "Shooting",
);

foreach($array as $game => $genre) {
    $game = new videoGame();
    $game->setTheGameType($game, $genre);
    $collection->add_video_game($game);
}

现在你有一个可以做的事情的集合,比如返回所有标题,或者如果你构建了附加功能,按标题排序,返回特定类型的电影,返回所有类型等。

于 2013-09-13T23:54:46.803 回答
1

您正在循环一个数组,并在循环的每次迭代中成功地将标题和流派存储在对象中。但是,您每次也会覆盖存储在对象中的值。当你运行时$list->getTheGameType();,你会看到你输入的最后一个值,因为它覆盖了之前的值。

如果您希望您的对象存储有关多个游戏的信息,请将其修改为将数据存储在嵌套数组中(甚至是新的对象类,代表单个游戏)。如果您的类被设计为包含单个游戏,那么您将需要创建一个 videoGames 对象数组,在每个对象中存储有关一个游戏的信息。这完全取决于您希望如何对数据进行建模。

于 2013-09-13T23:39:52.293 回答