問題描述
我有以下功能 Wordpress 功能,但這是一個 PHP 問題。他們根據每個物件的後設資料中的 artist_lastname 屬性對 $term 物件進行排序。
我想在第一個函式中將一個字串傳遞給 $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);
}
最佳解決方法
在 PHP 中,callback 的一個選項是傳遞一個包含物件控制程式碼和方法名稱的 two-element 陣列,以呼叫該物件。例如,如果 $ obj 是 MyCallable 類的一個例項,並且您要呼叫 $ obj 上的 MyCallable 的 method1 方法,那麼可以將陣列 ($ obj,”method1″) 作為回撥傳遞。
使用這種支援的回撥型別的一個解決方案是定義一個基本上類似於閉包型別的 single-use 類:
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'));
假設你沒有訪問物件/static; 你可以做一個全球化:
$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");'));
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。