- PHP method_exists
- Introduction to the PHP method_exists function
- PHP method_exists function examples
- 1) Using the PHP method_exists() function to check if a class has a method
- 2) Using the PHP method_exists function to check if an object has a method
- 3) Using the method_exists function to check if an object has a static method
- PHP method_exists function in MVC frameworks
- Summary
- Check if a method exists in an extended class but not parent class
- 6 Answers 6
- Find out if a method exists in a static class
- 3 Answers 3
- Update:
PHP method_exists
Summary: in this tutorial, you’ll learn how to use the PHP method_exists() function to check if a class or an object of a class has a specified method.
Introduction to the PHP method_exists function
The method_exists() function returns true if an object or a class has a specified method. Otherwise, it returns false .
The syntax of the method_exists() function is as follows:
method_exists(object|string $object_or_class, string $method): bool
Code language: PHP (php)
The method_exists() has two parameters:
- $object_or_class is an object or a class in which you want to check if a method exists.
- $method is a string that represents the method to check.
PHP method_exists function examples
Let’s take some examples of using the method_exists() function.
1) Using the PHP method_exists() function to check if a class has a method
The following example uses the method_exists() function to check if a method exists in the BankAccount class:
class BankAccount < public function transferTo(BankAccount $other, float $amount) < // more code > > $exists = method_exists(BankAccount::class, 'transferTo'); var_dump($exists); // bool(true) $exists = method_exists(BankAccount::class, 'deposit'); var_dump($exists); // bool(false)
Code language: PHP (php)
In this example, the following statement returns true because the transferTo method exists in the BankAccount class:
method_exists(BankAccount::class, 'transferTo');
Code language: PHP (php)
However, the following statement returns false because the deposit method doesn’t exist in the BankAccount class:
method_exists(BankAccount::class, 'deposit');
Code language: PHP (php)
2) Using the PHP method_exists function to check if an object has a method
The following example creates a new object of the BankAccount and uses the method_exists() function to check the object has a specified method:
class BankAccount < public function transferTo(BankAccount $other, float $amount) < // more code > > $account = new BankAccount(); $exists = method_exists($account, 'transferTo'); var_dump($exists); // bool(true) $exists = method_exists($account, 'deposit'); var_dump($exists); // bool(false)
Code language: PHP (php)
The $account object has the transferTo method, therefore, the following statement returns true :
method_exists($account, 'transferTo');
Code language: PHP (php)
On the other hand, the $account object doesn’t have the deposit method. Therefore, the following statement returns false :
method_exists($account, 'deposit');
Code language: PHP (php)
3) Using the method_exists function to check if an object has a static method
The method_exists() also returns true if a class has a static method. For example:
class BankAccount < public function transferTo(BankAccount $other, float $amount) < // more code > public static function compare(BankAccount $other): bool < // implementation // . return false; > > $exists = method_exists(BankAccount::class, 'compare'); var_dump($exists); // bool(true) $account = new BankAccount(); $exists = method_exists($account, 'compare'); var_dump($exists); // bool(true)
Code language: PHP (php)
The BankAccount has the compare static method, so the following statement returns true :
method_exists(BankAccount::class, 'compare');
Code language: PHP (php)
The $account is an instance of the BankAccount class that has the compare static method, the following expression also returns true :
$exists = method_exists($account, 'compare');
Code language: PHP (php)
PHP method_exists function in MVC frameworks
The method_exists() method is often used in Model-View-Controller (MVC) frameworks to check if a controller class has a certain method before calling it.
For example, suppose that you have the following request URI:
/posts/edit/1
Code language: PHP (php)
This URI has three parts: posts, edit, and 1.
- The posts maps to the PostsController class.
- The edit maps the edit method of the class.
- The number 1 is the post id to edit.
The PostsController class will look like the following:
class PostsController < public function edit(int $id) < // show the edit post form > >
Code language: PHP (php)
And you use the method_exists() function to check whether the edit method exists in the $controller object like this:
// . if(method_exists($controller, $action)) < $controller->$action($id); >
Code language: PHP (php)
Summary
Check if a method exists in an extended class but not parent class
How can I check that the method only exists on the current class and not parent class (ie. Tootsie )?
6 Answers 6
Since v. 4.0.5 php has get_parent_class() method, that returns parent class. So you can handle it without relflection:
class A < function a() < /* . */>function b() < /* . */>> class B extends A < function b() < /* . */>function c() < /* . */>> function own_method($class_name, $method_name) < if (method_exists($class_name, $method_name)) < $parent_class = get_parent_class($class_name); if ($parent_class !== false) return !method_exists($parent_class, $method_name); return true; >else return false; > var_dump(own_method('B', 'a')); // false var_dump(own_method('B', 'b')); // false var_dump(own_method('B', 'c')); // true
notice: This function returns false when the extending class overwrites a parent method. I’m looking for a method that returns true if a method exists in the extending class even if that method overwrites an parent method.
If you need to know if the method exists in a given child regardless the existence in a parent class you can do it like this:
$reflectionClass = new ReflectionClass($class_name); if ($reflectionClass->getMethod($method_name)->class == $class_name) < // do something >
$refl = new ReflectionClass($class_name); if($refl->hasMethod($method_name)) < //do your stuff here >
Unfortunately this seems like it suffers from the same problem as method_exists as well — «Parent methods (regardless of visibility) are also available to a ReflectionObject.» from ca3.php.net/manual/en/reflectionclass.hasmethod.php#100660
Based on the @sleepless answer above, but working in case the method doesn’t exist at all:
function methodImplementedInClass($className, $methodName) < // If this class doesn't have the method at all, return false if (!method_exists($className, $methodName)) < return false; >// Now check if the method was implemented in this class or in some parent return (new ReflectionClass($className))->getMethod($methodName)->class == $className; >
For me the question was Check if a method exists in an extended class but not parent class from the parent class
Taking the above example from Elantcev Mikhail, it would look more like this:-
class A < function a() < /* . */>function b() < /* . */>public function own_method( $method_name ) < if (method_exists($this, $method_name)) < return true; >else return false; > > class B extends A < function b() < /* . */>function c() < /* . */>> $b = new B; var_dump($b->own_method('c')); // true
Why would you want to do this?
I have a class BaseModel in which I format hints for attributes in the extended model:
class BaseModel < public function attributeHelp($attributeName) < if (method_exists($this, 'hints') && array_key_exists($attributeName, $this->hints())) < return 'hints()[$attributeName] . '">'; > return false; > >
And then in my data model
class Customer extends BaseModel < public function hints() < return [ 'customer_name' =>'please use your fullname . ', 'some other attribute' => 'some other description' ]; > >
Here’s my solution, using reflection and checking the actual class involved in the Reflection Method.
public function Extended() < >> class Child extends Base < public function ChildOnly() < >public function Extended() < >> function childMethodExists($baseClass, $childClass, $methodName) < if (!method_exists($childClass, $methodName)) < return false; // doesn't exist in the child class or base class >if (!method_exists($baseClass, $methodName)) < return true; // only exists on child class, as otherwise it would have returned above >// now to check if it is overloaded $baseMethod = new ReflectionMethod($baseClass, $methodName); $childMethod = new ReflectionMethod($childClass, $methodName); return $childMethod->class !== $baseMethod->class; > var_dump(childMethodExists(Base::class, Child::class, 'BaseOnly')); // false var_dump(childMethodExists(Base::class, Child::class, 'ChildOnly')); // true var_dump(childMethodExists(Base::class, Child::class, 'Neither')); // false var_dump(childMethodExists(Base::class, Child::class, 'Extended')); // true
Find out if a method exists in a static class
I want to check is a function exists in a library that I am creating, which is static. I’ve seen function and method_exists, but haven’t found a way that allows me to call them in a relative context. Here is a better example:
class myClass < function test1() < if(method_exists("myClass", "test1")) < echo "Hi"; >> function test2() < if(method_exists($this, "test2")) < echo "Hi"; >> function test3() < if(method_exists(self, "test3")) < echo "Hi"; >> > // Echos Hi myClass::test1(); // Trys to use 'self' as a string instead of a constant myClass::test3(); // Echos Hi $obj = new myClass; $obj->test2();
I need to be able to make test 3 echo Hi if the function exists, without needing to take it out of static context. Given the keyword for accessing the class should be ‘self’, as $this is for assigned classes.
Because I want to put this into a class that will be extended by multiple classes. I could use a magic constant to achieve this, but there should be an easier way.
3 Answers 3
static::class is available since PHP 5.5, and will return the «Late Static Binding» class name:
class myClass < public static function test() < echo static::class.'::test()'; >> class subClass extends myClass <> subClass::test() // should print "subClass::test()"
get_called_class() does the same, and was introduced in PHP 5.3
class myClass < public static function test() < echo get_called_class().'::test()'; >> class subClass extends myClass <> subClass::test() // should print "subClass::test()"
The get_class() function, which as of php 5.0.0 does not require any parameters if called within a class will return the name of the class in which the function was declared (e.g., the parent class):
class myClass < public static function test() < echo get_class().'::test()'; >> class subClass extends myClass <> subClass::test() // prints "myClass::test()"
class myClass < public static function test() < echo __CLASS__.'::test()'; >> class subClass extends myClass <> subClass::test() // prints "myClass::test()"
I was looking for a way to check if a static method exists on the parent class, and this answer led me to discover that get_parent_class() works the same way when called without any params. Thanks!
Just a note static::class does the same as get_called_class() and self::class does the same as get_class() but they are only available since PHP 5.5
Update:
Ahh, apologies. I was temporarily blind 🙂 You’ll want to use the magic constant __CLASS__
if (method_exists(__CLASS__, "test3"))
this answer seems to be the same as the question example’s test1() method using method_exists() with the class name passed as a string
The idea is that I don’t need a class name, and I can therefore put the method in any class, and it should work, whether the class has been assigned or not.
If extensibility is your goal, it should be noted that __CLASS__ , __TRAIT__ , __FILE__ , etc explicitly returns the name of the class/trait/file where the constant is used, whereas if you want to account for child objects, you will want get_class($this) for instantiated objects, or get_called_class() for static classes/methods to track inheritance. Then you can drop one function in a trait or base class and use it everywhere, thereby preventing code duplication issues, and use instanceof [trait, parent class, or interface] or method_exists() for validation without duplicate code.
Also in PHP 7+, the static::PROPERTY construct was added to simplify late static binding. Eg: return self::PROPERTY -> always returns from current class scope, return static::PROPERTY -> returns highest level declaration, honoring child class overrides of class constants, static functions, etc.