3v4l.org

run code in 300+ PHP versions simultaneously
<?php // Define a test HTML document containing two tables. Note that the first table // has a row that combined <th> and <td> cells, while the second one only has // <th> cells. $xhtml = <<<XHTML <html> <head> <title>Table test page</title> </head> <body> <table> <tr> <th>Cell 1</th> <td>Cell 2</td> </tr> </table> <table> <tr> <th>Cell 1</th> <th>Cell 2</th> </tr> </table> </body> </html> XHTML; $document = new DOMDocument(); $document->loadXML($xhtml); $xpath = new DOMXPath($document); $xpath = function ($query) use ($xpath) { echo $query . "\n"; $result = $xpath->query($query); if (method_exists($result, 'count')) { $count = $result->count(); } else { // Fallback for older PHP versions that don't have DomNodeList::count(). $result_array = iterator_to_array($result); // Filter out any bogus results that equal `NULL`. $result_array = array_filter($result_array); $count = count($result_array); } echo $count . ' result' . ($count != 1 ? 's' : '') . ($count ? ':' : '') . "\n"; foreach ($result as $element) { $document = new DOMDocument(); $document->appendChild($document->importNode($element->cloneNode(TRUE), TRUE)); echo $document->saveHTML(); } echo "\n"; }; echo "I am using the following XPath expression to select table cells from\n"; echo "the first row of the first table, by combining the results for <th>\n"; echo "and <td>. This works fine, I get both cells back.\n"; echo "Note that the first table combines <th> and <td> in a single row.\n"; $xpath('(((descendant-or-self::html/descendant-or-self::table)[1]//tr)[1]/td|((descendant-or-self::html/descendant-or-self::table)[1]//tr)[1]/th)'); echo "When I try to get the first cell by appending [1] to the expression\n"; echo "I get the second cell back instead of the first. Why?\n"; echo "The expected result of this expression is '<th>Cell 1</th>'\n"; $xpath('(((descendant-or-self::html/descendant-or-self::table)[1]//tr)[1]/td|((descendant-or-self::html/descendant-or-self::table)[1]//tr)[1]/th)[1]'); echo "Appending [2] yields the second cell successfully. But why not the first?\n"; $xpath('(((descendant-or-self::html/descendant-or-self::table)[1]//tr)[1]/td|((descendant-or-self::html/descendant-or-self::table)[1]//tr)[1]/th)[2]'); echo "Similarly, for the second table I can get all cells with this expression.\n"; echo "The second table only contains <th> cells in the first row.\n"; $xpath('(((descendant-or-self::html/descendant-or-self::table)[2]//tr)[1]/td|((descendant-or-self::html/descendant-or-self::table)[2]//tr)[1]/th)'); echo "However, when I append [1] to get only the first cell back, I get an empty result.\n"; echo "The expected result for this expression is '<th>Cell 1</th>'\n"; $xpath('(((descendant-or-self::html/descendant-or-self::table)[2]//tr)[1]/td|((descendant-or-self::html/descendant-or-self::table)[2]//tr)[1]/th)[1]'); echo "The second cell can be retrieved successfully by appending [2].\n"; echo "But why not the first?\n"; $xpath('(((descendant-or-self::html/descendant-or-self::table)[2]//tr)[1]/td|((descendant-or-self::html/descendant-or-self::table)[2]//tr)[1]/th)[2]'); echo "Note that by replacing the first 'descendant-or-self' with '//' the expression\n"; echo "seems to work as expected in all cases for both the first and second table:\n"; $xpath('(((//html/descendant-or-self::table)[1]//tr)[1]/td|((//html/descendant-or-self::table)[1]//tr)[1]/th)'); $xpath('(((//html/descendant-or-self::table)[1]//tr)[1]/td|((//html/descendant-or-self::table)[1]//tr)[1]/th)[1]'); $xpath('(((//html/descendant-or-self::table)[1]//tr)[1]/td|((//html/descendant-or-self::table)[1]//tr)[1]/th)[2]'); $xpath('(((//html/descendant-or-self::table)[2]//tr)[1]/td|((//html/descendant-or-self::table)[2]//tr)[1]/th)'); $xpath('(((//html/descendant-or-self::table)[2]//tr)[1]/td|((//html/descendant-or-self::table)[2]//tr)[1]/th)[1]'); $xpath('(((//html/descendant-or-self::table)[2]//tr)[1]/td|((//html/descendant-or-self::table)[2]//tr)[1]/th)[2]');

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.4.130.0060.00418.21
8.4.120.0120.00920.63
8.4.110.0060.00422.95
8.4.100.0060.00518.07
8.4.90.0130.01021.12
8.4.80.0080.01119.34
8.4.70.0140.00719.22
8.4.60.0060.00321.18
8.4.50.0050.00718.88
8.4.40.0130.00319.62
8.4.30.0100.00718.17
8.4.20.0140.00719.74
8.4.10.0170.00318.82
8.3.260.0100.01116.77
8.3.250.0110.00819.36
8.3.240.0080.01417.04
8.3.230.0110.00916.97
8.3.220.0040.00419.50
8.3.210.0070.00717.02
8.3.200.0100.01017.19
8.3.190.0120.00817.66
8.3.180.0100.00918.45
8.3.170.0150.00317.69
8.3.160.0100.01018.74
8.3.150.0160.00317.54
8.3.140.0060.00317.63
8.3.130.0060.00318.77
8.3.120.0030.00621.02
8.3.110.0130.00720.94
8.3.100.0030.00724.06
8.3.90.0050.00326.77
8.3.80.0060.00618.68
8.3.70.0110.01118.52
8.3.60.0130.00618.93
8.3.50.0090.00518.63
8.3.40.0080.00819.35
8.3.30.0090.00619.14
8.3.20.0030.00522.33
8.3.10.0040.00422.32
8.3.00.0040.00420.06
8.2.290.0120.00820.81
8.2.280.0110.00918.57
8.2.270.0100.01017.58
8.2.260.0110.00016.88
8.2.250.0150.00418.81
8.2.240.0100.00719.46
8.2.230.0040.01122.58
8.2.220.0030.00737.54
8.2.210.0000.01526.77
8.2.200.0030.00716.88
8.2.190.0130.00316.88
8.2.180.0000.01518.89
8.2.170.0040.01522.96
8.2.160.0090.00620.95
8.2.150.0060.00325.66
8.2.140.0080.00024.66
8.2.130.0080.00019.82
8.2.120.0040.00426.35
8.2.110.0100.00020.67
8.2.100.0060.00618.16
8.2.90.0030.00618.25
8.2.80.0040.00419.28
8.2.70.0000.00818.18
8.2.60.0030.00618.30
8.2.50.0030.00518.47
8.2.40.0030.00620.92
8.2.30.0000.00819.75
8.2.20.0040.00418.43
8.2.10.0000.01018.50
8.2.00.0080.00018.51
8.1.330.0060.01422.21
8.1.320.0100.01216.50
8.1.310.0050.00318.77
8.1.300.0030.00718.17
8.1.290.0060.00330.84
8.1.280.0120.00925.92
8.1.270.0040.00423.99
8.1.260.0000.00826.35
8.1.250.0000.01028.09
8.1.240.0040.00824.16
8.1.230.0120.00021.47
8.1.220.0040.00418.04
8.1.210.0030.00618.77
8.1.200.0030.00517.73
8.1.190.0000.00817.60
8.1.180.0040.00418.10
8.1.170.0030.00619.04
8.1.160.0040.00419.28
8.1.150.0000.00719.41
8.1.140.0030.00618.13
8.1.130.0000.00719.40
8.1.120.0000.00717.79
8.1.110.0000.00917.75
8.1.100.0030.00517.82
8.1.90.0050.00517.94
8.1.80.0000.00817.77
8.1.70.0040.00417.80
8.1.60.0060.00318.02
8.1.50.0060.00617.79
8.1.40.0030.00617.93
8.1.30.0060.00518.09
8.1.20.0030.00618.00
8.1.10.0040.00717.84
8.1.00.0040.00417.95
8.0.300.0050.00318.77
8.0.290.0000.00817.25
8.0.280.0000.00718.82
8.0.270.0000.00717.60
8.0.260.0050.00217.71
8.0.250.0000.00717.32
8.0.240.0020.00517.34
8.0.230.0070.00017.47
8.0.220.0040.00417.42
8.0.210.0040.00417.31
8.0.200.0080.00017.28
8.0.190.0000.00817.38
8.0.180.0000.00817.29
8.0.170.0040.00717.29
8.0.160.0020.00517.38
8.0.150.0000.00717.19
8.0.140.0040.00417.36
8.0.130.0000.00713.78
8.0.120.0030.00617.29
8.0.110.0050.00317.27
8.0.100.0040.00417.40
8.0.90.0030.00617.27
8.0.80.0030.02017.42
8.0.70.0030.00517.28
8.0.60.0040.00417.29
8.0.50.0030.00517.30
8.0.30.0100.00917.50
8.0.20.0120.00917.46
8.0.10.0040.00417.54
8.0.00.0130.01017.23
7.4.330.0000.00515.55
7.4.320.0000.00716.96
7.4.300.0000.00716.84
7.4.290.0030.00616.91
7.4.280.0000.00816.83
7.4.270.0050.00316.84
7.4.260.0030.00316.77
7.4.250.0060.00316.97
7.4.240.0080.00016.85
7.4.230.0050.00217.01
7.4.220.0030.00517.01
7.4.210.0120.00617.09
7.4.200.0050.00217.00
7.4.160.0100.00816.94
7.4.140.0120.01017.86
7.4.130.0130.00616.89
7.4.120.0110.01016.96
7.4.110.0160.00316.89
7.4.100.0130.00416.88
7.4.90.0100.01616.77
7.4.80.0090.01219.39
7.4.70.0150.00416.95
7.4.60.0130.00416.75
7.4.50.0040.01116.93
7.4.40.0110.00817.06
7.4.00.0120.00315.16
7.3.330.0030.00313.49
7.3.320.0000.00713.72
7.3.310.0070.00016.78
7.3.300.0030.00316.77
7.3.290.0080.00016.66
7.3.280.0110.00416.81
7.3.260.0090.00916.77
7.3.240.0120.00816.96
7.3.230.0090.01116.75
7.3.210.0090.00916.81
7.3.200.0030.01417.06
7.3.190.0080.01016.96
7.3.180.0070.01116.95
7.3.170.0130.00516.64
7.3.160.0100.00716.99
7.3.10.0100.00716.88
7.3.00.0000.01416.69
7.2.330.0120.00816.99
7.2.320.0060.01216.88
7.2.310.0100.01016.96
7.2.300.0130.01017.02
7.2.290.0030.01717.18
7.2.130.0060.01017.13
7.2.120.0060.00917.25
7.2.110.0090.00617.08
7.2.100.0000.01217.22
7.2.90.0060.00917.29
7.2.80.0060.00917.39
7.2.70.0090.00316.97
7.2.60.0070.00716.99
7.2.50.0100.00317.12
7.2.40.0450.01417.81
7.2.30.0480.00817.57
7.2.20.0070.01417.81
7.2.10.0510.00617.72
7.2.00.0120.01017.38
7.1.250.0040.01115.88
7.1.200.0000.01015.91
7.1.160.0740.01516.84
7.1.150.0090.01417.08
7.1.140.0790.01417.18
7.1.130.0750.01317.21
7.1.120.0540.01317.06
7.1.110.0700.01216.39
7.1.100.1060.01216.51
7.1.90.1000.01216.45
7.1.80.0790.01116.54
7.1.70.1150.01515.38
7.1.60.1120.01833.38
7.1.50.1340.00933.28
7.1.40.1540.02232.79
7.1.30.1570.02032.75
7.1.20.1190.01932.94
7.1.10.0930.01915.07
7.1.00.0640.01715.13

preferences:
28.83 ms | 403 KiB | 5 Q