类中的PHP异常

时间:2010-04-21 19:13:01

标签: php exception

我正在为我的朋友编写一个Web应用程序(PHP),并决定使用Java提供的有限OOP培训。

我的问题是,在我的课程/应用程序中,如果没有真正破坏我的页面,那么特定的关键事项会失败,这是最好的方法。

我的问题是我有一个Object“SummerCamper”,它接受一个camper_id作为参数,将所有必要的数据从数据库加载到对象中。假设某人在查询字符串中指定了一个不存在的camper_id,我将其传递给我的对象构造函数并且加载失败。我目前没有看到从构造函数返回false的方法。

我已经读过我可能会使用Exceptions执行此操作,如果在数据库中找不到任何记录,或者如果从应用程序等输入camper_id时某些验证失败,则抛出异常。

但是,我还没有找到一个很好的方法来警告我的程序对象加载失败。我尝试从CATCH中返回false但是对象仍然存在于我的php页面中。我知道如果加载失败我可以放置变量$ is_valid = false然后使用get方法检查Object但我认为可能有更好的方法。

如果加载失败,实现对象基本终止的最佳方法是什么?我应该从构造函数外部将数据加载到对象中吗?我应该研究一些设计模式吗?

任何帮助都将不胜感激。

function __construct($camper_id){
        try{
            $query = "SELECT * FROM campers WHERE camper_id = $camper_id";
            $getResults = mysql_query($query);

            $records = mysql_num_rows($getResults);

            if ($records != 1) {
                throw new Exception('Camper ID not Found.');
            }

            while($row = mysql_fetch_array($getResults))
            {
                $this->camper_id = $row['camper_id'];
                $this->first_name = $row['first_name'];
                $this->last_name = $row['last_name'];
                $this->grade = $row['grade'];
                $this->camper_age = $row['camper_age'];
                $this->camper_gender = $row['gender'];
                $this->return_camper = $row['return_camper'];
            }
        }
        catch(Exception $e){
            return false;
        }



    }

4 个答案:

答案 0 :(得分:14)

constructor in PHP将始终返回void。此

public function __construct()
{
    return FALSE;
}

不起作用。构造函数中的Throwing an Exception

public function __construct($camperId)
{
    if($camperId === 1) {
        throw new Exception('ID 1 is not in database');
    }
}

会终止脚本执行,除非你把它抓到某个地方

try { 
    $camper = new SummerCamper(1);
} catch(Exception $e) {
    $camper = FALSE;
}

你可以将上面的代码移到static method的SummerCamper来创建它的实例,而不是使用new关键字(这在我听说过的Java中很常见)

class SummerCamper
{
    protected function __construct($camperId)
    {
        if($camperId === 1) {
            throw new Exception('ID 1 is not in database');
        }
    }
    public static function create($camperId)
    {
        $camper = FALSE;
        try {
            $camper = new self($camperId);
        } catch(Exception $e) {
            // uncomment if you want PHP to raise a Notice about it
            // trigger_error($e->getMessage(), E_USER_NOTICE);
        }
        return $camper;
    }
}

这样你可以做到

$camper = SummerCamper::create(1);
FALSE不存在时,

并在$camper中获取$camper_id。自statics are considered harmful起,您可能希望使用Factory。

另一种选择是将数据库访问与SummerCamper完全分离。基本上,SummerCamper是一个只关注SummerCamper事物的实体。如果您了解如何坚持自己,那么您实际上是在创建ActiveRecordRowDataGateway。您可以使用DataMapper方法:

class SummerCamperMapper
{
    public function findById($id)
    {
        $camper = FALSE;
        $data = $this->dbAdapter->query('SELECT id, name FROM campers where ?', $id);
        if($data) {
            $camper = new SummerCamper($data);
        }
        return $camper;
    }
}

和你的实体

class SummerCamper
{
    protected $id;
    public function __construct(array $data)
    {
        $this->id = data['id'];
        // other assignments
    }
}

DataMapper有点复杂,但它为您提供了解耦代码,最终可维护性和灵活性。看看SO,关于这些主题有很多问题。

答案 1 :(得分:5)

要添加其他人的答案,请记住,您可以从单个方法中抛出不同类型的异常,并以不同方式处理它们:

try {
    $camper = new SummerCamper($camper_id);
} catch (NoRecordsException $e) {
    // handle no records
} catch (InvalidDataException $e) {
    // handle invalid data
}

答案 2 :(得分:1)

从构造函数中抛出异常可能是正确的方法。您可以在适当的位置捕获此信息,并采取必要的操作(例如显示错误页面)。由于您没有显示任何代码,因此不清楚您捕获异常的位置或原因似乎不起作用。

答案 3 :(得分:1)

try {
    $camper = new SummerCamper($id);
    $camper->display();
} catch (NonexistentCamper $ex) {
    handleFailure($ex);
}