PHP层次导航OOP结构



使用PHP表示树导航结构的最佳方式是什么?我需要能够使用面包屑轨迹跟踪树中的当前页面位置。树的某些部分是从数据库(如make->models)中生成的。每个模型都有相同的等价分支,例如:

制作>模型>(区域1、区域2、区域3)。

树的某些部分可能会随着时间的推移而变化。最好是有一个静态的类层次结构,还是有一个可以重用类的动态解决方案?

希望能简单解释一下。

我会选择:

  • 每个元素的CCD_ 1列表[如果为空,它当然是叶节点]
  • 父元素的CCD_ 2字段[如果为空,则为根节点]

通过这种方式,您可以为每个节点重建面包屑跟踪,为它们提供getTrail()方法:

public function getTrail()
{
    $parent = $this -> parent();
    $trail = array();
    while($parent !== NULL)
    {
        // push parent element to trail
        $trail[] = $parent;
        // go backwards one node
        $parent = $parent -> parent();
    }
    // you want trail in reverse order [from root to latest]
    return array_reverse($trail);
}

如果您的节点类型不同,请确保至少提供具有getTrail()/getParent()方法的TrailTrackable接口。

class TreeNode {
    /**
 * the parent node
 *
 * @var TreeNode
 */
    private $parentNode=null;
     /**
 * the children of this node
 *
 * @var TreeNode[]
 */
    private $children=array();
     /**
 * The user element this tree node holds.
 *
 * @var Object
 */
    private $element;
}

从OO的角度来看,我建议定义如下接口:

interface BreadcrumbInterface
{
    public function getLabel();
    public function getParent(); // returns an instance of BreadcrumbInterface, or null
}

然后创建一个Page类,它实现了这个接口,并且可以选择包含一个"parent",它也必须实现这个接口。这将建立你所需要的继承权。

检索完整的面包屑的一个好方法(同时在此过程中复习OO设计模式)是使用访问者模式。在这种情况下,您可能需要定义一个通用的抽象类和接口,以便"抽象掉"处理访问者的逻辑。。。

abstract class BaseNode implements BreadcrumbInterface
{
    protected $parent = null;
    public function accept(BreadcrumbVisitor $visitor)
    {
        $visitor->visit($this);
    }
    public function setParent(BreadcrumbInterface $parent)
    {
        $this->parent = $parent;
    }
    public function getParent()
    {
        return $this->parent;
    }
}
class BreadcrumbVisitor
{
    protected $breadcrumbs = array();
    public function visit(BreadcrumbInterface $node)
    {
        $parent = $node->getParent();
        if ($parent instanceof BaseNode) {
            $parent->accept($this);
        }
        $this->breadcrumbs[] = $node->getLabel();
    }
    public function getBreadcrumbs()
    {
        return $this->breadcrumbs;
    }
}

这不会按原样运行,但希望你能明白。您可能还希望您的节点确定其页面的URL以及标签,但添加这些内容非常容易。我只是想展示解决这个问题的通用OO结构。

编辑:

添加粗略用法示例:

$rootPage = new Page(/*...*/);
$parentPage = new Page(/*...*/);
$parentPage->setParent($rootPage); // In reality you most likely wouldn't be building this structure so explicitly. Each object only needs to know about it's direct parent
$currentPage = new Page(/*...*/);
$currentPage->setParent($parentPage);
$visitor = new BreadcrumbVisitor();
$currentPage->accept($visitor);
$breadcrumbs = $visitor->getBreadcrumbs(); // returns an array, where the first element is the root
// then you can implode with ' > ' if you want
$breadcumbString = implode(' > ', $breadcrumbs);

相关内容

  • 没有找到相关文章

最新更新