一尘不染

如何在PHP中检查特定类型的对象

php

我有一个接受PDO对象作为参数的方法,以允许用户使用现有连接,而不是该方法打开一个新连接并节省资源:

public static function databaseConnect($pdo = null) {

我知道is_object()要检查参数是否为对象,但我想检查是否$pdo为PDO对象,而不仅仅是对象。

因为用户可以轻松输入(错误地输入?)另一种对象(一个mysqli或类似的对象),并且整个脚本会破裂。

简而言之:如何检查特定类型对象的变量?


阅读 339

收藏
2020-05-29

共1个答案

一尘不染

您可以使用instanceof

if ($pdo instanceof PDO) {
    // it's PDO
}

但是请注意,您不能像否定!instanceof,所以您应该这样做:

if (!($pdo instanceof PDO)) {
    // it's not PDO
}

另外,查看您的问题,您可以使用对象类型提示,它有助于强制执行要求并简化检查逻辑:

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

输入的参数可以是必需的或可选的:

// 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) { }

无类型的参数可通过显式条件实现灵活性:

// 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?,无论好坏,它都是熟悉的。我将亲自编写一个接口并针对该接口执行普通的类型提示:

interface QueryableInterface
{ 
    function query();
}

class MyPDO extends PDO implements QueryableInterface { }

function connect(QueryableInterface $queryable) { }

但是,这并不 总是 可行的。在此示例中,PDO对象不是有效的参数,因为基本类型未实现QueryableInterface

还值得一提的是,在PHP中, 值具有类型 ,而不是变量。这很重要,因为null将使instanceof检查失败。

$object = new Object();
$object = null;
if ($object instanceof Object) {
    // never run because $object is simply null
}

当值变成时,它失去类型null,缺少类型。

2020-05-29