3v4l.org

run code in 150+ php & hhvm versions
Bugs & Features
<?php class Menu { const MENU_CACHE_KEY = 'menu_cache'; /** @var MenuItem[] */ protected $rootNodes = array(); protected $childNodes = array(); /** @var ICache */ protected $cache; /** * @param ICache $cache */ public function setCache(ICache $cache) { $this->cache = $cache; } public function hasCache() { return $this->cache instanceof ICache; } /** * @param MenuItem $menuItem */ public function add(MenuItem $menuItem) { if ($menuItem->isParent()) { $this->addRootNode($menuItem); } else { $this->addChildNode($menuItem); } } /** * @param MenuItem $menuItem */ private function addRootNode(MenuItem $menuItem) { array_push($this->rootNodes, $menuItem); } /** * @param MenuItem $menuItem */ private function addChildNode(MenuItem $menuItem) { $this->ensureChildNodeExists($menuItem->parentId); array_push($this->childNodes[$menuItem->parentId], $menuItem); } /** * @param int $parentId */ private function ensureChildNodeExists($parentId) { if (!isset($this->childNodes[$parentId])) { $this->childNodes[$parentId] = array(); } } /** * @return string */ public function render() { if ($this->hasCache()) { $cached = $this->cache->getItem(self::MENU_CACHE_KEY); if (!empty($cached)) { return $cached; } } $html = '<ul>'; foreach ($this->rootNodes as $menuItem) { $html .= '<li>' . $menuItem->render(); if (!empty($this->childNodes[$menuItem->id])) { $html .= '<ul>'; /** @var $childMenuItem MenuItem */ foreach ($this->childNodes[$menuItem->id] as $childMenuItem) { $html .= '<li>' . $childMenuItem->render() . '</li>'; } $html .= '</ul>'; } $html .= '</li>'; } $html .= '</ul>'; if ($this->hasCache()) { $this->cache->setItem(self::MENU_CACHE_KEY, $html); } return $html; } } class MenuItem { public $id; public $parentId; public $label; public $link; /** * @param array|null $params */ public function __construct($params = null) { if (!is_null($params)) { $this->id = (int) $params['id']; $this->label = $params['label']; $this->link = $params['link']; $this->parentId = (int) $params['parent_id']; } } /** * @return bool */ public function isParent() { return $this->parentId === 0; } /** * @return string */ public function render() { return '<a href="' . $this->link . '">' . $this->label . '</a>'; } } interface ICache { /** * @param string $key * * @return string|null */ public function getItem($key); /** * @param string $key * @param string $value */ public function setItem($key, $value); } $dbResults = array( array('id' => 1, 'parent_id' => 0, 'link' => '#', 'label' => 'Home'), array('id' => 2, 'parent_id' => 0, 'link' => '#', 'label' => 'Portfolio'), array('id' => 3, 'parent_id' => 0, 'link' => '#', 'label' => 'Projects'), array('id' => 4, 'parent_id' => 2, 'link' => '#', 'label' => 'Design'), array('id' => 5, 'parent_id' => 2, 'link' => '#', 'label' => 'Dev'), array('id' => 6, 'parent_id' => 2, 'link' => '#', 'label' => 'Foo'), array('id' => 7, 'parent_id' => 3, 'link' => '#', 'label' => 'Bar'), ); $menu = new Menu(); /* $menu->setCache(new RedisCache()); $menu->setCache(new FileCache()); $menu->setCache(new MemcachedCache()); */ foreach ($dbResults as $row) { $menu->add(new MenuItem($row)); } echo $menu->render();
based on hbfMa
Output for 5.0.0 - 7.1.0
<ul><li><a href="#">Home</a></li><li><a href="#">Portfolio</a><ul><li><a href="#">Design</a></li><li><a href="#">Dev</a></li><li><a href="#">Foo</a></li></ul></li><li><a href="#">Projects</a><ul><li><a href="#">Bar</a></li></ul></li></ul>
Output for 4.4.2 - 4.4.9
Parse error: syntax error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/N6cli on line 5
Process exited with code 255.
Output for 4.3.0 - 4.3.1, 4.3.5 - 4.4.1
Parse error: parse error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/N6cli on line 5
Process exited with code 255.
Output for 4.3.2 - 4.3.4
Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in /in/N6cli on line 5
Process exited with code 255.