如何在PHP中检查特定types的对象
我有一个接受一个PDO对象作为参数的方法,以允许用户使用现有的连接,而不是方法来打开一个新的,并节省资源:
public static function databaseConnect($pdo = null) {
我知道is_object()
来检查参数是否是一个对象,但我想检查$pdo
是否是一个PDO对象,而不是一个对象。
因为用户可以很容易地input(错误地)一个不同types的对象,一个mysqli或类似的东西,整个脚本将会分开。
简而言之:如何检查特定types对象的variables?
你可以使用instanceof
:
if ($pdo instanceof PDO) { // it's PDO }
但请注意,不能像!instanceof
那样否定,所以你应该这样做:
if (!($pdo instanceof PDO)) { // it's not PDO }
另外,看看你的问题,你可以使用对象types提示,这有助于强制要求,以及简化你的检查逻辑:
function connect(PDO $pdo = null) { if (null !== $pdo) { // it's PDO since it can only be // NULL or a PDO object (or a sub-type of PDO) } } connect(new SomeClass()); // fatal error, if SomeClass doesn't extend PDO
types参数可以是必需的或可选的:
// required, only PDO (and sub-types) are valid function connect(PDO $pdo) { } // optional, only PDO (and sub-types) and // NULL (can be omitted) are valid function connect(PDO $pdo = null) { }
无types的参数允许通过显式条件的灵活性:
// accepts any argument, checks for PDO in body function connect($pdo) { if ($pdo instanceof PDO) { // ... } } // accepts any argument, checks for non-PDO in body function connect($pdo) { if (!($pdo instanceof PDO)) { // ... } } // accepts any argument, checks for method existance function connect($pdo) { if (method_exists($pdo, 'query')) { // ... } }
至于后者( 使用method_exists
),我觉得有点混。 来自Ruby的人会发现对respond_to?
熟悉respond_to?
, 不pipe是好是坏。 我亲自编写一个接口,并执行一个正常的types提示反对:
interface QueryableInterface { function query(); } class MyPDO extends PDO implements QueryableInterface { } function connect(QueryableInterface $queryable) { }
但是,这并不总是可行的。 在这个例子中, PDO
对象不是有效的参数,因为基types没有实现QueryableInterface
。
值得一提的是,在PHP中, 值有types而不是variables。 这很重要,因为null
会检查一个instanceof
。
$object = new Object(); $object = null; if ($object instanceof Object) { // never run because $object is simply null }
当它变成null
的时候,这个值会丢失它的types。
使用
bool is_a ( object $object , string $class_name )
这也适用于儿童class。
编辑:或者你可以使用types提示:
public static function databaseConnect(PDO $pdo = null) {...
我认为你可以使用instanceof
类似于:
if ($pdo instanceof YOUR_PDO_OBJECT_INSTANCE) { // it is... }
正如在其他答案中指出的, instanceof
, get_class
和is_a
可能是你正在寻找的。
然而,一些开发人员并不是在testingtypes的守卫中进行编码,而是发现它更有效率(更容易阅读),让运行时处理执行,特别是当你谈论其他程序员将要做的调用时当一个程序员犯了一个错误,应用程序大声的投诉可以说是一件好事)。
如果程序员不正确地使用你的方法时,如果你真的不需要脚本解体,那么在代码块中包装代码的相关部分(在这种情况下,可能是databaseConnect的内部),也许使用set_error_handler来引发脚本错误,然后设置一个或多个catch块,指出发生exception情况时应如何处理。