• Сервис онлайн-записи на собственном Telegram-боте
    Тот, кто работает в сфере услуг, знает — без ведения записи клиентов никуда. Мало того, что нужно видеть свое расписание, но и напоминать клиентам о визитах тоже. Нашли самый бюджетный и оптимальный вариант: сервис VisitTime.
    Для новых пользователей первый месяц бесплатно.
    Чат-бот для мастеров и специалистов, который упрощает ведение записей:
    Сам записывает клиентов и напоминает им о визите;
    Персонализирует скидки, чаевые, кэшбэк и предоплаты;
    Увеличивает доходимость и помогает больше зарабатывать;
    Начать пользоваться сервисом
  • Как продвинуть сайт на первые места?
    Вы создали или только планируете создать свой сайт, но не знаете, как продвигать? Продвижение сайта – это не просто процесс, а целый комплекс мероприятий, направленных на увеличение его посещаемости и повышение его позиций в поисковых системах.
    Ускорение продвижения
    Если вам трудно попасть на первые места в поиске самостоятельно, попробуйте технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Если ни один запрос у вас не продвинется в Топ10 за месяц, то в SeoHammer за бустер вернут деньги.
    Начать продвижение сайта

PHP: Получение информации об объекте или классе, методах, свойствах и наследовании

Получение информации об объекте или классе

Как вы знаете, с помощью уточнений типов классов можно ограничить тип аргумента для метода некоторого объекта. Но, увы, даже используя эту возможность, не всегда можно быть уверенным в отношении типа объекта.

Существует ряд основных средств для проверки типа объекта. Прежде всего, мы можем узнать класс объекта с помощью функции get_class(). В качестве аргумента ей передается объект любого типа, а она возвращает в виде строки его имя класса.


$product = getProduct();

if ( get_class( $product ) == 'CdProduct' )
{
    print "\$product - объект класса CdProduct\n";
}

В данном фрагменте кода мы получаем что-то от функции getProduct(). Чтобы быть абсолютно уверенными, что это объект типа CdProduct, мы используем функцию get_class().

Ниже привожу определение функции getProduct().


function getProduct()
{
    return new CdProduct("Пропавший без вести", "Группа", "ДДТ", 10.99, 60.33 );
}

Как видите, функция getProduct() просто создает экземпляр объекта СdProduct и возвращает его. Вскоре мы воспользуемся этой функцией.

Функция get_class() выдает достаточно специфическую информацию, в то время как нам обычно нужно что-то более общее и простое - например, информация о принадлежности к семейству классов.

Допустим, мы хотим убедиться, что объект принадлежит семейству ShopProduct, но при этом не имеет значения, к какому классу конкретно: BookProduct или CdProduct. Для этой цели в PHP предусмотрен оператор instanceof.

Работает он с двумя операндами: объектом, который нужно проверить (указывается слева от ключевого слова instanceof), и именем класса или интерфейса справа.

Оператор возвращает значение true, если объект является экземпляром класса указанного типа.


$product = getProduct();

if ( $product ) instanceof ShopProduct )
{
    print "\$product - объект типа ShopProduct\n";
}

Получение информации о методах

Иногда бывает нужно получить список всех методов класса. Для этого нужно воспользоваться функцией get_class_methods(). В качестве аргумента ей передается имя класса, а она возвращает массив, содержащий имена всех методов класса.


print_r (get_class_methods('CdProduct'));

Предполагая, что класс CdProduct существует, получим такой результат.


Array
(
    0 => __construct
    1 => getPlayLength
    2 => getSummaryLine
    3 => getProducerFirstName
    4 => getProducerMainName
    5 => setDiscount
    6 => getDiscount
    7 => getTitle
    8 => getPrice
    9 => getProducer
    10 => setID
    11 => getInstanse
)

Все очень просто - мы передаем функции имя класса и распечатываем полученный массив с помощью функции print_r().

C таким же успехом мы могли бы передать функции get_class_methods() не только класс, но и конкретный объект.

Идем дальше.

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


$product = getProduct(); // получим объект
$method="getTitle";     // определим имя вызываемого метода
print $product->$method();  // вызовем метод

Всё вроде бы неплохо, однако такой подход таит в себе определенную опасность. Что произойдет, если метода не существует? Очевидно, сценарий завершится ошибкой. У нас уже есть опыт проверки того, существует ли метод.


if (in_array($method, get_class_methods($product )))
{
    print $product->$method();  // вызовем метод
}

Прежде, чем вызвать метод, мы проверяем, есть ли его имя в массиве, возвращенном функцией get_class_methods(). Неплохое решение, однако в PHP для этой цели уже изобретен другой "велосипед")

