类中的PHP异常

mmu*_*iff 6 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;
        }



    }
Run Code Online (Sandbox Code Playgroud)

Gor*_*don 14

PHP中构造函数将始终返回void.这个

public function __construct()
{
    return FALSE;
}
Run Code Online (Sandbox Code Playgroud)

不管用.在构造函数中抛出异常

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

将终止脚本执行,除非你在某处捕获它

try { 
    $camper = new SummerCamper(1);
} catch(Exception $e) {
    $camper = FALSE;
}
Run Code Online (Sandbox Code Playgroud)

您可以将上面的代码移动到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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样你就可以做到

$camper = SummerCamper::create(1);
Run Code Online (Sandbox Code Playgroud)

FALSE在不存在$camper时进入$camper_id.由于静态被认为是有害的,您可能想要使用工厂.

另一种选择是将数据库访问与数据访问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;
    }
}
Run Code Online (Sandbox Code Playgroud)

和你的实体

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

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


web*_*ave 5

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

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

  • 是.好建议. (2认同)