Làm thế nào để các bộ lọc và hook thực sự hoạt động trong PHP


21

Làm thế nào để các bộ lọc và hook thực sự hoạt động trong WordPress?

Tôi đang hỏi về một cái gì đó tiên tiến. Nó được triển khai như thế nào trong PHP? Ví dụ: làm thế nào để nó thu thập tất cả các hook từ các plugin khác nhau và "gắn" chúng vào các hook core, v.v.


2
Theo như tôi biết thì không có 'hook' hay 'filter' trong php, có các hàm. Wordpress có các chức năng đặc biệt mà trước khi thực thi chúng sử dụng gọi lại các chức năng khác.
Ofir Baruch


3
@OfirBaruch, tôi khá chắc chắn rằng OP đã đề cập đến việc triển khai của họ trong WordPress và không gợi ý rằng có một số triển khai PHP gốc.
Tom Auger

Câu trả lời:


33

Tổng quan

Về cơ bản " API Plugin ", triệu tập các Bộ lọc và Móc, bao gồm các chức năng sau:

  1. apply_filters()- thực hiện
  2. do_action- thực hiện
  3. apply_filters_ref_array()- thực hiện
  4. do_action_ref_array()- thực hiện
  5. add_filter()- thêm vào ngăn xếp
  6. add_action()- thêm vào ngăn xếp

Thực tập cơ bản

Nhìn chung, có một vài thế giới (những gì khác trong thế giới WordPress) có liên quan:

global $wp_filter, $wp_actions, $wp_current_filter, $merged_filters;

Cái đầu tiên $wp_filterlà một toàn cục Arraychứa tất cả các tên bộ lọc dưới dạng các phần tử con. Mỗi phân đoạn đó sau đó giữ nhiều phân đoạn hơn nữa là các cuộc gọi lại được triệu tập dưới một mảng ưu tiên.

Tóm tắt chuyên sâu

Vì vậy, khi một hàm thực thi được gọi, WordPress sẽ tìm kiếm các mảng toàn cục cho các khóa có tên đó. Sau đó, các cuộc gọi lại đính kèm được thực hiện ưu tiên sau ưu tiên. Điều duy nhất xảy ra ở phía trước là các cuộc gọi lại được gắn vào allbộ lọc.

Khi bạn thêm một cuộc gọi lại bằng cách sử dụng add_actionhoặc add_filter, thì trước tiên WordPress sẽ tính ID "duy nhất" để không ghi đè lên các cuộc gọi lại đã được đính kèm.

$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);

Sau đó, nó thêm cuộc gọi lại của bạn vào global $wp_filterngăn xếp:

$wp_filter[ $tag ][ $priority ][ $idx ] = array(
    'function'      => $function_to_add,
    'accepted_args' => $accepted_args
);

Như bạn có thể thấy mảng phụ chính là $tag(hoặc tên hành động / bộ lọc), sau đó mọi thứ được triệu tập theo một mức độ ưu tiên cụ thể và sau đó chuỗi gọi lại / ID "duy nhất" được sử dụng làm khóa.

Sau đó, khi một bộ lọc được gọi - xảy ra với $tag/ action- / tên bộ lọc - mảng được tìm kiếm và các cuộc gọi lại được gọi. Vì nó đang sử dụng call_user_func_arraynên thực sự có bao nhiêu đối số được đính kèm. WordPress tự giải quyết điều đó.

foreach ( (array) current( $wp_filter[ $tag ] ) as $the_ )
{
    call_user_func_array(
        $the_['function'], 
        array_slice(
            $args, 
            0, 
            (int) $the_['accepted_args']
        )
    );
}

3
đừng quên rằng khi nó đi qua các cuộc gọi lại, nó ra lệnh thực hiện nhiều cuộc gọi lại trên cùng một hook bằng cách sử dụng "mức độ ưu tiên" của chúng, được đặt (tùy chọn) với add_action () và application_filters () và mặc định là 10.
Tom Auger

1
@TomAuger Xin vui lòng thêm bất kỳ ghi chú và chỉnh sửa bổ sung nào cho câu trả lời.
kaiser

5

Móc được bao gồm trong cả tệp lõi WordPress và một số tệp chủ đề gốc. Chúng cho phép bạn nối vào nội dung ở một vị trí cụ thể trong tệp.

