2009-02-10 25 views

Trả lời

11

Đây là số bit trễ, nhưng tôi chỉ muốn chỉ ra rằng kể từ PHP 5.3, nó thực sự có thể ghi đè lên các chức năng nội bộ mà không cần sử dụng phần mở rộng PHP.

Bí quyết là bạn có thể xác định lại hàm PHP bên trong bên trong vùng tên. Nó dựa trên cách PHP giải quyết tên cho các chức năng:

Không gian tên bên trong (nói A \ B), các cuộc gọi đến các chức năng không đủ tiêu chuẩn được giải quyết trong thời gian chạy. Sau đây là cách gọi hàm foo() được giải quyết:

  1. Tìm một hàm từ không gian tên hiện tại: A \ B \ foo().
  2. Nó cố gắng tìm và gọi hàm toàn cục foo()
+0

Tốt, tại sao câu trả lời này không được chấp nhận? – Pacerier

+1

Rất có thể, vì nó được đăng gần bốn năm sau câu hỏi và câu trả lời được chấp nhận có lẽ là câu trả lời phù hợp nhất vào thời điểm đó. –

+0

Tôi vẫn ở trên SO ... Đã chấp nhận! –

9

Không, nó không thể làm được điều này như bạn mong đợi.

Từ manual:

PHP không hỗ trợ chức năng quá tải, cũng không phải là nó có thể undefine hoặc xác định lại chức năng trước đó tuyên bố.

Tuy nhiên, bạn có thể sử dụng runkit_function_redefine và anh em họ của nó, nhưng nó chắc chắn không phải là rất thanh lịch ...

Bạn cũng có thể sử dụng create_function để làm một cái gì đó như thế này:

<?php 
$func = create_function('$a,$b','return $a + $b;'); 
echo $func(3,5); // 8 
$func = create_function('$a,$b','return $a * $b;'); 
echo $func(3,5); // 15 
?> 

Như với runkit, nó không phải là rất thanh lịch, nhưng nó mang lại cho hành vi bạn đang tìm kiếm.

+0

Bạn đã nói nó hai lần, nhưng tại sao nó "không phải là rất thanh lịch"? – Pacerier

+0

@Pacerier: Vâng, để bắt đầu, nó là một chút của một mùi mã để muốn làm điều này để bắt đầu, và nó chắc chắn sẽ ném ra bất cứ ai đến phía sau bạn để xem mã của bạn, nhưng nếu bạn có được quá khứ rằng bạn phải nhập mã chức năng dưới dạng đối số chuỗi trong cả hai trường hợp, điều này khó coi đối với bất kỳ điều gì ngoài các hàm ngắn nhất. –

+0

Chắc chắn chúng ta ít nhất là trên PHP 5.3, không ai làm String nữa, mã chức năng có thể được cung cấp như một hàm ẩn danh. – Pacerier

5

Tôi nhận thấy câu hỏi này hơi cũ, nhưng Patchwork là dự án PHP 5.3 được phát hành gần đây hỗ trợ định nghĩa lại các hàm do người dùng xác định. Mặc dù, như tác giả đề cập, bạn sẽ cần phải sử dụng đến runkit hoặc php-test-helpers để các chức năng lõi/thư viện vá lỗi khỉ.

+2

Rất ít lib tốt đẹp. Cảm ơn bạn đã chia sẻ :) –

1

Như jmikola đã đề cập, chắp vá là một giải pháp tốt nếu bạn muốn thêm mã vào hàm.

Dưới đây là một bài viết về cách hoạt động: http://phpmyweb.net/2012/04/26/write-an-awesome-plugin-system-in-php/

Nó đi kèm với một số mẫu mã. Tôi nghĩ rằng phiên bản phpmyweb sử dụng một mã tốt hơn một chút, bởi vì anh ta không sử dụng mã eval() ', không giống như chắp vá. Bạn có thể cache opcodes khi sử dụng eval().

+0

tại sao bạn cần phải lo lắng về bộ nhớ cache opcode khi bạn đang thử nghiệm đơn vị? Hoặc những gì ... bạn đang sử dụng khỉ vá cho một cái gì đó khác hơn là thử nghiệm ?? trong trường hợp đó bạn có vấn đề lớn hơn 'eval()' để lo lắng. – Spudley

+1

@Spudley Rõ ràng là bài viết tôi đăng không nhằm mục đích thử nghiệm đơn vị (do đó tiêu đề "Viết một hệ thống plugin tuyệt vời"). Anh ấy chỉ hiển thị một cách khác để tạo kiến ​​trúc plugin. Và anh ấy cũng nói rằng anh ấy chỉ muốn thể hiện một cách khác để tạo ra một kiến ​​trúc như vậy. Ofcourse, nó lên để thảo luận nếu nó là một cách tốt. Mặc dù tôi không thấy bất kỳ vấn đề với nó. --- Bạn đang làm gì? Giống như tác giả cho biết, bộ nhớ đệm opcode không phải là một vấn đề vì eval() không được sử dụng ở tất cả (không giống như chắp vá). – Vivendi

+0

@Vivendi, Việc chắp vá có sử dụng các hàm runkit trong nội bộ không? – Pacerier

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