Як перевірити, чи не екземпляр якогось класу в symfony2


83

Я хочу виконати деякі функції, якщо сутність є членом кількох класів, але не деяких.

Існує функція, яка називається instanceof.

Але чи є щось подібне

if ($entity !instanceof [User,Order,Product])

1
instanceof - це не функція, це ключове слово. І ні, нічого подібного в мові PHP немає, вам доведеться реалізувати функцію, щоб зробити це самостійно.
GordonM

Đéo thằng nào có giải pháp ra hồn nhỉ
Vu Tran Kien

Відповіді:


146

Дайте їм загальний інтерфейс, а потім

if (!$entity instanceof ShopEntity)

або залишитися з

if (!$entity instanceof User && !$entity instanceof Product && !$entity instanceof Order)

Я б уникав створення довільних функцій лише для того, щоб зберегти деякі символи в одному місці. З іншого боку, якщо вам це потрібно "занадто часто", можливо, у вас є недолік дизайну? (У значенні "занадто багато крайових випадків" або подібних)


63
чи не було б краще if (!($entity instanceof User))?
Даніель В.

7
@DanFromGermany Не має значення. Можливо, читабельність. Тобі вирішувати.
KingCrunch

1
@KingCrunch Дуже концептуально заплутано, чому це не має значення? Я віддаю перевагу відповіді та раціоналізації Драгоша. Це я так роблю, оскільки здається брудним заперечувати екземпляр, який ви хочете перевірити, перш ніж перевірити, що це насправді.
Джонатан,

6
Див @ Джонатан php.net/manual/en/language.operators.precedence.php Наприкінці це тільки $a+$b+$cпроти ($a+$b)+$c. Ви коли-небудь пробували 2**3**4 == (2**3)**4? ;)
KingCrunch

Обов’язково імпортуйте / використовуйте клас, який ви перевіряєте з instanceof. Напр. бо if ( $entity instanceof Audio )мені потрібно мати use App\Entity\Audio;. PHP не видасть помилки, якщо ви не використовуєте клас, який перевіряєте, але ваш if ніколи не запускатиметься.
сім,

70

У посібнику PHP сказано: http://php.net/manual/en/language.operators.type.php

!($a instanceof stdClass)

Це лише логічний та «граматично» правильний письмовий синтаксис.

!$class instanceof someClass

Запропонований синтаксис вище, однак, хитрий, оскільки ми не вказуємо, яка саме сфера заперечення: сама змінна або вся конструкція $class instanceof someclass. Нам доведеться покладатися лише на перевагу оператора тут [Відредаговано завдяки @Kolyunya].


6
Це більш чисте рішення. Я впевнений, половина людей в кінцевому підсумку на це питання почали шукати, тому що if (!$entity instanceof ShopEntity)це не інтуїтивно ... Багато з нас використовують !$entityяк $entity === null.
mimoralea

6
Що ви маєте на увазі We will only have to rely here on the smart implementation of the PHP parser.? Існує специфікація мови, в якій чітко зазначено, що instanceofоператор має вищий пріоритет, ніж !оператор.
Колюня

2
Читаність @Kolyunya проти "хм, це виглядає дивним .. дозвольте мені знайти пріоритет оператора php ... добре, це перевіряє"
Бред Кент,

13

Перевага оператора PHP

instanceof оператор знаходиться безпосередньо перед запереченням, тоді цей вираз:

!$class instanceof someClass

в PHP в самий раз, і це все, що ви очікуєте.


Як ви вже згадували, основним моментом є те, що пріоритет instanceofоператора вищий ніж !, тому твердження дає справжній результат. Спасибі
АКО

2

Ця функція повинна це робити:

function isInstanceOf($object, Array $classnames) {
    foreach($classnames as $classname) {
        if($object instanceof $classname){
            return true;
        }
    }
    return false;
}

Отже, ваш код

if (!isInstanceOf($entity, array('User','Order','Product')));

0
function check($object) {
    $deciedClasses = [
        'UserNameSpace\User',
        'OrderNameSpace\Order',
        'ProductNameSpace\Product',
    ];

    return (!in_array(get_class($object), $allowedClasses));
}

Це погано обробляє спадщину.
hkoosha

0

Або ви можете спробувати ці

    $cls = [GlobalNameSpace::class,\GlobalNameSpaceWithSlash::class,\Non\Global\Namespace::class];
    if(!in_array(get_class($instance), $cls)){
        //do anything
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.