Family Tree data structure

I am looking for a way to represent a family tree in PHP. This means that children must inherit from two (or more) parents.

Here are the requirements:

  • 1, 2 or more parents
  • Bonus points if I can attach metadata such as name or relationship status.

Here is my non-working attempt (without arrays as keys, unfortunately):

$tree = array( 'uncle' => false, // no children array('mom', 'dad') => array( 'me' => false, array('brother', 'sister-in-law') => array( 'niece' => false ) ) ); 

The question is, how can I imagine a family tree with these requirements?

+6
php data-structures family-tree
source share
2 answers

You cannot do all this in one array() . You can customize these trees, but it takes several lines of code to create more complex graphs with multiple parents and other relationships.

This will help a lot if you throw OO. Let me create a Person class to help manage relationships. In fact, we have people and their relationships with other people, so we will start there.

Person class

I think everyone has a lot of relationships. This array will first be indexed by type of relationship, such as "parents" or "children." Each entry will be an array of Person s.

 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; } // Looks up multiple relations, for example "parents". function getRelations($type) { if (!isset($this->relations[$type])) { return array(); } return $this->relations[$type]; } // Looks up a single relation, for example "spouse". function getRelation($type) { $relations = $this->getRelations($type); return empty($relations) ? null : $relations[0]; } function __toString() { return $this->name; } 

Friendly Adders and Recipients

With the above as a basis, we can then add some more friendly method names. To illustrate, we will process the parent / child and spouse relationships.

  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'); } } 

Making people

Now we can create a couple of people and establish their relationship. Let Billy and his parents John and Jane try it.

 $john = new Person('John'); $jane = new Person('Jane'); $billy = new Person('Billy'); $john ->addSpouse ($jane); $billy->addParents($jane, $john); 

And we can check their relationship like this:

 echo "John is married to " . $john->getSpouse() . ".\n"; echo "Billy parents are " . implode(" and ", $billy->getParents()) . ".\n"; 

Output:

John is married to Jane.
Billy's parents are Jane and John.

Display family tree

We can cross the chart recursively if it grows. Here is an example of a tree function that displays a rudimentary family tree. I added Sarah, her husband Mike and their son Bobby to the mix.

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

Output:

John and Jane
.... Sarah and Mike
........ Bobby
.... Billy


Edit: Here is the @Wrikken comment below to reproduce:

About it really. IMHO adds from the date to each relationship though (maybe NULL without end). There are divorces, as well as adoptions, etc. Also: I would add inverse types and "flip back" to the addRelation() function:

 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); } } 
+19
source share

GEDCOM is an open specification for the exchange of genealogical data between different genealogy programs. A GEDCOM file is plain text (usually ANSEL or ASCII) containing genealogical information about individuals and metadata linking these records together. Most genealogy programs support import and / or export to the GEDCOM format.

The main advantage of using GEDCOM is that you could use desktop programs like Aldfaer (Dutch only) , Gramps or Legacy Family Tree , as well as online tools like Geneanet to create or modify your family tree and compare it with pedigrees of others.

Another important advantage of using the GEDCOM format is that you have libraries in several programming languages ​​at your disposal for saving and loading your data. Examples of PHP libraries would be Import / Export Filter GEDCOM , GenealogyGedcom or PHP GEDCOM .

Using PHP GEDCOM, reading and parsing a GEDCOM file will be as simple as this:

 $parser = new \PhpGedcom\Parser(); $gedcom = $parser->parse('gedcom.ged'); 

The main disadvantage of using GEDCOM is that the GEDCOM data format is built around a nuclear family, which means that the standard is limited in supporting non-traditional family structures, such as same-sex partnerships, mixed families or cohabitation. Although GEDCOM can be extended to support this type of relationship, interoperability between different programs is limited for such extensions.

Another major disadvantage of using GEDCOM is that GEDCOM files are monolithic. If you have a dataset of thousands of people or want to change your data structure frequently, you are likely to run into performance issues. Especially in such cases, it is better to store your data in a database. However, this does not mean that GEDCOM is useless. In such cases, you may need to use the database schema based on the GEDCOM format, which allows you to import / export the database and the GEDCOM format. There are libraries for this. Oxy-Gen is an example.


Alternatives to GEDCOM will be the GenTech Data Model or the Gramps Data Model . Although they are not as widely used as the GEDCOM standard, they can better suit your needs.

If you want to use the Gramps data model, you can use, for example. Gramps PHP exportorter to export your data to SQLite database. See also this source on how to create a database suitable for the Gramps data model.

+2
source share

All Articles