Php 无法为usort执行OOP回调函数 我已经阅读了几十篇关于使用类成员作为回调函数的讨论,但是没有一个例子能解决我在使用其他OOP语言(如C++和java)时的明显的OOP设计。
我在类中定义了一个比较方法:Php 无法为usort执行OOP回调函数 我已经阅读了几十篇关于使用类成员作为回调函数的讨论,但是没有一个例子能解决我在使用其他OOP语言(如C++和java)时的明显的OOP设计。,php,oop,Php,Oop,我在类中定义了一个比较方法: class TestClass { private $aField; // integer value function _construct($value) { $this->aField = $value; } // TestClass::_construct function compare($other) { if ($other instanceof TestClass) { //
class TestClass {
private $aField; // integer value
function _construct($value)
{
$this->aField = $value;
} // TestClass::_construct
function compare($other)
{
if ($other instanceof TestClass)
{ // comparing two instances
return $this->afield - $other->afield;
} // comparing two events
else
throw new Exception("parameter is not instance of TestClass");
} // TestClass::compare
} // class TestClass
$instances = array(new TestClass(5),new TestClass(3));
// the following fails because:
// 1. $this is not defined outside a class member
// 2. compare does not take two parameters
usort($instances, array($this, 'compare'));
// the following kluge works around this
function order($this, $that) { return $this->compare($that); }
usort($instances, 'order');
我在这个论坛和PHP文档中找到的所有示例都不完整,因为它们没有显示调用usort的上下文。现在,我可以通过将比较函数设置为带有两个参数的静态函数,并将其作为数组调用(“TestClass”、“compare”)来解决这个问题,但将比较方法定义为类的静态函数并不直观。基于在OOP方面30多年的个人经验,静态函数在大多数情况下都是糟糕的类设计造成的。特别是静态方法会破坏多态性
我要寻找的是一个类似Java的排序函数,它利用了类似的接口。我看到,早在2010年就有一些关于定义可比较接口的讨论,但这些讨论只涉及比较运算符,这让PHP纯粹主义者感到不舒服,因为它重载了运算符。但是,Java Compariable接口不重载运算符,因为除了String类之外,Java不支持重载运算符。在Java中实现Comparable接口使您能够在SortedMaps中使用类并在集合中对实例进行排序,但是如果您希望比较两个对象,则必须显式调用compareTo方法。我还看到了一个基本上没有文档记录的compare_objects方法,它已经覆盖了比较运算符的默认实现。换句话说,尽管纯粹主义者反对,PHP已经允许您重载类的比较运算符。但是,当PHP排序函数被要求对对象进行排序时,它是否使用compare_对象是没有文档记录的。您在类外调用$this
$obj = new TestClass();
$sorted = usort($instances, array($obj, 'compare'));
您也可以这样做(没有测试代码)
您在评论中提到了一个collection类,下面是一个使用(非常基本的)collection类的示例,并结合我提到的手册中用户评论的排序方法:
class Collection {
private $itemType;
private $items;
public function __construct($itemType) {
$this->itemType = $itemType;
$this->items = [];
}
public function add($item) {
if($item instanceof $this->itemType) {
$this->items[] = $item;
}
else {
throw new Exception('Only items of Type ' . $this->itemType . ' can be added!');
}
}
public function sort() {
usort($this->items, array($this, 'compareItems'));
var_dump($this->items); // test output, to check the result
}
private function compareItems($a, $b) { // calls the compare method of the item class
return $a->compare($b);
}
}
class TestClass {
private $aField;
public function __construct($value) {
$this->aField = $value;
}
public function compare($other) {
if($other instanceof TestClass) {
return $this->aField - $other->aField;
}
else {
throw new Exception('Parameter is not instance of TestClass!');
}
}
}
$collection = new Collection('TestClass');
$collection->add(new TestClass(5));
$collection->add(new TestClass(1));
$collection->add(new TestClass(3));
$collection->sort();
在真正的OOP(如Java)中,排序函数是集合类的方法,而不是单个对象的方法。在PHP中,各种风格的排序都是全局函数。看看这个用户评论,它可能并不完全是你想要的,但至少它提供了一种在某些情况下可能有用的解决方法。
class Collection {
private $itemType;
private $items;
public function __construct($itemType) {
$this->itemType = $itemType;
$this->items = [];
}
public function add($item) {
if($item instanceof $this->itemType) {
$this->items[] = $item;
}
else {
throw new Exception('Only items of Type ' . $this->itemType . ' can be added!');
}
}
public function sort() {
usort($this->items, array($this, 'compareItems'));
var_dump($this->items); // test output, to check the result
}
private function compareItems($a, $b) { // calls the compare method of the item class
return $a->compare($b);
}
}
class TestClass {
private $aField;
public function __construct($value) {
$this->aField = $value;
}
public function compare($other) {
if($other instanceof TestClass) {
return $this->aField - $other->aField;
}
else {
throw new Exception('Parameter is not instance of TestClass!');
}
}
}
$collection = new Collection('TestClass');
$collection->add(new TestClass(5));
$collection->add(new TestClass(1));
$collection->add(new TestClass(3));
$collection->sort();