Một ví dụ là hook wp_head trong WordPress. Bạn có thể sử dụng móc này trong chủ đề con của bạn để thêm nội dung vào vị trí đó '

Thí dụ:

add_action('wp_head', 'add_content_to_head');
function add_content_to_head() {
echo 'Your Content';
}

Một số chủ đề cao cấp cũng bao gồm các móc hành động mà bạn có thể sử dụng trong một chủ đề con để làm điều tương tự. Đây là bản đồ trực quan bao gồm tất cả các móc hành động và vị trí chúng xuất nội dung của bạn trong khung chủ đề Genesis.

Thí dụ:

add_action('genesis_header', 'add_content_to_header');
function add_content_to_header() {
echo 'Your Content';
}

Đây là cái móc trông như thế nào nếu bạn mở tệp header.php trong khung chủ đề Genesis:

do_action( 'genesis_header' );

Dưới đây là danh sách các móc WordPress mà bạn có thể sử dụng theo nhiều cách.

Các bộ lọc cho phép bạn sửa đổi đầu ra của một chức năng hiện có và được bao gồm trong cả các tệp cốt lõi của WordPress và một số khung chủ đề gốc như Genesis.

Dưới đây là danh sách các bộ lọc bạn có thể sử dụng với Genesis Design Framework

Dưới đây là danh sách các bộ lọc có trong WordPress

Đây là một ví dụ về cách bạn có thể sử dụng bộ lọc trong khung chủ đề như Genesis:

add_filter( 'comment_author_says_text', 'custom_comment_author_says_text' );
function custom_comment_author_says_text() {
return 'author says';
}

Đoạn mã trên có thể được sử dụng trong một chủ đề con để sửa đổi tác giả nói văn bản trong các bình luận của bạn. Nó hoạt động trong bất kỳ chủ đề.

Đây là một ví dụ khác tùy chỉnh độ dài đoạn trích thành 50 từ:

add_filter( 'excerpt_length', 'change_excerpt_length' );
function change_excerpt_length($length) {
return 50; 
}

Bạn sẽ tìm thấy hàm the_excerpt () trong tệp wp-gồm / post-template.php.

Đây là những gì nó trông giống như:

  function the_excerpt() {
        echo apply_filters('the_excerpt', get_the_excerpt());
}

Bạn cũng có thể sử dụng các hook và bộ lọc trong plugin để thực hiện chính xác điều tương tự và mã sẽ không bị mất khi bạn cập nhật chủ đề gốc hoặc WordPress.

Về cơ bản, hook và bộ lọc cho phép bạn tùy chỉnh và sửa đổi cả WordPress và chủ đề gốc mà không cần chỉnh sửa các tệp WordPress cốt lõi hoặc các tệp chủ đề gốc của bạn.

Dễ dàng hơn đáng kể để tùy chỉnh một chủ đề con khi khung chủ đề gốc bao gồm các móc và bộ lọc vì bạn không bao giờ cần phải chỉnh sửa các tệp mẫu chủ đề gốc. Bằng cách này bạn có thể thay đổi chủ đề một cách an toàn là tốt.


2
Đây là một tổng quan tuyệt vời về hook và bộ lọc, nhưng tôi sợ hoàn toàn bỏ lỡ câu hỏi của OP, đó là về nội bộ về cách hook hoạt động và cách WordPress tạo, lưu trữ và xử lý chúng. Câu trả lời chính xác; bạn có thể nên liên kết đến hướng dẫn của bạn trên trang web WP.
Tom Auger

Ok tôi sẽ xóa nó. Thật tệ vì tôi nên đọc câu hỏi tốt hơn nhưng nghĩ rằng câu trả lời đã được đưa ra sẽ dễ hiểu hơn cho người mới bắt đầu nếu họ biết cơ bản trước.
Brad Dalton

2
Brad, tôi đã hoàn tác nó vì tôi nghĩ nó cũng hữu ích khi có thông tin đó ở đây. Nếu bạn không đồng ý, chỉ cần đề cập / ping tôi ở đây và tôi sẽ xóa nó một lần nữa.
kaiser
Licensed under cc by-sa 3.0 with attribution required.