2008-09-16 69 views
7

Có thể trong PHP (as it is in C++) để khai báo một class method NGOÀI class definition?phương pháp lớp Định nghĩa trong PHP

+1

Theo như tôi biết những gì bạn đang yêu cầu là không thể trong C++. Bạn có thể muốn làm rõ. – erlando

+0

Trong C++, bạn có thể định nghĩa các hàm bên ngoài lớp và nếu tham số đầu tiên thuộc loại lớp đó, thì bạn sẽ có được những gì trông giống như một quá tải (tức là "rõ ràng" này "). Phương pháp này được sử dụng cho những thứ như toán tử << của std :: cout, ví dụ. Thật không may, PHP không nhận ra một loại khi gọi một hàm. Số lượng tham số là thứ duy nhất có thể sử dụng để phân biệt giữa các hàm PHP. Bản thân hàm có thể kiểm tra kiểu tham số và hành động khác nhau theo nó, nhưng hai hàm có cùng tên và cùng một số tham số là một cái gì đó bất hợp pháp trong PHP. –

Trả lời

1

số

Bạn có thể mở rộng các lớp học tuyên bố trước đó, tuy nhiên, nếu điều đó giúp.

8

Không, kể từ PHP 5.2. Tuy nhiên, bạn có thể sử dụng phương thức ma thuật __call để chuyển tiếp cuộc gọi đến hàm hoặc phương thức tùy ý.

class A { 

    public function __call($method, $args) { 
     if ($method == 'foo') { 
      return call_user_func_array('bar', $args); 
     } 
    } 

} 

function bar($x) { 
    echo $x; 
} 

$a = new A(); 
$a->foo('12345'); // will result in calling bar('12345') 

Trong PHP 5.4 có hỗ trợ cho đặc điểm. Trait là một cách thực hiện các phương thức mà không thể được khởi tạo như một đối tượng độc lập. Thay vào đó, đặc điểm có thể được sử dụng để mở rộng lớp với triển khai có chứa. Tìm hiểu thêm về Traits here.

0

Không có điều gì là không thể thực hiện được. nếu bạn định nghĩa hàm/phương thức bên ngoài lớp, nó sẽ trở thành hàm toàn cục.

+0

Tất cả các hàm được định nghĩa bên ngoài một lớp không phải là toàn cục. Nếu bạn lưu hàm trong một biến, thì nó không phải là toàn cục. ('$ func = function() {...};') –

3

Bạn có thể ghi đè lên __call or __callStatic để định vị phương thức bị thiếu trong thời gian chạy, nhưng bạn phải tạo hệ thống của riêng mình để định vị và gọi mã. Ví dụ, bạn có thể tải một lớp "Delegate" để xử lý cuộc gọi phương thức.

Đây là một ví dụ - nếu bạn cố gắng gọi $ foo-> bar(), lớp sẽ cố tạo lớp FooDelegate_bar và thanh cuộc gọi() trên đó với cùng các đối số. Nếu bạn đã thiết lập tự động tải lớp, đại biểu có thể sống trong một tệp riêng cho đến khi được yêu cầu ...

class Foo { 

    public function __call($method, $args) { 
     $delegate="FooDelegate_".$method; 
     if (class_exists($delegate)) 
     { 
      $handler=new $delegate($this); 
      return call_user_func_array(array(&$handler, $method), $args); 
     } 


    } 

} 
0

C++ cũng không thể làm điều này. Bạn đã kết hợp tuyên bố với de finition?

0

Không, như mọi người đã nói, điều đó là không thể.

Tuy nhiên, bạn có thể làm something like this để mô phỏng kết hợp trong PHP hoặc thêm phương thức vào lớp khi chạy, gần đúng như bạn sắp nhận được. Về cơ bản, nó chỉ sử dụng các mẫu thiết kế để đạt được chức năng tương tự. Zope 3 thực hiện một cái gì đó tương tự như mô phỏng mixins trong Python, một ngôn ngữ khác không hỗ trợ chúng trực tiếp.

+0

Câu lệnh của bạn về Python là không chính xác, vì Python hỗ trợ đa kế thừa, và thực sự hỗ trợ định nghĩa các phương thức trên thời gian chạy. – lkraider

5

Có thể thêm phương thức vào lớp PHP sau khi được xác định. Bạn muốn sử dụng classkit, tiện ích mở rộng "thử nghiệm". Dường như phần mở rộng này không được kích hoạt theo mặc định, do đó, nó phụ thuộc vào việc bạn có thể biên dịch một tệp nhị phân PHP tùy chỉnh hoặc tải PHP DLL nếu trên các cửa sổ (ví dụ: Dreamhost không cho phép các tệp nhị phân PHP tùy chỉnh và chúng dễ thiết lập).

<?php 
class A { } 
classkit_method_add('A', 'bar', '$message', 'echo $message;', 
    CLASSKIT_ACC_PUBLIC); 
$a = new A(); 
$a->bar('Hello world!'); 

Ví dụ từ cuốn hướng dẫn PHP:

<?php 
class Example { 
    function foo() { 
     echo "foo!\n"; 
    } 
} 

// create an Example object 
$e = new Example(); 

// Add a new public method 
classkit_method_add(
    'Example', 
    'add', 
    '$num1, $num2', 
    'return $num1 + $num2;', 
    CLASSKIT_ACC_PUBLIC 
); 

// add 12 + 4 
echo $e->add(12, 4); 
+0

Lưu ý rằng điều này đòi hỏi một phần mở rộng PECL mà mọi người không tự động có trên máy chủ của họ. Ngoài ra, nó bây giờ được gọi là runkit thay thế. http://www.php.net/manual/en/function.runkit-method-add.php –

1

Như PHP 5.3 hỗ trợ đóng cửa, bạn có thể tự động xác định phương pháp dụ như biến giữ đóng cửa:

$class->foo = function (&$self, $n) { 
    print "Current \$var: " . $self->var . "\n"; 
    $self->var += $n; 
    print "New \$var:  " .$self->var . "\n"; 
}; 

Lấy $self (bạn có thể' t sử dụng $this ngữ cảnh đối tượng bên ngoài) làm tham chiếu (&), bạn có thể sửa đổi cá thể.

Tuy nhiên, sự cố xảy ra khi bạn cố gắng để gọi hàm thông thường:

$class->foo(2); 

Bạn nhận được một lỗi nghiêm trọng. PHP nghĩ rằng foo là một phương pháp $class, vì cú pháp. Ngoài ra, bạn phải vượt qua ví dụ như đối số đầu tiên.

Có may mắn là một chức năng đặc biệt để gọi chức năng theo tên gọi call_user_func:

call_user_func($class->foo, &$class, 2); 
# => Current $var: 0 
# => New $var:  2 

Chỉ cần nhớ để đặt & trước khi biến ví dụ.

gì thậm chí còn dễ dàng hơn là nếu bạn sử dụng __call magic method:

class MyClass { 
    public function __call ($method, $arguments) { 
    if (isset($this->$method)) { 
     call_user_func_array($this->$method, array_merge(array(&$this), $arguments)); 
    } 
    } 
} 

Bây giờ bạn có thể gọi $class->foo(2) để thay thế. Phương thức ma thuật __call bắt cuộc gọi đến một phương thức không xác định và gọi kết thúc bằng biến số $class->foo có cùng tên với phương thức được gọi.

Tất nhiên, nếu $class->var là riêng tư, việc đóng trong lưu trữ trong biến số $class->foo sẽ không thể truy cập được.

+0

Lưu ý rằng việc sử dụng & khi gọi một hàm không hợp pháp trong PHP. Nó đã được chấp nhận một lúc trở lại (có lẽ cần thiết trong PHP 4) nhưng ngày nay bạn nhận được cảnh báo hoặc lỗi khi bạn chạy mã đó 'call_user_func ($ class-> foo, & $ class, 2);'. –

+0

Tôi biết. Nó là cần thiết trước – jocap

+0

Và hơn nữa, trong các phiên bản PHP mới nhất, bạn có thể sử dụng $ này trong bao đóng. – jocap

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