【问题标题】:Fatal Error: Call to member function on non-object when it is an object致命错误:当它是对象时调用非对象上的成员函数
【发布时间】:2013-09-16 00:23:45
【问题描述】:

我有一个类包含一组类。循环遍历数组并尝试运行 Class 函数时,出现错误:

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

这是我的代码:

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

汽车类

class Car {
    public $data;

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

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

当在那个“非对象”(第 19 行)上使用 print_r 时,我得到了这个:

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

当在“非对象”调用 getTDs()(第 20 行)上使用 print_r 时,我明白了:

<td>Ferrari</td>

那么,当我尝试将该结果添加到我的 $html 变量时,为什么在下一行它会中断?

【问题讨论】:

  • 当 PHP 告诉你某物不是对象时,它真的不是对象。
  • var_dump($this-&gt;cars) 看看里面是否有超过 1 个对象。
  • 这更像是一个问题而不是一个答案,但你可以在你正在实例化的同一个类中创建一个类的新实例。意思是你的New Car 行?你就不能$this吗?
  • @u_mulder var_dump($this-&gt;cars) 显示 115 辆汽车。我的数据库中有多少个。

标签: php class oop object foreach


【解决方案1】:

你的 for 语句是:

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

但在该循环中,您将 $i 增加了两倍。

$i++;
$i++;

所以在循环的最后一次迭代中,$i 指向 cars 的最后一个元素,但是当您再次增加 $i 时,您将到达数组的末尾。

所以在你到达太远之前停止循环。您的解决方法应该是:

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

编辑每次尝试访问索引时检查您是否位于 cars 数组的末尾会更明智。

【讨论】:

  • 啊,你是对的。错误不在我想象的第二个对象上,而是在数组末尾附近。虽然从计数中减去 2 不是解决方法,但在每次调用之前检查是否是 $i == $l。谢谢。
  • 如果你在数组的末尾,那么输出&lt;td&gt;&lt;/td&gt; 这样你就不会破坏最后一行
【解决方案2】:

你在循环中增加你的索引,你不需要这样做。这应该可以正常工作:

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

另外,作为最佳实践,请尝试在循环外使用计数,它具有更好的性能。

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

【讨论】:

  • 计数 正在 发生在循环之外,并且您破坏了 OP 想要的预期布局。
  • for 循环的第一部分用于初始化,即只执行一次。所以,没有性能问题。这两段代码之间的唯一区别是定义$l 的范围。
猜你喜欢
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 2012-05-30
  • 2016-08-30
  • 2015-02-06
  • 2012-05-14
相关资源
最近更新 更多