Реализация расширенных оболочек функций добавления *
add_action()
и add_filter()
являются основными функциями. Однако в некоторых сценариях добавьте еще одну функцию и закрепите ее где-нибудь подход становится громоздким и неудобным.
Я определил для себя несколько вариантов использования, которые могут упростить код с помощью оболочек поверх функций add_*
. Вещи, которые лучше обрабатываются с помощью одного вкладыша, чем дополнительные функции каждый раз.
Добавьте произвольный возврат фильтра. Уже есть
__return_*
функции, но они очень ограничены по определению. Почему бы просто не передать то, что вы хотите вернуть в фильтре. Спасает от множестваfunction return_stuff(){return 'stuff';}
Замените X на Y в фильтре. Спасает от множества
function replace_stuff(){return str_replace();}
Добавьте действие с произвольными аргументами. Действия срабатывают с аргументами, переданными в крючок. Но иногда вас это не волнует, и вы просто хотите запустить свою функцию со своими собственными аргументами на определенном крючке. Спасает от множества
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);
5 answers
Для простых случаев, таких как быстрые однострочные возвраты, следует помнить, что анонимную функцию можно подключить непосредственно в вызове добавления фильтра, например:
add_filter('some_filter_hook', function($v){return str_replace('..', '.', $v);});
add_action('some_action_hook', function(){echo '....';});
Возможно, вам захочется изучить методы магического класса и перегрузку в 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 выше.
Я выпустил свой код в виде библиотеки 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...
Для простых возвращаемых значений вам не нужно много дополнительных функций. Есть удобный 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' );
}
Или... я неправильно понял ваш вопрос?
Анонимные объявления или лямбда-функции) В любом случае я бы избегал их, так как вы не будете знать имя или получите довольно загадочный вывод, если позже проверите крючок. Отладка была бы мучительной.
Объявление вашего 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;
}