Экземпляр и пространства имен

Я столкнулся с неожиданным поведением, пытаясь использовать следующее:

$object instanceof $class

1/ Ключевое слово instanceof PHP и пространства имен хорошо работают вместе, как объяснено в официальном документе.

2/ Однако иногда экранирование обратной косой черты приводит к более тонкому (неясному?) поведению, как любезно объяснил Бен в этот хороший пост.

Где-то глубоко в моем коде я установил пару дампов следующим образом:

var_dump($object, $class);
var_dump($object instanceof $class);

который дает мне следующий вывод при запуске моего скрипта:

class Tools\Tests\Entity\testObject#226 (2) {
  private $var_one =>
  NULL
  private $var_two =>
  NULL
}
string(36) "Tools\Tests\Entity\testObject"
bool(false)

Класс моего первого дампа точно такой же, как и строка во втором дампе. Однако мой instanceof dump возвращает FALSE. Почему ?

Я играл с обратной косой чертой, но безуспешно. Может быть, я где-то напутал с пространствами имен? Дело в том, что я действительно не знаю, как устранить неполадки дальше. Что я должен попробовать?


person mika    schedule 22.05.2014    source источник
comment
О, и я только что проверил, что в моем пространстве имен нет ключевого слова php...   -  person mika    schedule 22.05.2014


Ответы (3)


Вы можете протестировать экземпляры, используя пространства имен, но используйте полное имя класса.

Для вашего теста я бы сделал это:

$class = "\\Tools\\Tests\\Entity\\testObject";
$object = new $class;
var_dump($object instanceof $class); //bool(true)

Вы также можете протестировать этот способ, используя одинарные кавычки, и не беспокоиться об экранировании обратной косой черты и сэкономить несколько нажатий клавиш.

$class = '\Tools\Tests\Entity\testObject';
$object = new $class;
var_dump($object instanceof $class); //bool(true)
person Crackertastic    schedule 22.05.2014
comment
Превосходно ! Это сочетание косых черт, которые я не пробовал... И это на самом деле исправление :) - person mika; 22.05.2014
comment
@mikaРад помочь! Я тестирую все свои экземпляры таким образом, чтобы не беспокоиться о неправильном обходе иерархии пространства имен. - person Crackertastic; 22.05.2014
comment
экранированная обратная косая черта - это двойные кавычки, так как вы получаете \t там. Одиночная кавычка не анализируется, поэтому обратную косую черту экранировать не нужно. - person Deadooshka; 22.05.2014
comment
@Deadooshka Очень хороший момент. Я так привык использовать двойные кавычки для большинства вещей. Я собираюсь обновить свой ответ, чтобы проиллюстрировать это на случай, если другие столкнутся с этим в будущем. - person Crackertastic; 22.05.2014
comment
@Crackertastic, пожалуйста, не надо! На самом деле я не использую прямое присвоение переменной $class, это происходит из файла yaml, который я проанализировал с помощью пакета Yaml symfony. Что требует двойной обратной косой черты в файле. Ну ладно, если появятся два варианта, то все в порядке ;) - person mika; 22.05.2014
comment
@mika Я не изменил исходный ответ. Я добавил вторичный метод рядом с ним. Без проблем :) - person Crackertastic; 22.05.2014
comment
Не используйте раствор. Когда класс создается, он может вызвать некоторые методы init|construct, которые вы не хотите выполнять при «проверке класса». - person user1954544; 20.09.2018
comment
@user1954544 user1954544 Они уже работали с экземпляром объекта. В моем ответе создание экземпляра носит просто иллюстративный характер и соответствует целевой проблеме ОП. Ответ по-прежнему актуален. - person Crackertastic; 05.11.2018

Я использую более простой вариант

var_dump($object instanceof \Tools\Tests\Entity\testClass);
person yAnTar    schedule 31.03.2016
comment
Это более уместно, если вам не нужно считывать пространство имен и класс из переменной. Также работает только с использованием имени класса, если его пространство имен было использовано. +1 - person Adambean; 19.10.2016

Вы должны использовать ReflectionClass, чтобы избежать любого выполнения или поведения, которое у вас есть в этой модели. Узнайте больше об ReflectionClass, чтобы получить больше информации о классе\модели, которую мы проверяем. http://php.net/manual/en/class.reflectionclass.php

foreach ($this->modelNamespaces as $namespace) {
    $reflectionClass = new \ReflectionClass($namespace);

    if ($reflectionClass->implementsInterface('common\models\FieldsInCollectionInterface')) {
        // class is implemented by FieldsInCollectionInterface
    }
}
person user1954544    schedule 20.09.2018