Передача дополнительных параметров для отмены обратного вызова

У меня есть следующие функции. Функции WordPress, но это действительно вопрос PHP. Они сортируют мои объекты $term соответствии с свойством artist_lastname в метаданных каждого объекта.

Я хочу передать строку в $meta в первой функции. Это позволило бы мне повторно использовать этот код, поскольку я мог бы применить его к различным свойствам метаданных.

Но я не понимаю, как я могу передать дополнительные параметры для обратного вызова usort. Я попытался сделать анонимную функцию стиля JS, но версия PHP на сервере слишком стар и выбросила синтаксическую ошибку.

Любая помощь – или толчок к правому углу руководства – с благодарностью оценили. Благодаря!

 function sort_by_term_meta($terms, $meta) { usort($terms,"term_meta_cmp"); } function term_meta_cmp( $a, $b ) { $name_a = get_term_meta($a->term_id, 'artist_lastname', true); $name_b = get_term_meta($b->term_id, 'artist_lastname', true); return strcmp($name_a, $name_b); } 

Related of "Передача дополнительных параметров для отмены обратного вызова"

В PHP одним из вариантов обратного вызова является передача двухэлементного массива, содержащего дескриптор объекта и имя метода для вызова объекта. Например, если $obj был экземпляром класса MyCallable и вы хотите вызвать метод метода MyCallable в $obj , вы можете передать array($obj, "method1") в качестве обратного вызова.

Одним из решений, использующих этот поддерживаемый тип обратного вызова, является определение одноразового класса, который по существу действует как тип замыкания:

 function sort_by_term_meta( $terms, $meta ) { usort($terms, array(new TermMetaCmpClosure($meta), "call")); } function term_meta_cmp( $a, $b, $meta ) { $name_a = get_term_meta($a->term_id, $meta, true); $name_b = get_term_meta($b->term_id, $meta, true); return strcmp($name_a, $name_b); } class TermMetaCmpClosure { private $meta; function __construct( $meta ) { $this->meta = $meta; } function call( $a, $b ) { return term_meta_cmp($a, $b, $this->meta); } } 

Я думаю, что этот вопрос заслуживает обновления. Я знаю, что исходный вопрос был для PHP версии 5.2, но я пришел сюда для поиска решения и нашел его для более новых версий PHP и думал, что это может быть полезно и для других людей.

Для PHP 5.3 и выше вы можете использовать ключевое слово « use », чтобы ввести локальные переменные в локальную область анонимной функции. Таким образом, следующее должно работать:

 function sort_by_term_meta(&$terms, $meta) { usort($terms, function($a, $b) use ($meta) { $name_a = get_term_meta($a->term_id, 'artist_lastname', true); $name_b = get_term_meta($b->term_id, 'artist_lastname', true); return strcmp($name_a, $name_b); }); } 

Еще один общий код

Если вы хотите отсортировать массив только один раз и вам нужен дополнительный аргумент, вы можете использовать анонимную функцию, например:

 usort($arrayToSort, function($a, $b) use ($myExtraArgument) { //$myExtraArgument is available in this scope //perform sorting, return -1, 0, 1 return strcmp($a, $b); }); 

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

 function mySortFunction(&$arrayToSort, $myExtraArgument1, $myExtraArgument2) { usort($arrayToSort, function($a, $b) use ($myExtraArgument1, $myExtraArgument2) { //$myExtraArgument1 and 2 are available in this scope //perform sorting, return -1, 0, 1 return strcmp($a, $b); }); } 

Предполагая, что у вас есть доступ к объектам и статическим (PHP 5 или выше), вы можете создать объект и передать аргументы прямо там, например:

 <?php class SortWithMeta { private static $meta; static function sort(&$terms, $meta) { self::$meta = $meta; usort($terms, array("SortWithMeta", "cmp_method")); } static function cmp_method($a, $b) { $meta = self::$meta; //access meta data // do comparison here } } // then call it SortWithMeta::sort($terms, array('hello')); 

Предполагая, что у вас нет доступа к объектам / статическим; вы могли бы просто сделать глобальный:

 $meta = array('hello'); //define meta in global function term_meta_cmp($a, $b) { global $meta; //access meta data // do comparison here } usort($terms, 'term_meta_cmp'); 

Документы говорят, что create_function() должен работать на PHP> = 4.0.1. Это работает?

 function term_meta_cmp( $a, $b, $meta ) { echo "$a, $b, $meta<hr>"; // Debugging output } $terms = array("d","c","b","a"); usort($terms, create_function('$a, $b', 'return term_meta_cmp($a, $b, "some-meta");')); 

Это не поможет вам с помощью функции usort() но может быть полезно, тем не менее. Вы можете отсортировать массив, используя одну из других функций сортировки, array_multisort() .

Идея состоит в том, чтобы построить массив значений, которые вы будете сортировать (возвращаемые значения из get_term_meta() ) и multisort, которые против вашего основного массива $terms .

 function sort_by_term_meta(&$terms, $meta) { $sort_on = array(); foreach ($terms as $term) { $sort_on[] = get_term_meta($term->term_id, $meta, true); } array_multisort($sort_on, SORT_ASC, SORT_STRING, $terms); }