我希望标题有意义,我正在学习使用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();
}
答案 0 :(得分: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();
}
另见:
答案 1 :(得分: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关于课程架构的答案。这个答案只是为了说明你获得现在结果的原因。
答案 2 :(得分: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);
}
现在你有一个可以做反对的集合,比如返回所有标题,或者如果你构建添加的功能,按标题排序,返回特定类型的电影,返回所有类型等等。
答案 3 :(得分:1)
循环遍历数组,并在循环的每次迭代中成功地在对象中存储标题和流派。但是,您每次都会覆盖存储在对象中的值。当你运行$list->getTheGameType();
时,你会看到你输入的最后一个值,因为它覆盖了以前的值。
如果您希望对象存储有关多个游戏的信息,请对其进行修改以将数据存储在嵌套数组中(甚至是代表单个游戏的新类对象)。如果您的类被设计为包含单个游戏,那么您将需要创建一个videoGames对象数组,在每个对象中存储有关一个游戏的信息。这都是关于如何建模数据的。