php 将额外的参数传递给 usor 回调
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8230538/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pass extra parameters to usort callback
提问by djb
I have the following functions. WordPress functions, but this is really a PHP question. They sort my $term
objects according to the artist_lastname
property in each object's metadata.
我有以下功能。WordPress 功能,但这确实是一个 PHP 问题。他们$term
根据artist_lastname
每个对象元数据中的属性对我的对象进行排序。
I want to pass a string into $meta
in the first function. This would let me reuse this code as I could apply it to various metadata properties.
我想$meta
在第一个函数中传递一个字符串。这将使我可以重用此代码,因为我可以将其应用于各种元数据属性。
But I don't understand how I can pass extraparameters to the usort callback. I tried to make a JS style anonymous function but the PHP version on the server is too old and threw a syntax error.
但我不明白如何将额外的参数传递给 usort 回调。我试图制作一个JS风格的匿名函数,但是服务器上的PHP版本太旧并且抛出了一个语法错误。
Any help - or a shove towards the right corner of the manual - gratefully appreciated. Thanks!
任何帮助 - 或推向手册的右角 - 感激不尽。谢谢!
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);
}
采纳答案by Daniel Trebbien
In PHP, one option for a callbackis to pass a two-element array containing an object handle and a method name to call on the object. For example, if $obj
was an instance of class MyCallable
, and you want to call the method1
method of MyCallable
on $obj
, then you can pass array($obj, "method1")
as a callback.
在 PHP 中,回调的一种选择是传递一个包含对象句柄和方法名称的二元素数组,以在对象上调用。例如,如果$obj
是 class 的实例MyCallable
,并且您想调用on的method1
方法,那么您可以作为回调传递。MyCallable
$obj
array($obj, "method1")
One solution using this supported callback type is to define a single-use class that essentially acts like a closure type:
使用这种受支持的回调类型的一种解决方案是定义一个本质上类似于闭包类型的一次性类:
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);
}
}
回答by Bas
I think this question deserves an update. I know the original question was for PHP version 5.2, but I came here looking for a solution and found one for newer versions of PHP and thought this might be useful for other people as well.
我认为这个问题值得更新。我知道最初的问题是针对 PHP 5.2 版的,但我来这里是为了寻找解决方案,并为较新版本的 PHP 找到了一个解决方案,并认为这对其他人也可能有用。
For PHP 5.3 and up, you can use the 'use' keyword to introduce local variables into the local scope of an anonymous function. So the following should work:
对于 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);
});
}
Some more general code
一些更通用的代码
If you want to sort an array just once and need an extra argument you can use an anonymous function like this:
如果您只想对数组排序一次并需要一个额外的参数,您可以使用这样的匿名函数:
usort($arrayToSort, function($a, $b) use ($myExtraArgument) {
//$myExtraArgument is available in this scope
//perform sorting, return -1, 0, 1
return strcmp($a, $b);
});
If you need a reusable function to sort an array which needs an extra argument, you can always wrap the anonymous function, like for the original question:
如果您需要一个可重用的函数来对需要额外参数的数组进行排序,您始终可以包装匿名函数,就像原始问题一样:
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);
});
}
回答by Kato
Assuming you've access to objects and static (PHP 5 or greater), you can create an object and pass the arguments directly there, like so:
假设您可以访问对象和静态(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'));
Assuming you don't have access to objects/static; you could just do a global:
假设您无权访问对象/静态;你可以做一个全球性的:
$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');
回答by John Watson
WarningThis function has been DEPRECATED as of PHP 7.2.0. Relying on this function is highly discouraged.
警告该函数自 PHP 7.2.0 起已被弃用。强烈建议不要依赖此功能。
The docs say that create_function()
should work on PHP >= 4.0.1. Does this work?
文档说这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");'));
回答by salathe
This won't help you at all with usort()
but might be helpful nevertheless. You could sort the array using one of the other sorting functions, array_multisort()
.
这根本不会帮助你,usort()
但可能会有所帮助。您可以使用其他排序函数之一对数组进行排序array_multisort()
。
The idea is to build an array of the values that you would be sorting on (the return values from get_term_meta()
) and multisort that against your main $terms
array.
这个想法是构建一个你将要排序的值的数组(来自 的返回值get_term_meta()
)和对你的主$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);
}