你不能像这样在单个
array()
中完成所有操作。你可以像那样设置树形结构,但要设置更复杂的具有多个父级和其他关系的图形需要多行代码。
如果你加入一些面向对象编程(OO),它会对你有很大帮助。让我们创建一个
Person
类来帮助管理关系。基本上,我们有人和他们与其他人之间的关系,所以我们从那里开始。
Person类
我想象每个人都有一个关系数组。该数组首先按关系类型进行索引,例如“父母”或“孩子”。然后,每个条目将是一个
Person
数组。
class Person {
var $name, $relations;
function __construct($name) {
$this->name = $name;
$this->relations = array();
}
function addRelation($type, $person) {
if (!isset($this->relations[$type])) {
$this->relations[$type] = array();
}
$this->relations[$type][] = $person;
}
function getRelations($type) {
if (!isset($this->relations[$type])) {
return array();
}
return $this->relations[$type];
}
function getRelation($type) {
$relations = $this->getRelations($type);
return empty($relations) ? null : $relations[0];
}
function __toString() {
return $this->name;
}
友好的添加和获取方法
有了上述基础,我们可以添加一些更友好命名的方法。为了说明,我们将处理父母/子女关系和配偶关系。
function addParents($mom, $dad) {
$mom->addChild($this);
$dad->addChild($this);
}
function addChild($child) {
$this ->addRelation('children', $child);
$child->addRelation('parents', $this);
}
function addSpouse($spouse) {
$this ->addRelation('spouse', $spouse);
$spouse->addRelation('spouse', $this);
}
function getParents () { return $this->getRelations('parents'); }
function getChildren() { return $this->getRelations('children'); }
function getSpouse () { return $this->getRelation ('spouse'); }
}
创建人
现在我们可以创建几个人并建立他们之间的关系。让我们试着创建比利和他的父母约翰和简。
$john = new Person('John');
$jane = new Person('Jane');
$billy = new Person('Billy');
$john ->addSpouse ($jane);
$billy->addParents($jane, $john);
我们可以这样查看它们之间的关系:
echo "John is married to " . $john->getSpouse() . ".\n";
echo "Billy's parents are " . implode(" and ", $billy->getParents()) . ".\n";
输出:
John和Jane结婚了。
Billy的父母是Jane和John。
显示家谱
如果家谱树逐渐变得更加复杂,我们可以使用递归来遍历它。这是一个示例的树遍历函数,用于显示简单的家谱树。我已经加入了Sara、她的丈夫Mike和他们的儿子Bobby。
$john = new Person('John');
$jane = new Person('Jane');
$sara = new Person('Sara');
$mike = new Person('Mike');
$bobby = new Person('Bobby');
$billy = new Person('Billy');
$john ->addSpouse ($jane);
$sara ->addParents($jane, $john);
$sara ->addSpouse ($mike);
$bobby->addParents($sara, $mike);
$billy->addParents($jane, $john);
function displayFamilyTree($root, $prefix = "") {
$parents = array($root);
if ($root->getSpouse() != null) {
$parents[] = $root->getSpouse();
}
echo $prefix . implode(" & ", $parents) . "\n";
foreach ($root->getChildren() as $child) {
displayFamilyTree($child, "....$prefix");
}
}
displayFamilyTree($john);
输出:
约翰和简
....莎拉和迈克
........鲍比
....比利
编辑: 下面是@Wrikken的评论,为了易读性而重复:
确实如此。 我认为每个关系都应该添加一个从-到日期(可能为NULL表示没有结束)。 离婚会发生,收养等也会发生。 此外:我会在addRelation()
函数中添加反向类型和“回嗔回来”:
function addRelation($type, $person, $reverseType, $pingback = false) {
if (!isset($this->relations[$type])) {
$this->relations[$type] = array();
}
if (!in_array($person, $this->relations[$type], true)) {
$this->relations[$type][] = $person;
}
if (!$pingback) {
$person->addRelation($reverseType, $this, $type, true);
}
}