Имена методов можно проверить с помощью двух функций: is_callable() и method_exists(). Из этих двух вариантов is_callable() - более сложная.

В качестве первого аргумента ей передается строковая переменная, определяющая имя функции. Если заданная функция существует и ее можно вызвать, функция is_callable() возвращает значение true.

Чтобы применить такую же проверку к методу, вместо имени функции нужно передать ей массив, который должен содержать ссылку на объект или имя класса в качестве первого элемента и имя метода для проверки - в качестве второго.

Функция вернет значение true, если указанный метод существует в классе.


if ( is_callable( array( $product, $method) ) )
{
    print $product->$method();  // вызовем метод
}

У функции is_callable() также есть второй необязательный аргумент - булево значение. Если установить для него значение true, то функция будет проверять только синтаксис функции или метода, имя которого задано, а не его реальное существование.

Функции method_exists() передается ссылка на объект (или имя класса) и имя метода, а она возвращает значение true, если заданный метод существует в классе объекта.


if ( method_exists( $product, $method ) )
{
    print $product->$method();  // вызовем метод
}

Важно!
То, что метод существует, еще не означает, что его можно вызвать. функция method_exists() возвращает значение true для всех методов: закрытых (private), защищенных (protected) и, конечно же, общедоступных (public).

Получение информации о свойствах

Точно так же, как можно запросить список методов класса, можно запросить и список его свойств. Функции get_class_vars() передается имя класса, а она возвращает ассоциативный массив.

Имена свойств сохраняются в виде ключей этого массива, а значения свойств - в виде значений.

Давайте выполним проверку объекта CdProduct. Для наглядности добавим к классу общедоступное свойство: CdProduct::$coverUrl.

В результате вызова


print_r( get_class_vars( 'CdProduct' ) );

будет показано только общедоступное свойство.


Array
(
	[coverUrl] =>
)

Получение информации о наследовании

С помощью функций для работы с классами можно также выявлять отношения наследования.

Например, с помощью функции get_parent_class() можно узнать имя родительского класса для указанного класса.

Этой функции передается ссылка на объект или имя класса, а она возвращает имя родительского класса (суперкласса), если таковой существует. Если же такого класса нет, то функция вернет значение false. В результате вызова


print get_parent_class('CdProduct');

мы получим имя родительского класса ShopProduct, как и можно было ожидать.

С помощью функции is_subclass_of() можно также проверить, является ли класс дочерним для другого класса.

Этой функции передается ссылка на дочерний объект и имя родительского класса. Функция возвращает значение true, если второй класс является суперклассом первого аргумента.


$product = getProduct(); // получим объект

if ( is_subclass_of( $product, 'ShopProduct' ) )
{
    print "CdProduct является дочерним классом  класса ShopProduct";
}

Функция is_subclass_of() сообщит информацию только об отношениях наследования в классе, однако не поможет нам узнать, реализует ли класс интерфейс - для этой цели следует использовать оператор instanceof.

Кроме того, можно воспользоваться функцией call_implements(), которая является частью SPL (Standard PHP Library). Этой функции передается имя класса или ссылка на объект, а она возвращает массив имен интерфейсов.


if ( in_array( 'someInterface', class_implements( $product )) )
{
    print "CdProduct реализует интерфейс someInterface";
}

Ну вот мы и разобрались с тем, как получать информацию об объекте или классе, методах, свойствах и наследовании. Увидимся в новых материалах.

Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!


Смотрите также:

CodeIgniter: жив или мертв?

CodeIgniter: жив или мертв?

Функции обратного вызова, анонимные функции и механизм замыканий

Функции обратного вызова, анонимные функции и механизм замыканий

Применение функции к каждому элементу массива

Применение функции к каждому элементу массива

Слияние массивов. Преобразование массива в строку

Слияние массивов. Преобразование массива в строку

Деструктор и копирование объектов с помощью метода __clone()

Деструктор и копирование объектов с помощью метода __clone()

Эволюция веб-разработчика или Почему фреймворк - это хорошо?

Эволюция веб-разработчика или Почему фреймворк - это хорошо?

Магические методы в PHP или методы-перехватчики (сеттеры, геттеры и др.)

Магические методы в PHP или методы-перехватчики (сеттеры, геттеры и др.)

PHP: Удаление элементов массива

PHP: Удаление элементов массива

Ключевое слово final (завершенные классы и методы в PHP)

Ключевое слово final (завершенные классы и методы в PHP)

50 классных сервисов, программ и сайтов для веб-разработчиков

50 классных сервисов, программ и сайтов для веб-разработчиков

Наверх