Я не понимаю, как работает этот параметр..?


Хорошо, у меня есть этот простой код для простого плагина, который предваряет заголовки сообщений словом ТЕСТИРОВАНИЕ.. Мне действительно непонятно, как здесь работает этот параметр. Я понимаю, как работают параметры в PHP, но внутри этого параметра ничего не было передано для WordPress, чтобы знать, что переменная - это название.. если это имеет смысл?? Не понимаю, как это работает.

Я все еще довольно плохо разбираюсь в разработке WordPress - мне всегда кажется, что я начинаю, застреваю и не очень далеко.

add_filter('the_title', 'cm_title');

/**
* Modify the title prepending the article title with the word 'TESTING'
*/

function cm_title($text) {

return 'TESTING  ' . $text;

}
Author: Howdy_McGee, 2015-03-10

2 answers

Давайте посмотрим, сможем ли мы разбить его так, чтобы его было легко понять.

У вас есть функция PHP с именем 'cm_title':

function cm_title($text) {
   return 'TESTING  ' . $text;
}

Он делает только 1 вещь. Он берет то, что ему дано, "$text", и возвращает этот $текст со словами "Тестирование", добавленными к нему.

Как WordPress узнает, что такое "$text"?

Он знает/присваивает данные параметру $text из-за этого фильтра WP:

add_filter('the_title', 'cm_title');

Этот фильтр проверяется WP при создании "the_title". Так что как раз перед тем, как WP выплевывает "the_title", он проверяет, есть ли фильтр для использования. В этом случае мы просим WP применить этот фильтр (функцию "cm_title"), прежде чем выплевывать заголовок.

Все, что можно сказать, WP отправляет то, что у него есть до сих пор, для "the_title" (т. Е. "Это пост обо мне") и пропускает его через этот фильтр, прежде чем выплюнуть.

Таким образом, в данном случае "Это сообщение обо мне" - это данные в параметре $text в функции cm_title.

Ваш конечный результат становится "ПРОВЕРКА, это пост обо мне".

Помогает ли это прояснить ситуацию?

 1
Author: Sean Grant, 2015-03-10 20:45:09

WordPress использует крючки , чтобы помочь разработчикам делать то, что им нужно, относительно простым способом. Некоторые из этих крючков apply_filter() и do_action(), которые определяются WordPress. Давайте посмотрим, что именно произойдет, когда мы вызовем the_title() до тех пор, пока он не попадет на определенный вами крючок.

<?php the_title(); ?>

Ресурсы разработчика - the_title()

function the_title($before = '', $after = '', $echo = true) {
    $title = get_the_title();

    if ( strlen($title) == 0 )
        return;

    $title = $before . $title . $after;

    if ( $echo )
        echo $title;
    else
        return $title;
}

Прямо вверху он вызывает get_the_title(), где мы найдем наш фильтр. Давайте взглянем на это:

Разработчик Ресурсы - get_the_title()

function get_the_title( $post = 0 ) {
    $post = get_post( $post );

    $title = isset( $post->post_title ) ? $post->post_title : '';
    $id = isset( $post->ID ) ? $post->ID : 0;

    if ( ! is_admin() ) {
        if ( ! empty( $post->post_password ) ) {

            /**
             * Filter the text prepended to the post title for protected posts.
             *
             * The filter is only applied on the front end.
             *
             * @since 2.8.0
             *
             * @param string  $prepend Text displayed before the post title.
             *                         Default 'Protected: %s'.
             * @param WP_Post $post    Current post object.
             */
            $protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s' ), $post );
            $title = sprintf( $protected_title_format, $title );
        } else if ( isset( $post->post_status ) && 'private' == $post->post_status ) {

            /**
             * Filter the text prepended to the post title of private posts.
             *
             * The filter is only applied on the front end.
             *
             * @since 2.8.0
             *
             * @param string  $prepend Text displayed before the post title.
             *                         Default 'Private: %s'.
             * @param WP_Post $post    Current post object.
             */
            $private_title_format = apply_filters( 'private_title_format', __( 'Private: %s' ), $post );
            $title = sprintf( $private_title_format, $title );
        }
    }

    /**
     * Filter the post title.
     *
     * @since 0.71
     *
     * @param string $title The post title.
     * @param int    $id    The post ID.
     */
    return apply_filters( 'the_title', $title, $id );
}

Вы заметите прямо внизу функции, которую она вызывает apply_filters() и передает в function_name в виде строки , $title как строка и $id как int затем возвращает все, что возвращает apply_fitlers(), что является вашим крючком. Давайте взглянем на apply_filters():

Ресурсы разработчика - apply_filters()

