Реализация расширенных оболочек функций добавления *


add_action() и add_filter() являются основными функциями. Однако в некоторых сценариях добавьте еще одну функцию и закрепите ее где-нибудь подход становится громоздким и неудобным.

Я определил для себя несколько вариантов использования, которые могут упростить код с помощью оболочек поверх функций add_*. Вещи, которые лучше обрабатываются с помощью одного вкладыша, чем дополнительные функции каждый раз.

  1. Добавьте произвольный возврат фильтра. Уже есть __return_* функции, но они очень ограничены по определению. Почему бы просто не передать то, что вы хотите вернуть в фильтре. Спасает от множества function return_stuff(){return 'stuff';}

  2. Замените X на Y в фильтре. Спасает от множества function replace_stuff(){return str_replace();}

  3. Добавьте действие с произвольными аргументами. Действия срабатывают с аргументами, переданными в крючок. Но иногда вас это не волнует, и вы просто хотите запустить свою функцию со своими собственными аргументами на определенном крючке. Спасает от множества function echo_stuff(){echo 'stuff'}; и больше.

Итак...

  • Существуют ли какие-либо другие варианты использования, которые вы хотите и/или используете на практике?

  • Как бы вы реализовали такие обертки? Существует множество возможных подходов (замыкания, глобальные переменные для хранения дополнительных аргументов, передача объектов при обратном вызове и т.д.).

PS У меня есть пара разных реализаций для (1) и (3) уже и (как было предложено) опубликую некоторые фрагменты моего кода время позднее, чтобы я не испортил веселье.:)

Пример

Текущий способ:

add_filter('wp_feed_cache_transient_lifetime', 'change_transient_lifetime', 10);

function change_transient_lifetime($lifetime) {

    return 3600;
}

Обертка:

add_filter_return('wp_feed_cache_transient_lifetime', 10, 3600);
Author: Rarst, 2011-03-05

5 answers

Для простых случаев, таких как быстрые однострочные возвраты, следует помнить, что анонимную функцию можно подключить непосредственно в вызове добавления фильтра, например:

add_filter('some_filter_hook', function($v){return str_replace('..', '.', $v);});

add_action('some_action_hook', function(){echo '....';});
 6
Author: wyrfel, 2011-03-05 17:42:15

Возможно, вам захочется изучить методы магического класса и перегрузку в PHP, в которых в качестве параметра будет передано имя вызываемой функции. Затем вы можете принимать решения на основе имени функции, например return__some_string Я прикрепляю некоторый примерный и непроверенный код:

class magiCall {
    public static function __callStatic ( string $name , array $arguments ) {
        // your code here, $name is the function name called.
    }
}

add_filter('hookname', 'magiCall::return__the_string');

Я думаю, что этот пример в значительной степени показывает идею.

Это PHP 5.3.x вы можете сделать этот PHP 5.2 совместимым с помощью волшебного метода __call, и если у вас есть статическая общедоступная функция для возврата обратный вызов, тогда вы, возможно, сможете написать его сравнительно упрощенно. Смотрите ссылку на руководство по php выше.

 5
Author: hakre, 2011-03-06 10:44:47

Я выпустил свой код в виде библиотеки Advanced Hooks API.

Некоторые примеры:

add_action_with_arguments('test', 'printf', 10, 'boo%s', '<br />');
do_action('test');
// boo

add_filter_return('test2',10,'boo');
echo apply_filters('test2','not boo') . '<br />';
// boo

add_filter_append('test3',10,' and boo');
echo apply_filters('test3','boo') . '<br />';
// boo and boo

add_filter_prepend('test4',10,'boo and ');
echo apply_filters('test4','boo') . '<br />';
// boo and boo

add_filter_replace('test5','boo','you thought...');
echo apply_filters('test5','boo');
// you thought...
 5
Author: Rarst, 2014-12-30 13:18:02

Для простых возвращаемых значений вам не нужно много дополнительных функций. Есть удобный current_filter(). Вы можете использовать это внутри своих собственных функций.

Пример

<?php # -*- coding: utf-8 -*-
/*
Plugin Name: Filter System From Mail
Description: Sets the WP from mail address to the first admin’s mail and the from name to blog name.
Version:     1.1
Author:      Thomas Scholz
Author URI:  http://toscho.de
License:     GPL
*/

if ( ! function_exists( 'filter_system_from_mail' ) )
{
    /**
     * First admin's e-mail address or blog name depending on current filter.
     *
     * @return string
     */
    function filter_system_from_mail()
    {
        return get_option( 'wp_mail_from' == current_filter()
            ? 'admin_email' : 'blogname' );
    }

    add_filter( 'wp_mail_from',      'filter_system_from_mail' );
    add_filter( 'wp_mail_from_name', 'filter_system_from_mail' );
}

Или... я неправильно понял ваш вопрос?

 1
Author: fuxia, 2011-03-05 14:03:32

Анонимные объявления или лямбда-функции) В любом случае я бы избегал их, так как вы не будете знать имя или получите довольно загадочный вывод, если позже проверите крючок. Отладка была бы мучительной.

Объявление вашего A) Подход выглядит красиво и предлагает довольно простой API (+1).

Объявление @хакре А) Я использую почти ту же функцию[1] в своем ядре фреймворков - расширенную с помощью "set_" и исключения - для установки и получения переменных на лету. Таким образом, мне нужно только расширить этот класс с дочерним классом, который выглядит как интерфейс "только для переменных" (те, которые должны быть доступны). Это хороший и организованный подход, который хранит в файлах только то, что служит одной задаче. С помощью чего-то подобного вы, возможно, сможете избежать написания определенных функций для каждого такса, таких как "_replace" и т. Д.

[1] Код - я запускаю это все время, так что вы можете назвать это "проверено - и работает"

/**
 * Magic getter/setter method
 * Guesses for a class variable & calls/fills it or throws an exception.
 * Note: Already defined methods override this method.
 * 
 * Original @author Miles Keaton <[email protected]> 
 * on {@link http://www.php.net/manual/de/language.oop5.overloading.php#48440}
 * The function was extended to also allow 'set' tasks/calls and throws an exception.
 * 
 * @param (string) $name | Name of the property
 * @param unknown_type $args | arguments the function can take
 */
function __call( $name, $args )
{
    $_get = false;

    // See if we're calling a getter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == 'get_' )
    {
        $_get = true;
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == 'get' )
    {
        $_get = true;
        $varname = substr( $val, 3 );
    }

    // See if we're calling a setter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == 'set_' )
    {
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == 'set' )
    {
        $varname = substr( $val, 3 );
    }

    if ( ! isset( $varname ) )
        return new Exception( sprintf( __( "The method %1$s doesn't exist" ), "<em>{$val}</em>" ) );

    // Now see if that variable exists:
    foreach( $this as $class_var => $class_var_value )
    {
        if ( strtolower( $class_var ) == strtolower( $varname ) )
        {
            // GET
            if ( $_get )
            {
                return $this->{$class_var};
            }
            // SET
            else 
            {
                return $this->{$class_var} = $x[0];
            }
        }
    }

    return false;
}
 0
Author: kaiser, 2011-08-14 14:31:45