Aust
Aust

Reputation: 11632

Fatal Error: Call to member function on non-object when it is an object

I have one class that holds an array of Classes. When looping through the array and trying to run Class functions, I get the error:

Fatal error: Call to a member function getTDs() on a non-object on line 21

Here is my code:

Cars.class

class Cars {
    private $cars = array();

    public function __construct(){
        $result = DB::getData("SELECT * FROM `cars` ORDER BY `name`");

        foreach($result as $row){
            $this->cars[] = new Car($row);
        }
    }

    public function printTable(){
        $html = '<table>';
        for($i=0, $l=count($this->cars); $i<$l; $i++){
            $html .= '<tr>';
            $html .= $this->cars[$i]->getTDs();
            $html .= '<td></td>';
            $i++;
            //print_r($this->cars[$i]);
            //print_r($this->cars[$i]->getTDS());
            $html .= $this->cars[$i]->getTDs(); //This is the supposed non-object
            $html .= '<td></td>';
            $i++;
            $html .= $this->cars[$i]->getTDs();
            $html .= '</tr>';
        }
        $html .= '</table>';
        echo($html);
    }
}

Car.class

class Car {
    public $data;

    public function __construct($data){
        $this->data = $data;
    }

    public function getTDs(){
        $html = '<td>'.$this->data['name'].'</td>';
        return $html;
    }
}

When using print_r on that "non-object" (line 19) I get this:

Car Object
(
    [data] => Array
    (
        [name] => 'Ferrari'
    )
)

When using print_r on the "non-object" calling getTDs() (line 20) I get this:

<td>Ferrari</td>

So how come when in the very next line when I try to add that result to my $html variable it breaks?

Upvotes: 0

Views: 206

Answers (2)

oscarmtzr5
oscarmtzr5

Reputation: 7

You're incrementing your index inside the loop, which you do not need to do. This should work fine:

for($i=0, $l=count($this->cars); $i<$l; $i++){
        $html .= '<tr>';
        $html .= $this->cars[$i]->getTDs();
        $html .= '<td></td>';
        $html .= "</tr>";
}

Also, as a best practice, try using count outside loops, it has better performance.

$numCars = count($this->cars);
for($i=0; $i<$numCars; $i++)
{
  ...
}

Upvotes: -1

000
000

Reputation: 27247

Your for statement is:

for($i=0, $l=count($this->cars); $i<$l; $i++){

But inside that loop, you are incrementing $i twice more.

$i++;
$i++;

So at the last iteration through the loop, $i points to the last element of cars, but when you increment $i again, you're reaching past the end of the array.

So stop the loop before you reach too far. Your fix should be:

for($i=0, $l=count($this->cars)-2; $i<$l; $i++){

Edit It is smarter to check if you're at the end of the cars array every time you attempt to access an index.

Upvotes: 3

Related Questions