Method exists: примеры (PHP)
method_exists(object|string $object_or_class, string $method): boolФункция method_exists проверяет, существует ли метод в переданном объекте или классе. Она часто используется для динамического вызова методов, в системах плагинов, обработчиках событий или при работе с объектами, структура которых может меняться.
Функция принимает два обязательных параметра:
- object_or_class (mixed) – Объект (экземпляр класса) или имя класса в виде строки.
- method (string) – Название метода, существование которого нужно проверить. Чувствительно к регистру.
Возвращаемое значение: true, если метод существует, false – в противном случае.
<?php
class MyClass {
public function myMethod() {}
}
$obj = new MyClass();
var_dump(method_exists($obj, 'myMethod'));
var_dump(method_exists($obj, 'nonExistentMethod'));bool(true) bool(false)
<?php
class MyClass {
public function myMethod() {}
}
var_dump(method_exists('MyClass', 'myMethod'));
var_dump(method_exists('MyClass', 'unknownMethod'));bool(true) bool(false)
<?php
class ParentClass {
public function inheritedMethod() {}
}
class ChildClass extends ParentClass {}
$obj = new ChildClass();
var_dump(method_exists($obj, 'inheritedMethod'));bool(true)
function_exists() – проверяет существование глобальной функции, но не метода класса.
is_callable() – более универсальная функция. Проверяет, может ли переданное значение быть вызвано как функция. Учитывает область видимости метода (public, private, protected) и массив callable формата [$object, 'method'].
property_exists() – проверяет существование свойства у объекта или класса.
Используйте method_exists, когда нужно просто проверить наличие метода в классе, не обращая внимания на его область видимости. Функция is_callable предпочтительнее, если проверка нужна перед непосредственным вызовом, так как она также проверяет доступность метода в текущем контексте.
class MyClass:
def my_method(self):
pass
obj = MyClass()
print(hasattr(obj, 'my_method')) # Проверяет наличие атрибута/метода
print(callable(getattr(obj, 'my_method', None))) # Проверяет, что атрибут можно вызватьTrue True
class MyClass {
myMethod() {}
}
const obj = new MyClass();
console.log(typeof obj.myMethod === 'function'); // true
console.log('myMethod' in obj); // true (проверка в цепочке прототипов)
console.log(obj.hasOwnProperty('myMethod')); // false, т.к. метод в прототипеtrue true false
В SQL подобная проверка не требуется, так как структура баз данных статична и определяется через системные таблицы (INFORMATION_SCHEMA).
<?php
// Будет выведено предупреждение, но функция вернет false
var_dump(method_exists('NonExistentClass', 'someMethod'));Warning: method_exists(): Class NonExistentClass does not exist in ... bool(false)
<?php
$className = $_GET['class'] ?? 'DefaultClass';
// Опасный код, если класс может не существовать
if (method_exists($className, 'handle')) { ... }Рекомендуется сначала проверить существование класса через class_exists.
<?php
class MyClass {
public function myMethod() {}
}
$obj = new MyClass();
var_dump(method_exists($obj, 'MYMETHOD')); // falsebool(false)
В PHP 8.0.0 параметр object_or_class теперь принимает только объекты или строки с именем класса. Передача других типов данных теперь вызывает ошибку TypeError. Ранее принимались любые типы, что могло приводить к неочевидному поведению.
<?php
// PHP 7: выдаст предупреждение и вернет false
// PHP 8: вызовет TypeError
var_dump(method_exists(null, 'foo'));<?php
interface Handler {
public function handle($data);
}
class LogHandler implements Handler {
public function handle($data) { echo "Log: $data"; }
}
class MailHandler implements Handler {
public function handle($data) { echo "Mail: $data"; }
public function setup() { echo "Setup mail"; }
}
function process($handlerName, $data) {
if (!class_exists($handlerName)) {
throw new Exception("Class $handlerName not found");
}
$handler = new $handlerName();
if (method_exists($handler, 'setup')) {
$handler->setup(); // Вызываем опциональный метод, если он существует
}
$handler->handle($data);
}
process('MailHandler', 'test data');
process('LogHandler', 'test data');Setup mail Mail: test data Log: test data
<?php
class MagicClass {
public function __call($name, $arguments) {
echo "Вызван магический метод $name";
}
}
$obj = new MagicClass();
// method_exists не проверяет магические методы __call и __callStatic
var_dump(method_exists($obj, 'dynamicMethod'));
// Но проверяет сам факт наличия __call
var_dump(method_exists($obj, '__call'));bool(false) bool(true)
<?php
trait MyTrait {
public function traitMethod() {}
}
class MyClass {
use MyTrait;
}
$obj = new MyClass();
var_dump(method_exists($obj, 'traitMethod'));bool(true)
<?php
class ParentClass {
private function privateMethod() {}
protected function protectedMethod() {}
}
class ChildClass extends ParentClass {}
$obj = new ChildClass();
// method_exists возвращает true даже для приватных методов родителя
var_dump(method_exists($obj, 'privateMethod'));
var_dump(method_exists($obj, 'protectedMethod'));
// Но is_callable для приватного метода вернет false
var_dump(is_callable([$obj, 'privateMethod']));bool(true) bool(true) bool(false)