Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 无法为usort执行OOP回调函数 我已经阅读了几十篇关于使用类成员作为回调函数的讨论,但是没有一个例子能解决我在使用其他OOP语言(如C++和java)时的明显的OOP设计。_Php_Oop - Fatal编程技术网

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();