在类内的类外部使用 foreach 数组


Using a foreach array outside a class inside a class?

我希望标题有意义,我正在学习使用 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();
}

在这个例子中,你并没有真正正确地使用类。一个对象应该对一个对象进行建模:

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

另请参阅:

  • ooPHP - 如何从关联数组创建对象数组?

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

$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();
}

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

现在,你的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);
}

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

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

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