Reputation: 2781
With method_exists
, it checks all methods, including the parent class.
Example:
class Toot {
function Good() {}
}
class Tootsie extends Toot {
function Bad() {}
}
function testMethodExists() {
// true
var_dump(method_exists('Toot', 'Good'));
// false
var_dump(method_exists('Toot', 'Bad'));
// true
var_dump(method_exists('Tootsie', 'Good'));
// true
var_dump(method_exists('Tootsie', 'Bad'));
}
How can I check that the method only exists on the current class and not parent class (ie. Tootsie
)?
Upvotes: 13
Views: 6209
Reputation: 13071
Here's my solution, using reflection and checking the actual class involved in the Reflection Method.
<?php
class Base {
public function BaseOnly() {
}
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
Upvotes: 0
Reputation: 1423
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;
}
Upvotes: 2
Reputation: 1789
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
}
Upvotes: 7
Reputation: 631
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 '<i html for nicely formatted hint'
. $this->hints()[$attributeName]
. '"></i>';
}
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'
];
}
}
Upvotes: 0
Reputation: 174
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
Upvotes: 5
Reputation: 315
you can use reflection
$refl = new ReflectionClass($class_name);
if($refl->hasMethod($method_name)){
//do your stuff here
}
for more information ReflectionClass
Upvotes: 2