2010-03-05 15 views
2

J'essaie d'utiliser une boucle foreach pour un tableau d'objets. A l'intérieur de la méthode BeginBattle(), je veux parcourir tous les objets et incrémenter automatiquement leur nombre. Malheureusement, le navigateur web montre que j'ai une erreur: Erreur fatale: Appel à une fonction membre BattleInitiated() sur un non-objet dans /nfs/c05/h01/mnt/70299/domains/munchkinparty.neededspace.net/html/ Battle.php sur la ligne 75PHP foreach sur un tableau d'objets

Des idées?

<?php 
/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 

/** 
* Description of Battle 
* 
* @author joshualowry 
*/ 
class Battle { 
    /** 
    * 
    * @var <type> 
    */ 
    private $_players; 
    /** 
    * 
    * @var <type> 
    */ 
    private $_battleInProgress; 
    /** 
    * 
    */ 
    public function Battle(){ 
     $this->_players = array(); 
     $this->_battleInProgress = FALSE; 

    } 
    /** 
    * 
    * @param <type> $player 
    * @return <type> 
    */ 
    public function AddPlayer($player){ 
     if(!$this->_battleInProgress) 
      $this->_players[] = $player; 
     else 
      return; 
      //Spit some error 
    } 

    /** 
    * 
    * @param <type> $player 
    * @return <type> 
    */ 
    public function BattleWon($player){ 
     if($player != NULL) 
      $player->BattleWon(); 
     else 
      return; 
      //Spit some error 
    } 
    /** GetPlayerByName Get the player's object by the player's name field. 
    * 
    * @param <type> $playerName 
    * @return <type> 
    */ 
    public function GetPlayerByName($playerName){ 
     foreach($this->_players as &$player) { 
      if($player->GetName() == $playerName) 
     return $player; 
     } 
     return NULL; 
    } 

    /** 
    * 
    */ 
    public function BeginBattle(){ 
     $this->_battleInProgress = TRUE; 
     foreach($this->_players as $player){ 
     $player->BattleInitiated(); 
    } 
    } 
    /** 
    * 
    */ 
    public function DisplayCurrentBoard() { 
     echo "Name Alias Wins Battles<br/>"; 
     foreach($this->_players as &$player){ 
      echo "$player->GetName() $player->GetAlias() $player->GetWins() $player->GetBattles()<br/>"; 
     } 
    } 

} 
?> 

C'est là que tout est déclarée et a appelé:

<?php 
    include 'Battle.php'; 
    include 'Person.php'; 
    include 'Player.php'; 

    $currentBattle = new Battle(); 

    $playerA = new Player("JohnnyDanger","John",0,0); 
    $playerB = new Player("JoshTheJest","Josh",0,0); 
    $PlayerC = new Player("CarbQueen","Nicole",0,0); 

    $currentBattle->AddPlayer($playerA); 
    $currentBattle->AddPlayer($playerB); 
    $currentBattle->AddPlayer($playerC); 

    $currentBattle->BeginBattle(); 
    $currentBattle->BattleWon($currentBattle->GetPlayerByName("Josh")); 
    $currentBattle->DisplayCurrentBoard(); 
?> 

La classe du joueur

<?php 

    /** 
    * Description of Player 
    * 
    * @author joshualowry 
    */ 
    class Player extends Person { 

     private $_alias; 
     private $_wins; 
     private $_battles; 

     public function Player($name, $alias, $wins, $battles) { 
      parent::SetName($name); 
      $this->_alias = $alias; 
      $this->_battles = $battles; 

      if($battles == 0) { 
       $this->_wins = 0; 
      } 
      else { 
       $this->_wins = $wins; 
      } 
     } 

     protected function SetAlias($value){ 
      $this->_alias = $value; 
     } 

     public function GetAlias(){ 
      return $this->_alias; 
     } 

     protected function SetBattles($value) { 
      $this->_battles = $value; 
     } 

     public function GetBattles(){ 
      return $this->_battles; 
     } 

     protected function SetWins($value) { 
      $this->_wins = $value; 
     } 

     public function GetWins() { 
      return $this->_wins; 
     } 

     public function BattleWon(){ 
      $this->_wins += 1; 
     } 

     public function BattleInitiated(){ 
      $this->_battles += 1; 
     } 

    } 

