我希望标题有意义,我正在学习使用 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 对象数组,在每个对象中存储有关一个游戏的信息。 这完全取决于您希望如何对数据进行建模。