PHP5,析构函数中的异常

时间:2014-01-04 00:31:28

标签: php exception destructor

我现在正在阅读“专业人士的PHP5”,这是2006年的出版物。在一个例子中,他们在析构函数中抛出异常,很长一段时间我无法理解为什么我的析构函数中的最后一个异常不起作用,然后我搜索了它并发现在 PHP => 5.3 在析构函数中抛出异常不可用。那么如何做更好,如果在析构函数中我更新我的数据库,如果变量$needsUpdate = true;并关闭我的数据库连接,所以我想在数据库无法更新时抛出异常。例如,我在我的数据库类中抛出异常,但在主文件中捕获它们,如下所示:

它的类Widget:

class Widget {

    private $_id;
    private $_name;
    private $_description; private $_hDB;
    private $_needsUpdating = false;

    public function __construct($widgetID) {

        $this->_hDB = new mysqli('localhost', 'phpbook', 'Un+)J=<AaH', 'phpbook');
        if (! $this->_hDB) {
            throw new Exception('Не удалось подключится к базе данных');
        }
        $sql = "SELECT `name`, `description` FROM widgets WHERE id = '$widgetID'";
        $rs = $this->_hDB->query($sql);

        if (! $rs) {
            throw new Exception("Произошла ошибка при выборе базы данных");
        }

        if (! $rs->num_rows) {
            throw new Exception("Указаная запись в базе данных отсутствует");
        }
        $data = $rs->fetch_assoc();
        $this->_id = $widgetID;
        $this->_name = $data['name'];
        $this->_description = $data['description'];

    }

    public function getName() {
        return $this->_name;
    }

    public function getDescription() {
        return $this->_description;
    }

    public function setName($name) {
        $this->_name = $name;
        $this->_needsUpdating = true;
    }

    public function setDescription($description) {
        $this->_description = $description;
        $this->_needsUpdating = true;
    }

    public function __destruct() {
        if (! $this->_needsUpdating) {
            return;
        }

        $sql = 'UPDAT2E `widgets` SET';
        $sql .= ' `name` = "' . $this->_hDB->real_escape_string($this->_name) . '",';
        $sql .= ' `description` = "' . $this->_hDB->real_escape_string($this->_description) . '" ';
        $sql .= 'WHERE id = ' . $this->_id;


        $rs = $this->_hDB->query($sql);
        if (! $rs) {
            throw new Exception("Произошла ошибка при обновлении базы данных");
        }
        $this->_hDB->close();
    }
}

这是主要档案。

try {
    $widget = new Widget(2);
    echo "Name: " . $widget->getName() . "<br />\n";
    echo "Description: " . $widget->getDescription() . "<br />\n";
    $widget->setName("Iphone 4 / 64GB");
    $widget->setDescription("New Phone, black color, blablabla");

} catch (Exception $e) {
    die("An error has occurred: " . $e->getMessage());
}

__destruct()中的最后一个例外不起作用。

如果更新数据库失败,那么有一种很好的方法可以抛出异常吗?还是有其他正确的方法,我不明白的东西?

1 个答案:

答案 0 :(得分:3)

析构函数中的异常(可能)会导致致命错误。文档说明了这一点:构造“&gt; http://us.php.net/_construct

  

注意:   尝试从析构函数中抛出异常(在脚本终止时调用)会导致致命错误。

在大多数情况下,你会得到这样的东西:

PHP Fatal error: Exception thrown without a stack frame in Unknown on line 0

一个好方法是不要重新发明这个轮子并采取例如Doctrine(http://www.doctrine-project.org/)帮助您完成此任务。即使你不能使用这个软件,你也可以查看资料来了解本杰明是如何做到这一点的。查看EntityManager(https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/EntityManager.php)和UnitOfWork(https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php),它们与您在问题中提到的处理有关。