3v4l.org

run code in 300+ PHP versions simultaneously
<?php $str = <<<HTML <div class="article" id="titleDetails"> <span class="rightcornerlink"> </span> <div class="txt-block"> <h4 class="inline">Country:</h4> <a href="/country/us?ref_=tt_dt_dt" itemprop="url">USA</a> </div> <div class="txt-block"> <h4 class="inline">Language:</h4> <a href="/language/en?ref_=tt_dt_dt" itemprop="url">English</a> </div> </div> HTML; $html = HtmlParser::from_string($str); echo "<pre>"; var_dump(HtmlParser::css_to_xpath('#titleDetails h4')); foreach ($html->find('#titleDetails h4') as $r) { if (preg_match('/Country/', $r->text)) { var_dump($r->text); var_dump($r->parent()->find('a', 0)->text); } } echo "</pre>"; /** * Author: Hitesh Kumar, IIT Delhi. * License: http://en.wikipedia.org/wiki/WTFPL */ class HtmlParser { public static function from_string($str, $xml = false) { libxml_use_internal_errors(true); $html = new DOMDocument(); if($xml) { $html->loadXML($str); } else { $html->preserveWhiteSpace = true; $html->loadHTML($str); } libxml_clear_errors(); $dom_xpath = new DOMXPath($html); return new HtmlNode($html->documentElement, $dom_xpath); } public static function from_file($file, $xml = false) { $str = file_get_contents($file); return self::from_string($str, $xml); } // Converts a given CSS Selector expression to xpath expression. // This function is direct port of firebug's css to xpath convertor. public static function css_to_xpath($rule) { $reg_element = '/^([#.]?)([a-z0-9\\*_-]*)((\|)([a-z0-9\\*_-]*))?/i'; $reg_attr1 = '/^\[([^\]]*)\]/i'; $reg_attr2 = '/^\[\s*([^~=\s]+)\s*(~?=)\s*"([^"]+)"\s*\]/i'; $reg_attr3 = '/^\[\s*([^~=\s]+)\s*(~?=)\s*\'([^\']+)\'\s*\]/i'; $reg_attr4 = '/^\[\s*([^~=\s]+)\s*(~?=)\s*([^\]]+)\s*\]/i'; $reg_pseudo = '/^:([a-z_-]+)(\([a-z_-]+\))?/i'; $reg_combinator = '/^(\s*[>+\s])?/i'; $reg_comma = '/^\s*,/i'; $index = 1; $parts = array(".//", "*"); $last_rule = null; while ($rule && $rule !== $last_rule) { $last_rule = $rule; // Trim leading whitespace $rule = trim($rule); if (!$rule) break; // Match the element identifier preg_match($reg_element, $rule, $m); if ($m) { if (!$m[1]) { // XXXjoe Namespace ignored for now if (isset($m[5])) $parts[$index] = $m[5]; else $parts[$index] = $m[2]; } else if ($m[1] == '#') $parts[] = "[@id='" . $m[2] . "']"; else if ($m[1] == '.') $parts[] = "[contains(concat(' ',@class,' '), ' " . $m[2] . " ')]"; $rule = substr($rule, strlen($m[0])); } // Match attribute selectors preg_match($reg_attr4, $rule, $m); if(!$m) preg_match($reg_attr3, $rule, $m); if(!$m) preg_match($reg_attr2, $rule, $m); if ($m) { if ($m[2] == "~=") $parts[] = "[contains(concat(' ', @" . $m[1] . ", ' '), ' " . $m[3] . " ')]"; else $parts[] = "[@" . $m[1] . "='" . $m[3] . "']"; $rule = substr($rule, strlen($m[0])); } else { preg_match($reg_attr1, $rule, $m); if ($m) { $parts[] = "[@" . $m[1] . "]"; $rule = substr($rule, strlen($m[0])); } } // Skip over pseudo-classes and pseudo-elements, which are of no use to us preg_match($reg_pseudo, $rule, $m); while ($m) { // Handle Later // if($m[1] && $m[2]) // { // $m[2] = substr($m[2], 1, -1); // switch($m[1]) // { // case 'contains': // $parts[] = '[contains(translate(normalize-space(string(.)),"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz"),translate("'.$m[2].'","ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz"))]'; // } // } $rule = substr($rule, strlen($m[0])); preg_match($reg_pseudo, $rule, $m); } // Match combinators preg_match($reg_combinator, $rule, $m); if ($m && strlen($m[0])) { if (strpos($m[0], ">") !== false) $parts[] = "/"; else if (strpos($m[0], "+") !== false) $parts[] = "/following-sibling::"; else $parts[] = "//"; $index = count($parts); $parts[] = "*"; $rule = substr($rule, strlen($m[0])); } preg_match($reg_comma, $rule, $m); if ($m) { $parts[] = " | "; $parts[] = ".//"; $index = count($parts); $parts[] = "*"; $rule = substr($rule, strlen($m[0])); } } $xpath = implode("", $parts); return $xpath; } } class HtmlNode { private $dom_xpath; private $node; public function __construct($node, $dom_xpath = null) { $this->node = $node; if($dom_xpath) $this->dom_xpath = $dom_xpath; } // use $node->text for node's text. // use $node->html for node's inner HTML. // use $node->anything for node's attribute. public function __get($name) { if($name == 'text' || $name == 'plaintext') return $this->text(); else if($name == 'html') return $this->html(); else if($this->node->hasAttribute($name)) return $this->node->getAttribute($name); else return null; } // finds nodes by css selector expression. // returns an array of nodes if $idx is not given, otherwise returns a single node at index $idx. // returns null if node not found or error in selector expression. // $idx can be negative (find from last). public function find($query, $idx = null) { $xpath = HtmlParser::css_to_xpath($query); return $this->xpath($xpath, $idx); } // finds nodes by xpath expression. public function xpath($xpath, $idx = null) { $result = $this->dom_xpath->query($xpath, $this->node); if($idx === null) { if(!$result) return array(); return self::wrap_nodes($result, $this->dom_xpath); } else if($idx >= 0) { if(!$result) return null; return self::wrap_node($result->item($idx), $this->dom_xpath); } else { if(!$result) return null; return self::wrap_node($result->item($result->length + $idx), $this->dom_xpath); } } public function child($idx = null) { if(!$this->node->hasChildNodes()) return array(); $nodes = array(); foreach($this->node->childNodes as $node) { if($node->nodeType === XML_ELEMENT_NODE) $nodes[] = $node; } if($idx === null) { if(!$nodes) return array(); return self::wrap_nodes($nodes, $this->dom_xpath); } else if($idx >= 0) { if(!$nodes) return null; return self::wrap_node($nodes[$idx], $this->dom_xpath); } else { if(!$nodes) return null; return self::wrap_node($nodes[count($nodes) + $idx], $this->dom_xpath); } } public function has_child() { if($this->node->hasChildNodes()) { foreach($this->node->childNodes as $node) { if($node->nodeType === XML_ELEMENT_NODE) return true; } } return false; } public function first_child() { $node = $this->node->firstChild; while($node && $node->nodeType !== XML_ELEMENT_NODE) { $node = $node->nextSibling; } return self::wrap_node($node, $this->dom_xpath); } public function last_child() { $node = $this->node->lastChild; while($node && $node->nodeType !== XML_ELEMENT_NODE) { $node = $node->previousSibling; } return self::wrap_node($node, $this->dom_xpath); } public function parent() { $node = $this->node->parentNode; while($node && $node->nodeType !== XML_ELEMENT_NODE) { $node = $node->parentNode; } return self::wrap_node($node, $this->dom_xpath); } public function next() { $node = $this->node->nextSibling; while($node && $node->nodeType !== XML_ELEMENT_NODE) { $node = $node->nextSibling; } return self::wrap_node($node, $this->dom_xpath); } public function prev() { $node = $this->node->previousSibling; while($node && $node->nodeType !== XML_ELEMENT_NODE) { $node = $node->previousSibling; } return self::wrap_node($node, $this->dom_xpath); } public function text() { return $this->node->nodeValue; } public function html() { $tag = $this->node_name(); return preg_replace('@(^<' . $tag . '[^>]*>)|(</' . $tag . '>$)@', '', $this->outer_html()); } public function inner_html() { return $this->html(); } public function outer_html() { $doc = new DOMDocument(); $doc->appendChild($doc->importNode($this->node, TRUE)); $html = trim($doc->saveHTML()); return $html; } public function node_name() { return $this->node->nodeName; } // Wrap given DOMNodes in HtmlNode and return an array of them. private static function wrap_nodes($nodes, $dom_xpath = null) { $wrapped = array(); foreach($nodes as $node) { $wrapped[] = new HtmlNode($node, $dom_xpath); } return $wrapped; } // Wrap a given DOMNode in HtmlNode. private static function wrap_node($node, $dom_xpath = null) { if($node == null) return null; return new HtmlNode($node, $dom_xpath); } }

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.3.60.0120.00619.04
8.3.50.0120.00721.64
8.3.40.0120.00419.51
8.3.30.0080.01120.70
8.3.20.0040.00421.15
8.3.10.0080.00021.42
8.3.00.0030.00524.16
8.2.180.0100.01017.50
8.2.170.0160.00722.96
8.2.160.0070.00720.88
8.2.150.0030.00624.18
8.2.140.0080.00024.66
8.2.130.0000.00826.16
8.2.120.0040.00421.40
8.2.110.0100.00019.83
8.2.100.0060.00618.61
8.2.90.0030.00519.55
8.2.80.0060.00318.43
8.2.70.0030.00618.13
8.2.60.0040.00418.54
8.2.50.0060.00318.38
8.2.40.0120.00018.67
8.2.30.0030.00520.08
8.2.20.0030.00518.54
8.2.10.0030.00618.58
8.2.00.0030.00718.40
8.1.280.0030.01625.92
8.1.270.0040.00423.99
8.1.260.0040.00426.35
8.1.250.0040.00428.09
8.1.240.0030.00723.09
8.1.230.0040.00821.47
8.1.220.0000.00818.77
8.1.210.0060.00319.59
8.1.200.0070.00318.00
8.1.190.0040.00418.14
8.1.180.0080.00018.27
8.1.170.0030.00619.27
8.1.160.0080.00019.41
8.1.150.0080.00019.35
8.1.140.0050.00318.09
8.1.130.0050.00218.38
8.1.120.0050.00318.13
8.1.110.0000.00818.08
8.1.100.0040.00418.09
8.1.90.0060.00318.11
8.1.80.0080.00018.14
8.1.70.0000.00818.08
8.1.60.0030.00518.30
8.1.50.0040.00418.14
8.1.40.0030.00618.17
8.1.30.0060.00318.35
8.1.20.0000.00818.33
8.1.10.0000.00818.14
8.1.00.0040.00418.17
8.0.300.0050.00320.52
8.0.290.0000.00817.80
8.0.280.0030.00519.08
8.0.270.0060.00317.82
8.0.260.0030.00617.45
8.0.250.0000.00817.67
8.0.240.0000.00917.61
8.0.230.0050.00317.64
8.0.220.0040.00417.69
8.0.210.0070.00417.54
8.0.200.0050.00317.70
8.0.190.0090.00017.56
8.0.180.0000.00817.61
8.0.170.0030.00517.54
8.0.160.0000.00817.65
8.0.150.0050.00317.56
8.0.140.0060.00317.63
8.0.130.0030.00313.98
8.0.120.0090.00017.68
8.0.110.0050.00317.71
8.0.100.0040.00417.59
8.0.90.0080.00017.72
8.0.80.0090.00917.68
8.0.70.0090.00017.68
8.0.60.0000.00817.41
8.0.50.0030.00517.71
8.0.30.0070.01417.59
8.0.20.0080.01217.97
8.0.10.0000.00817.75
8.0.00.0080.01117.49
7.4.330.0060.00017.05
7.4.320.0000.00717.25
7.4.300.0000.00717.15
7.4.290.0060.00317.38
7.4.280.0000.00817.33
7.4.270.0040.00417.17
7.4.260.0060.00014.00
7.4.250.0000.00917.29
7.4.240.0080.00017.37
7.4.230.0080.00017.52
7.4.220.0110.00817.48
7.4.210.0110.00717.32
7.4.200.0040.00417.43
7.4.190.0080.00017.29
7.4.160.0120.00617.53
7.4.150.0130.01017.40
7.4.140.0100.00917.86
7.4.130.0050.01417.18
7.4.120.0100.00917.43
7.4.110.0040.01517.21
7.4.100.0070.01117.29
7.4.90.0030.01617.22
7.4.80.0130.00619.39
7.4.70.0150.00317.31
7.4.60.0180.00617.12
7.4.50.0040.00416.94
7.4.40.0060.01222.77
7.4.30.0110.00817.20
7.4.00.0030.01315.45
7.3.330.0000.00614.00
7.3.320.0060.00014.04
7.3.310.0030.00617.00
7.3.300.0030.00617.07
7.3.290.0060.00916.99
7.3.280.0100.01017.05
7.3.270.0070.01117.40
7.3.260.0120.01518.24
7.3.250.0080.01317.18
7.3.240.0060.01217.26
7.3.230.0060.01217.22
7.3.210.0150.00317.21
7.3.200.0040.01619.39
7.3.190.0100.01017.11
7.3.180.0090.00917.32
7.3.170.0030.01717.40
7.3.160.0130.00617.24
7.3.120.0040.01515.14
7.2.330.0060.01517.30
7.2.320.0100.01617.34
7.2.310.0070.01417.30
7.2.300.0140.00317.41
7.2.290.0060.01217.29
7.2.00.0040.01119.94
7.1.200.0030.01016.08
7.1.100.0040.01318.81
7.1.70.0060.00317.68
7.1.60.0030.01019.17
7.1.50.0200.01334.74
7.1.00.0000.05322.57
7.0.200.0060.00316.83
7.0.140.0130.06722.31
7.0.100.0200.07720.30
7.0.90.0100.08020.26
7.0.80.0070.07020.25
7.0.70.0200.07320.28
7.0.60.0030.08720.22
7.0.50.0030.08720.64
7.0.40.0070.08720.29
7.0.30.0070.07720.30
7.0.20.0070.08020.31
7.0.10.0030.06720.25
7.0.00.0230.02720.25
5.6.280.0030.07721.30
5.6.250.0100.08320.99
5.6.240.0070.05020.96
5.6.230.0200.07020.79
5.6.220.0030.08720.94
5.6.210.0130.04320.82
5.6.200.0070.08321.30
5.6.190.0170.08021.20
5.6.180.0100.07721.35
5.6.170.0070.08021.21
5.6.160.0100.08021.26
5.6.150.0030.07721.29
5.6.140.0130.08021.28
5.6.130.0100.04721.35
5.6.120.0170.07021.22
5.6.110.0130.03721.28
5.6.100.0170.07321.20
5.6.90.0100.08721.18
5.6.80.0100.07720.73
5.6.70.0100.05320.71
5.6.60.0070.05720.57
5.6.50.0100.04720.59
5.6.40.0130.05720.58
5.6.30.0030.05320.69
5.6.20.0070.07720.67
5.6.10.0130.07320.66
5.6.00.0170.06720.70
5.5.380.0100.06720.72
5.5.370.0170.06720.59
5.5.360.0070.08720.79
5.5.350.0100.07720.68
5.5.340.0230.07321.14
5.5.330.0130.07321.03
5.5.320.0100.07721.13
5.5.310.0030.04021.07
5.5.300.0070.07321.09
5.5.290.0200.03021.04
5.5.280.0030.08321.04
5.5.270.0100.07321.13
5.5.260.0070.04321.13
5.5.250.0070.08020.79
5.5.240.0170.06020.39
5.5.230.0100.07320.50
5.5.220.0130.07020.50
5.5.210.0100.06720.49
5.5.200.0130.06320.40
5.5.190.0170.06720.42
5.5.180.0030.08020.44
5.5.160.0130.07720.39
5.5.150.0070.07020.44
5.5.140.0100.06320.32
5.5.130.0100.07720.43
5.5.120.0070.08020.43
5.5.110.0000.07720.41
5.5.100.0100.06720.36
5.5.90.0070.07720.27
5.5.80.0070.08320.22
5.5.70.0100.08320.31
5.5.60.0070.04020.32
5.5.50.0030.08020.36
5.5.40.0230.04020.27
5.5.30.0100.03720.32
5.5.20.0170.05020.34
5.5.10.0030.04720.22
5.5.00.0130.07020.28
5.4.450.0100.07319.59
5.4.440.0000.08719.43
5.4.430.0070.07319.66
5.4.420.0200.05319.71
5.4.410.0170.05319.56
5.4.400.0030.06019.20
5.4.390.0130.07019.13
5.4.380.0200.06719.11
5.4.370.0070.08319.27
5.4.360.0100.07719.26
5.4.350.0100.06719.30
5.4.340.0070.07319.10
5.4.320.0100.06719.31
5.4.310.0070.07019.35
5.4.300.0130.04719.29
5.4.290.0070.04719.22
5.4.280.0070.08319.31
5.4.270.0030.04019.38
5.4.260.0100.04719.10
5.4.250.0070.04319.40
5.4.240.0030.06719.32
5.4.230.0130.07319.34
5.4.220.0030.04719.34
5.4.210.0030.07019.38
5.4.200.0070.08319.33
5.4.190.0030.07019.30
5.4.180.0070.07019.09
5.4.170.0070.06319.21
5.4.160.0200.06719.27
5.4.150.0030.04019.37
5.4.140.0070.07016.70
5.4.130.0130.07016.50
5.4.120.0100.06716.59
5.4.110.0070.07316.67
5.4.100.0070.07716.57
5.4.90.0000.08016.72
5.4.80.0070.03716.77
5.4.70.0070.04716.77
5.4.60.0030.05016.64
5.4.50.0100.07316.69
5.4.40.0000.05316.61
5.4.30.0030.07716.68
5.4.20.0170.05716.72
5.4.10.0100.05316.56
5.4.00.0000.06715.96
5.3.290.0030.07714.91
5.3.280.0130.07014.84
5.3.270.0070.07314.93
5.3.260.0130.05015.01
5.3.250.0030.06714.96
5.3.240.0070.07714.93
5.3.230.0100.07014.92
5.3.220.0030.06314.98
5.3.210.0030.04014.89
5.3.200.0170.06714.91
5.3.190.0070.07314.97
5.3.180.0030.04314.88
5.3.170.0030.08014.89
5.3.160.0030.04714.82
5.3.150.0000.07314.93
5.3.140.0000.06014.88
5.3.130.0030.06314.99
5.3.120.0070.06014.80
5.3.110.0130.06314.95
5.3.100.0100.03314.46
5.3.90.0130.06314.37
5.3.80.0070.06014.28
5.3.70.0170.06314.32
5.3.60.0030.06314.19
5.3.50.0070.07314.29
5.3.40.0170.05014.28
5.3.30.0100.07014.19
5.3.20.0070.07013.94
5.3.10.0070.05313.90
5.3.00.0100.04313.84

preferences:
70.93 ms | 401 KiB | 5 Q