function apply_filters( $tag, $value ) {
    global $wp_filter, $merged_filters, $wp_current_filter;

    $args = array();

    // Do 'all' actions first.
    if ( isset($wp_filter['all']) ) {
        $wp_current_filter[] = $tag;
        $args = func_get_args();
        _wp_call_all_hook($args);
    }

    if ( !isset($wp_filter[$tag]) ) {
        if ( isset($wp_filter['all']) )
            array_pop($wp_current_filter);
        return $value;
    }

    if ( !isset($wp_filter['all']) )
        $wp_current_filter[] = $tag;

    // Sort.
    if ( !isset( $merged_filters[ $tag ] ) ) {
        ksort($wp_filter[$tag]);
        $merged_filters[ $tag ] = true;
    }

    reset( $wp_filter[ $tag ] );

    if ( empty($args) )
        $args = func_get_args();

    do {
        foreach( (array) current($wp_filter[$tag]) as $the_ )
            if ( !is_null($the_['function']) ){
                $args[1] = $value;
                $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
            }

    } while ( next($wp_filter[$tag]) !== false );

    array_pop( $wp_current_filter );

    return $value;
}

Это выглядит сложным, но прежде чем мы перейдем к этому, давайте перейдем к самой важной части этой функции, $wp_filter. Теперь этот маленький засранец содержит ВСЕ фильтры, добавленные как вами, так И WordPress. Вы можете распечатать его прямо под своим wp_head(), чтобы увидеть полный список. Это выглядит примерно так (тонны больше, я только что выбрал the_title, так как это по теме!)

[the_title] => Array
    (
        [10] => Array
            (
                [wptexturize] => Array
                    (
                        [function] => wptexturize
                        [accepted_args] => 1
                    )

                [convert_chars] => Array
                    (
                        [function] => convert_chars
                        [accepted_args] => 1
                    )

                [trim] => Array
                    (
                        [function] => trim
                        [accepted_args] => 1
                    )

            )

        [11] => Array
            (
                [capital_P_dangit] => Array
                    (
                        [function] => capital_P_dangit
                        [accepted_args] => 1
                    )

            )

    )

Таким образом, это многомерный массив фильтров, индексированный тегом , затем приоритетом и, наконец, именем функции . Довольно аккуратно, я думаю! Фильтр, который вы добавили, так как вы не передали приоритет, является по умолчанию индексируется 10 и будет добавлен прямо под trim, а затем дополнительно проиндексирован по имени функции cm_title.

Давайте немного вернемся назад. Если мы посмотрим на конец функции get_the_title() выше, мы увидим, что она передает три переменные в функцию apply_filters, но, как мы ясно видим, она принимает только два параметра! Мне пришлось немного вникнуть в это, и похоже, что эта маленькая функция func_get_args(), которую мы видим замусоренной внутри apply_filters(), на самом деле захватит все, что угодно и все перешло к нему. Вот пример, кодовый ключ также хорош. Теперь, несмотря на то, что все может быть передано, если мы вернемся к нашему многомерному массиву, там есть параметры accepted_args, так что технически вы вроде как не можете, хотя это позволяет вам это сделать.

ФУ

Наконец, он проходит через каждый из этих фильтров, используя массив $wp_filters:

do {
    foreach( (array) current($wp_filter[$tag]) as $the_ )
        if ( !is_null($the_['function']) ){
            $args[1] = $value;
            $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
        }

} while ( next($wp_filter[$tag]) !== false );

Итак, давайте соберем все это вместе!

  • the_title() вызовы get_the_title()
  • get_the_title() возвращает apply_filters(), передавая: 'the_title' (имя функции), $title (заголовок строки), $id (идентификатор записи int).
  • apply_filters() просматривает глобальный массив, содержащий все добавленные фильтры, затем запускает их, передавая информацию, которая была передана ему ($title, и $id ).

Функция, которую вы вызываете add_filter, фактически добавляет ваше имя функции, приоритет и аргументы в глобальный массив $wp_filters. Вы можете увидеть это ниже:

Разработчик Ресурсы - add_filter()

function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
    global $wp_filter, $merged_filters;

    $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
    $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
    unset( $merged_filters[ $tag ] );
    return true;
}

Действительно, это вызывается до того, как the_title() когда-либо будет вызван. Ваши функции загружаются с помощью wp_head(), и поэтому любые фильтры, которые вы добавляете с помощью плагинов или functions.php, также будут добавлены в этот глобальный массив.


Это было длинно, но, надеюсь, теперь это имеет немного больше смысла, если у вас есть какие-либо вопросы, задавайте в комментариях!

 2
Author: Howdy_McGee, 2017-05-23 12:40:07