2010-07-22 2 views
5

Я пытаюсь использовать функцию php function_exists, но мне нужно проверить, существует ли метод в родительском классе объекта.method_exists в родительском классе php

так:

class Parent 
{ 
    public function myFunction() 
    { 
     /* ... */ 
    } 
} 

class Child extends Parent 
{ 
    /* ... */ 
} 

$myChild = new Child(); 

if (method_exists($myChild, 'myFunction')) 
{ 
    /* ... */ 
} 

if (method_exists(Parent, 'myFunction')) 
{ 
    /* ... */ 
} 

if (is_callable(array('Parent', 'myFunction')) 
{ 
    /* ... */ 
} 

Но ни один из вышеперечисленных не работают. Я не уверен, что попробовать дальше.

Спасибо за помощь!

+0

Я считаю, что 'is_callable()' требует, чтобы экземпляр класса был первым индексом массива, а не именем класса. то есть. 'if (is_callable (array ($ myChild, 'myFunction')))' - хотя для этого для работы ваш класс 'Child' должен расширять« Parent »(как указано ниже). – MrWhite

+0

Вам нужно знать, если: а) именно родительский класс реализует метод; б) любой предок данного класса реализует метод; в) объект производного класса «имеет» конкретный метод; г) вы можете вызвать конкретный метод для объект? – VolkerK

ответ

7

ребенок Класс должен расширять родителя в этом случае

class Parent 
{ 
    public function hello() 
    { 

    } 
} 

class Child extends Parent 
{ 

} 

$child = new Child(); 

if(method_exists($child,"hello")) 
{ 
    $child->hello(); 
} 

Update Это будет иметь тот же эффект, как method_exists я считаю.

function parent_method_exists($object,$method) 
{ 
    foreach(class_parents($object) as $parent) 
    { 
     if(method_exists($parent,$method)) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

if(method_exists($child,"hello") || parent_method_exists($object,"hello")) 
{ 
    $child->hello(); 
} 

Просто обновляется с поста Wrikken «s

+0

Я забыл добавить часть extends, в моем проекте Child продлевает Parent. Это на самом деле класс базовой модели Doctrine, но при дальнейшем исследовании я не думаю, что то, что я пытаюсь сделать, будет работать, поскольку функции в классах модели Doctrine Base, похоже, работают с перегрузкой/перехватом, поскольку нет видимых объявлений функций – Serg

+0

@Serg Если у вас есть 'extends Parent' в вашем фактическом коде, тогда ваше первое выражение' if (method_exists ($ myChild, 'myFunction')) 'будет true. (NB: я добавил закрывающую скобку) – MrWhite

+0

@Serg: Может быть, вам следует добавить более конкретный пример вашего вопроса и подробно объяснить, чего вы на самом деле пытаетесь достичь. – VolkerK

1

RobertPitt является правильным в том, что Child класс не является классом ребенка, если он не расширяет Parent класс. Но из исходного фрагмента кода, следующий должен быть правдой:

if (method_exists('Parent', 'myFunction') 
{ 
    // True 
} 

Обратите внимание на «Родитель» в кавычках, вы должны были это без кавычек. Передача имени класса в виде строки.

4

Если вы хотите конкретно знать, если он существует в родителя, а не только в своем собственном классе:

foreach(class_parents($this) as $parent){ 
    if(method_exists($parent,$method){ 
     //do something, for instance: 
     parent::$method(); 
     break; 
    } 
} 
9

Вы должны использовать РНР API:

class Parend 
{ 
    public function myFunction() 
    { 

    } 
} 

class Child extends Parend{} 

$c = new Child(); 


$rc = new ReflectionClass($c); 
var_dump($rc->hasMethod('myFunction')); // true 

И если вы хотите узнать в , который (родительский) класс живет:

class Child2 extends Child{} 

$c = new Child2(); 
$rc = new ReflectionClass($c); 

while($rc->getParentClass()) 
{ 
    $parent = $rc->getParentClass()->name; 
    $rc = new ReflectionClass($parent); 
} 
var_dump($parent); // 'Parend' 
+0

Работает ли API отражения также с объектами, использующими перегрузку/перехват? – kiamlaluno

+0

AFAIK динамически (во время выполнения) проверяет объекты/классы, чтобы это было да. –

+0

Нет, он не сможет поймать функцию '__call()' (хотя было бы легко проверить существование '__call()'). Ex: 'class A {function __call ($ func, $ args) {}} $ r = new ReflectionClass ('A'); var_dump ($ r-> hasMethod'thisRandomFunctionWorks '));' выводит false, хотя функция может называться. – Wrikken

1

Не будет ли метод method_exists и get_parent_class работать, если это делается в дочернем классе?

Например

class Parent 
{ 

} 

class Child extends Parent 
{ 
    public function getConfig() 
    { 
    $hello = (method_exists(get_parent_class($this), 'getConfig')) ? parent::getConfig() : array(); 
    } 
} 
0

excample:. если (method_exists ('Parent', 'туРипсЫоп') не работает в PHP 5.3.5, если вы хотите, чтобы проверить родительский конструктор

Но это работает для меня:

class Child extends Parent { 
    function __construct($argument) { 
    if(method_exists(get_parent_class(),"__construct")) parent::__construct($argument) 
    } 
} 

он называет родительский конструктор, только если он существует в родительском классе

Смежные вопросы