Как проверить наличие определенного типа объекта в PHP
у меня есть метод, который принимает объект PDO в качестве аргумента, чтобы позволить пользователю использовать существующее соединение, а не метод для открытия нового и сохранения ресурсов:
public static function databaseConnect($pdo = null) {
Я в курсе is_object()
чтобы проверить, является ли аргумент объектом, но я хочу проверить, если $pdo
объект PDO, а не просто объект.
потому что пользователь может легко ввести (по ошибке?) другой вид объекта, mysqli или такой, и весь скрипт сломается отдельно.
короче говоря: как я могу проверить переменную для определенного типа объекта?
4 ответа:
можно использовать
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
), я немного смешан в своем мнении. Люди, приезжающие из Руби, найдут его знакомым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
отсутствие типа.
использовать
bool is_a ( object $object , string $class_name )
это будет работать и для детских классов.
изменить: Или вы можете использовать подсказку типа:
public static function databaseConnect(PDO $pdo = null) {...
Я думаю, что вы можете использовать
instanceof
что-то типа:if ($pdo instanceof YOUR_PDO_OBJECT_INSTANCE) { // it is... }
как указано в других ответах,
instanceof
,get_class
иis_a
наверное, то, что вы ищете.однако, вместо того, чтобы кодировать во многих охранниках, которые проверяют тип, некоторые разработчики считают более продуктивным (и легче читать) просто позволить среде выполнения обрабатывать принудительное исполнение, особенно когда вы говорите о вызовах, которые будут делать другие программисты (когда программист делает ошибку, громкие жалобы на взлом приложений, возможно, хороши).
Если вам действительно не нужно, чтобы сценарий разваливался, когда программист неправильно использует ваш метод, оберните соответствующий раздел кода (в этом случае, вероятно, внутри databaseConnect) в попробовать блок, возможно использовать set_error_handler чтобы создать исключения для ошибок скрипта, а затем настроить один или несколько блоков catch, которые указали, что делать, когда происходит условие исключения.