?> 
+0

Montrez-nous où AddPlayer est d'être appelé. –

+0

Que transmettez-vous à AddPlayer()? – Amber

+0

Comment instanciez-vous votre objet 'Battle()' et appelez les fonctions 'AddPlayer()' et 'BeginBattle()'? –

Répondre

3

Le message d'erreur indique que vous essayez de toute la méthode BattleInitiated() sur quelque chose qui wasn 't un objet.

A en juger par votre code, le problème semble être avec cette boucle, dans la méthode BeginBattle():

foreach($this->_players as $player){ 
    $player->BattleInitiated(); 
} 

Ce qui signifie lecteur $, au moins un dans votre tableau, est probablement pas un objet; peut-être c'est null, ou un tableau?


Pour en savoir plus, vous devez utiliser var_dump pour afficher le contenu de $this->_players avant que la boucle, juste pour vous assurer qu'il contient ce que vous attendez à:

public function BeginBattle(){ 
    var_dump($this->_players); 
    $this->_battleInProgress = TRUE; 
    foreach($this->_players as $player){ 
     $player->BattleInitiated(); 
    } 
} 

Si $this->_players ne contient pas ce vous vous attendez à (et il n'a probablement pas!), vous devrez alors savoir pourquoi ...


Considérant $this->_players est modifié par la méthode AddPlayer(), qui ajoute ce qu'il reçoit à la fin du tableau, je parie que AddPlayer() est appelée au moins une fois sans un $player correct comme paramètre.

Pour aider, vous pouvez utiliser var_dump sur le $player étant ajouté:

public function AddPlayer($player){ 
    var_dump($player); 
    if(!$this->_battleInProgress) 
     $this->_players[] = $player; 
    else 
     return; 
     //Spit some error 
} 

Si ce var_dump indique au moins une fois que $player n'est pas un objet (par exemple, il est null, ou un tableau , ou une chaîne, ...), c'est la cause de votre erreur fatale.

+0

J'ai ajouté du code ci-dessus, mais le troisième joueur, PlayerC, est nul une fois qu'il est ajouté en utilisant AddPlayer ... des idées? –

+0

Je viens de réaliser que j'ajoutais $ PlayerC pas $ playerC. Votre réponse m'a aidé à trouver l'erreur. J'ai ajouté un contrôle lorsqu'un joueur est ajouté à la bataille pour voir s'il s'agit d'un joueur. Maintenant les vars NULL et les autres types ne seront pas ajoutés. –

+0

Heureux de vous voir trouvé ce qui causait le problème :-) Et merci de l'expliquer :-) –

0

votre variable $player est soit nulle ou non un objet du type vous voulez qu'il soit.

PlayerObject est quel que soit votre nom de classe pour le joueur.

Par exemple

$battle=new Battle(); 
$player1=new PlayerObject(); 
$player2="player"; 
$battle->AddPlayer($player1); 
$battle->AddPlayer($player2); 
$battle->BeginBattle(); 

lorsque vous appelez le BeginBattle()$player1->BattleInitiated(); sera couronnée de succès, mais le $player2->BattleInitiated() vous donnera l'erreur fatale et arrêter votre code de courir. même si $player2 était null, un entier ou quelque chose qui n'est pas PlayerObject.

1

ne le voyez-vous pas ??

il est tout à cause d'une petite faute de frappe:

$playerA = new Player("JohnnyDanger","John",0,0); 
    $playerB = new Player("JoshTheJest","Josh",0,0); 
    $PlayerC = new Player("CarbQueen","Nicole",0,0); 

    $currentBattle->AddPlayer($playerA); 
    $currentBattle->AddPlayer($playerB); 
    $currentBattle->AddPlayer($playerC); 

a déclaré: $ _P_layerC utilisé: correct $ _p_layerC

que vous êtes bon pour aller

+0

Merci de regarder en arrière à ce sujet. Comme vous verrez mon commentaire sur la réponse acceptée affirmant que les conseils de l'affiche m'a aidé à trouver la faute de frappe et m'a également aidé à réaliser que j'avais besoin de valider les entrées avant de les ajouter. –