Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to use a foreach loop for an array of objects. Inside of the BeginBattle() method I want to iterate through all of the objects and increment their played count automatically. Unfortunately, the web browser shows I have an error: Fatal error: Call to a member function BattleInitiated() on a non-object in /nfs/c05/h01/mnt/70299/domains/munchkinparty.neededspace.net/html/Battle.php on line 75

Any ideas?

<?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/>";
        }
    }

}
?>

This is where everything is declared and called:

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

The Player Class

    <?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;
        }

    }

?>
share|improve this question
Show us where AddPlayer is being called. – Matthew Flaschen Mar 5 '10 at 5:41
What are you passing to AddPlayer()? – Amber Mar 5 '10 at 5:42
How are you instantiating your Battle() object and calling the AddPlayer() and the BeginBattle() functions? – Jonathan Czitkovics Mar 5 '10 at 5:46
Do you have a Player class and a proper constructor [php.net/manual/en/language.oop5.decon.php] ? – JannieT Mar 5 '10 at 5:58
@JannieT Your link gives a 404. – Jonathan Czitkovics Mar 5 '10 at 6:14
show 2 more comments

3 Answers

up vote 3 down vote accepted

The error message indicates that you are trying to all the BattleInitiated() method on something that wasn't an object.

Judging from your code, the problem seems to be with this loop, in the BeginBattle() method :

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

Which means $player, at least one in your array, is probably not an object ; maybe it's null, or an array ?


To know more, you should use var_dump to display the content of $this->_players before the loop, just to make sure it contains what you expect it to :

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

If $this->_players doesn't contain what you expect it to (and it probably doesn't !), you'll then have to find out why...


Considering $this->_players is modified by the AddPlayer() method, which adds what it receives to the end of the array, I would bet that AddPlayer() is called at least once without a correct $player as a parameter.

To help with that, you could use var_dump on the $player being added :

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

If that var_dump indicates at least once that $player is not an object (for instance, it's null, or an array, or a string, ...), that's the cause of your Fatal Error.

share|improve this answer
I added some code above, but the third player, PlayerC, is null once it is added using AddPlayer... any ideas? – Joshua Lowry Mar 6 '10 at 4:21
I just realized I was adding $PlayerC not $playerC. Your answer helped me find the error. I added a check when a player is added to the battle to see if it is a 'Player'. Now NULL vars and other types will not be added. – Joshua Lowry Mar 6 '10 at 4:30
Glad to see you found what was causing the problem :-) And thanks for explaning it :-) – Pascal MARTIN Mar 6 '10 at 12:16

don't you see it??

it's all because of a small typo:

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

declared: $_P_layerC used: $_p_layerC

correct that and you're good to go

share|improve this answer
Thanks for looking back at this. As you will see my comment on the accepted answer stating that the poster's tips helped me to find the typo and also helped me to realize that I needed to validate the entries before adding them. – Joshua Lowry Feb 21 at 15:13

Your $player variable is either null or not an Object of the type you want it to be.

PlayerObject is what ever your class name for player is.

For example

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

when you call BeginBattle() the $player1->BattleInitiated(); will be successful but the $player2->BattleInitiated() will give you the fatal error and stop your code from running. same if $player2 was null, an integer or something that is not PlayerObject.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.