Подтвердить что ты не робот

Как проверить конкретный тип объекта в PHP

У меня есть метод, который принимает объект PDO в качестве аргумента, чтобы позволить пользователю использовать существующее соединение, а не метод для открытия нового, и сохранять ресурсы:

public static function databaseConnect($pdo = null) {

Я знаю is_object(), чтобы проверить, является ли аргумент объектом, но я хочу проверить, является ли $pdo объектом PDO, а не только объектом.

Так как пользователь может легко ввести (по ошибке?) другой тип объекта, mysqli или такой, и весь script разломается.

Вкратце: как я могу проверить переменную для определенного типа объекта?

4b9b3361

Ответ 1

Вы можете использовать instanceof:

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

Помните, что вы не можете отрицать, как !instanceof, поэтому вместо этого выполните:

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

Кроме того, просматривая свой вопрос, вы можете использовать подсказку типа объекта, которая помогает применять требования, а также упрощает логику проверки:

function connect(PDO $pdo = null)
{
    if (null !== $pdo) {
        // it 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, отсутствие типа.

Ответ 2

использование

 bool is_a ( object $object , string $class_name )

Это будет работать и для дочерних классов.

см. http://php.net/is-a

EDIT: Или вы можете использовать тип намека:

public static function databaseConnect(PDO $pdo = null) {...

Ответ 3

Я думаю, вы можете использовать instanceof что-то вроде:

if ($pdo instanceof YOUR_PDO_OBJECT_INSTANCE) {
   // it is...
}

Ответ 4

Как указано в других ответах, instanceof, get_class и is_a, вероятно, вы ищете.

Однако, вместо того, чтобы кодировать множество охранников, проверяющих тип, некоторые разработчики считают его более продуктивным (и более простым для чтения), чтобы позволить среде выполнения выполнять принудительное выполнение, особенно когда вы говорите о вызовах, которые другие программисты будут (когда программист совершает ошибку, прикладывающие громкие жалобы, возможно, хорошо).

Если вам действительно не нужно разваливать script, когда программист неправильно использует ваш метод, заверните соответствующий раздел кода (в данном случае, возможно, внутри базы данныхConnect) в попытаться заблокировать, возможно использовать set_error_handler для исключения исключений при ошибках script, а затем настроить один или несколько блоков catch, которые указывали, что делать, когда происходит условие исключения.