2010-07-22 52 views
5

Tôi đang cố gắng sử dụng hàm php method_exists, nhưng tôi cần kiểm tra xem phương thức tồn tại trong lớp cha của một đối tượng.method_exists trong lớp cha mẹ php

vậy:

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')) 
{ 
    /* ... */ 
} 

Nhưng không ai trong số trên đang làm việc. Tôi không chắc phải làm gì tiếp theo.

Cảm ơn bạn đã trợ giúp!

+0

Tôi tin rằng 'is_callable()' yêu cầu một cá thể lớp làm chỉ mục mảng đầu tiên, không phải là tên lớp. I E. 'if (is_callable (mảng ($ myChild, 'myFunction')))' - mặc dù để làm việc này, lớp 'Child' của bạn cần mở rộng' Parent' (như đã đề cập dưới đây). – MrWhite

+0

Bạn có cần biết nếu a) chính xác lớp cha thực hiện phương thức b) bất kỳ tổ tiên nào của một lớp đã cho thực hiện phương thức c) đối tượng của lớp dẫn xuất "có" một phương thức cụ thể d) bạn có thể gọi một phương thức cụ thể một đối tượng? – VolkerK

Trả lời

7

Lớp trẻ phải mở rộng phụ huynh trong trường hợp đó

class Parent 
{ 
    public function hello() 
    { 

    } 
} 

class Child extends Parent 
{ 

} 

$child = new Child(); 

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

Cập nhật Điều này sẽ có tác dụng tương tự như method_exists Tôi tin.

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(); 
} 

Chỉ cần cập nhật từ bài Wrikken 's

+0

Tôi quên thêm phần mở rộng, trong dự án của tôi Con không mở rộng Phụ huynh. Nó thực sự là một lớp Doctrine Base Model, nhưng trong quá trình điều tra, tôi không nghĩ rằng những gì tôi đang cố gắng làm sẽ hoạt động, vì các hàm trong các lớp mô hình Doctrine Base có vẻ hoạt động với quá tải/chặn vì không có khai báo hàm nào – Serg

+0

@Serg Nếu bạn có 'mở rộng Parent' trong mã thực tế của bạn thì biểu thức đầu tiên của bạn' if (method_exists ($ myChild, 'myFunction')) 'sẽ là đúng. (NB: Tôi đã thêm dấu ngoặc đơn đóng) – MrWhite

+0

@Serg: Có thể bạn nên thêm một ví dụ cụ thể hơn cho câu hỏi của mình và giải thích chi tiết những gì bạn đang thực sự cố gắng đạt được. – VolkerK

1

RobertPitt là đúng ở chỗ lớp Child không phải là một lớp con trừ khi nó mở rộng các lớp Parent. Nhưng từ đoạn mã ban đầu của bạn, những điều sau đây phải đúng:

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

Lưu ý 'Cha mẹ' được trích dẫn, bạn đã bỏ phiếu. Chuyển tên lớp thành một chuỗi.

4

Nếu bạn muốn biết cụ thể nếu nó tồn tại trong phụ huynh, và không chỉ trong lớp học của riêng bạn:

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

Bạn nên sử dụng API của PHP:

class Parend 
{ 
    public function myFunction() 
    { 

    } 
} 

class Child extends Parend{} 

$c = new Child(); 


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

Và nếu bạn muốn biết trong số trong đó (cha mẹ), hãy xếp loại phương thức:

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 phản chiếu có hoạt động với các đối tượng sử dụng quá tải/chặn không? – kiamlaluno

+0

AFAIK tự động (khi chạy) kiểm tra các đối tượng/lớp học, do đó sẽ có. –

+0

Không, nó sẽ không thể bắt được một hàm '__call()' (mặc dù sẽ dễ dàng kiểm tra sự tồn tại của '__call()'). Ví dụ: 'class A {function __call ($ func, $ args) {}} $ r = new ReflectionClass ('A'); var_dump ($ r-> hasMethod'thisRandomFunctionWorks '));' output false, mặc dù hàm có thể được gọi là. – Wrikken

1

Method_exists và get_parent_class kết hợp cũng sẽ hoạt động nếu được thực hiện trong lớp con?

Ví dụ

class Parent 
{ 

} 

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

Các excample:. if (method_exists ('Chánh', 'myFunction') không hoạt động trong PHP 5.3.5 nếu bạn muốn kiểm tra cho một constructor mẹ

Nhưng điều này đã làm việc cho tôi:

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

nó gọi Constructor Chánh chỉ khi nó tồn tại trong lớp cha mẹ

Các vấn đề liên quan