<?php
if (ob_get_level() == 0) ob_start();
if (function_exists('apache_setenv')) {
    apache_setenv('no-gzip', '1');
}
ini_set('zlib.output_compression', 'Off');
header('Content-Encoding: none');
header('Connection: close');
ob_start();
$has_gd = extension_loaded('gd') ? "yes" : "no";
$has_imagick = extension_loaded('imagick') ? "yes" : "no";
$has_zstd = extension_loaded('zstd') ? "yes" : "no";
$has_lz4 = extension_loaded('lz4') ? "yes" : "no";
$has_msgpack = extension_loaded('msgpack') ? "yes" : "no";
$has_dom = extension_loaded('dom') ? "yes" : "no";
$has_simplexml = extension_loaded('simplexml') ? "yes" : "no";
$has_intl = extension_loaded('intl') ? "yes" : "no";
$has_jsond = extension_loaded('jsond') ? "yes" : "no";
$qr = 
    "1111111000011010001111111".
    "1000001001100010001000001".
    "1011101000001000101011101".
    "1011101010001100101011101".
    "1011101011000100101011101".
    "1000001000011110001000001".
    "1111111010101010101111111".
    "0000000000110011000000000".
    "1100011101010111100011000".
    "1010000111001001000111110".
    "0011111000100111101001011".
    "0000000101001010111101001".
    "0100111001011011101000001".
    "1101000110000101100100010".
    "1010111010011111001111011".
    "1010100001110011010010101".
    "1010111111111111111110100".
    "0000000011001001100010100".
    "1111111011010010101011001".
    "1000001010110011100010011".
    "1011101000011111111111100".
    "1011101001111111011101011".
    "1011101000100110100100101".
    "1000001010100010100110001".
    "1111111011101000100001001";

class BenchmarkTimer {
    private $startTime;
    private $results = [];
    private $totalTime = 0;
    public function start() {
        list($usec, $sec) = explode(" ", microtime());
        $this->startTime = ((float) $usec + (float) $sec);
    }
    public function stop($title) {
        list($usec, $sec) = explode(" ", microtime());
        $time = ((float) $usec + (float) $sec) - $this->startTime;
        $this->results[$title] = $time;
        $this->totalTime += $time;
        return $time;
    }
    public function getResults() {
        return $this->results;
    }
    public function getTotalTime() {
        return $this->totalTime;
    }
}
$timer = new BenchmarkTimer();
ini_set('max_execution_time', 600); 
ini_set('memory_limit', '256M');    
$hostInfo = @file_get_contents('https://ipinfo.io/org');
$hostOrg = $hostInfo ? trim($hostInfo) : 'Unknown';
$hostLocation = @file_get_contents('https://ipinfo.io/loc');
$hostLoc = $hostLocation ? trim($hostLocation) : 'Unknown';
$stringTest = "    the quick <b>brown</b> fox jumps <i>over</i> the lazy dog and eat <span>lorem ipsum</span><br/> Valar morghulis  <br/>\n\r hello \n we are out of spoons, Neo! <span class='alert alert-danger'>We are out of spoons, Neo!</span>      ";
$string_complex = str_repeat($stringTest, 2);
$regexPattern = '/[\s,]+/';
$array_test = range(0, 999);
$json_data = [
    'menu' => [
        'id' => 'file',
        'value' => 'File',
        'popup' => [
            'menuitem' => [
                ['value' => 'New', 'onclick' => 'CreateNewDoc()'],
                ['value' => 'Open', 'onclick' => 'OpenDoc()'],
                ['value' => 'Close', 'onclick' => 'CloseDoc()']
            ]
        ]
    ]
];
$run_times = 50000;
$run_times_slow = 5000;
$run_times_slowest = 2500;
function calculateMetrics($time, $iterations, $cpuMhz = null) {
    $opsPerSec = $iterations / $time;
    $opsPerSecPerMhz = $cpuMhz ? ($opsPerSec / $cpuMhz) : null;
    return [
        'time' => $time,
        'ops_per_sec' => $opsPerSec,
        'ops_per_sec_mhz' => $opsPerSecPerMhz
    ];
}
function getDetailedCpuInfo() {
    $cpuInfo = [
        'cores' => 1,
        'frequency' => 0.0
    ];
    
    if (is_readable('/proc/cpuinfo')) {
        $cpuinfo = file_get_contents('/proc/cpuinfo');
        
        preg_match_all('/^processor/m', $cpuinfo, $matches);
        $cpuInfo['cores'] = count($matches[0]);
        
        if (preg_match('/cpu MHz\s+:\s+(.+)$/m', $cpuinfo, $matches)) {
            $cpuInfo['frequency'] = (float)$matches[1];
        }
    }
    
    if ($cpuInfo['cores'] === 1) {
        if (function_exists('shell_exec')) {
            $cores = (int)trim(shell_exec('nproc 2>/dev/null'));
            if ($cores > 0) {
                $cpuInfo['cores'] = $cores;
            }
            
            $lscpu = shell_exec('lscpu 2>/dev/null');
            if (preg_match('/CPU MHz:\s+(.+)$/m', $lscpu, $matches)) {
                $cpuInfo['frequency'] = (float)$matches[1];
            }
        }
    }
    
    return $cpuInfo;
}
function create_test_array($size) {
    $arr = [];
    for ($i = 0; $i < $size; $i++) {
        $arr[$i] = $i;
    }
    return $arr;
}
function runTest($timer, $testName, $testFunction, $iterations) {
    $timer->start();
    for ($i = 0; $i < $iterations; $i++) {
        $testFunction();
    }
    return $timer->stop($testName);
}
function getSystemMemory() {
    if (PHP_OS === 'Linux') {
        $methods = [
            'free -b | grep Mem: | awk \'{print $2}\'',
            'cat /proc/meminfo | grep MemTotal',
            'vmstat -s | grep "total memory"',
            'sysctl -n hw.memsize 2>/dev/null',
            'wmic computersystem get totalphysicalmemory 2>/dev/null'
        ];
        
        foreach ($methods as $cmd) {
            $output = @shell_exec($cmd);
            if ($output && preg_match('/(\d+)/', $output, $matches)) {
                return round($matches[1] / 1024 / 1024 / 1024, 1) . 'GB';
            }
        }
        return 'Unknown';
    }
    return 'Unknown';
}
$cpuInfo = getDetailedCpuInfo();
$cpuMhz = $cpuInfo['frequency'];
$tests = [
    'php_features' => [
        ['PHP: Exception', function() {
            try {
                throw new Exception('Test Exception');
            } catch (Exception $e) {
                $message = $e->getMessage();
            }
        }, $run_times],
        ['PHP: Type Hints', function() {
            $testFunc = function(string $a, int $b): string {
                return $a . $b;
            };
            $testFunc("test", 123);
        }, $run_times],
        ['PHP: OOP Public Properties', function() {
            $obj = new class { public $number = 0; };
            for ($i = 0; $i < 50; $i++) {
                $obj->number = $i;
                $dummy = $obj->number;
            }
        }, $run_times],
        ['PHP: OOP Getter/Setter', function() {
            $obj = new class {
                private $number = 0;
                public function getNumber() { return $this->number; }
                public function setNumber($n) { $this->number = $n; }
            };
            for ($i = 0; $i < 50; $i++) {
                $obj->setNumber($i);
                $dummy = $obj->getNumber();
            }
        }, $run_times],
        ['PHP: Magic Methods', function() {
            $obj = new class {
                private $number = 0;
                public function __get($n) { return $this->number; }
                public function __set($n, $v) { $this->number = $v; }
            };
            for ($i = 0; $i < 50; $i++) {
                $obj->number = $i;
                $dummy = $obj->number;
            }
        }, $run_times],
        ['PHP: Null Coalesce', function() {
            $arr = [0 => 0, 2 => 2, 4 => 4];
            for ($i = 0; $i < 50; $i++) {
                $dummy = $arr[$i % 5] ?? 0;
            }
        }, $run_times],
        ['PHP: Spaceship Operator', function() {
            for ($i = 0; $i < 50; $i++) {
                $dummy = $i % 5 <=> 2;
            }
        }, $run_times],
    ],
    'math' => [
        ['Math: Simple', function() { 
            $a = 0;
            for ($i = 0; $i < 50; $i++) {
                $a += $i;
                $a *= 2;
                $a -= $i;
                $a /= 2;
            }
        }, $run_times],
        ['Math: Complex', function() {
            $a = 0;
            for ($i = 0; $i < 50; $i++) {
                $a += sin($i) * cos($i);
                $a *= exp($i/1000);
                $a = sqrt($a * $a);
            }
        }, $run_times],
        ['Math: Increment', function() {
            $a = 0;
            for ($i = 0; $i < 50; $i++) {
                ++$a;
                ++$a;
                ++$a;
                ++$a;
            }
        }, $run_times],
        ['Math: Decrement', function() {
            $a = 1000;
            for ($i = 0; $i < 50; $i++) {
                --$a;
                --$a;
                --$a;
                --$a;
            }
        }, $run_times],
    ],
    'string' => [
        ['String: Concatenation', function() use ($stringTest) {
            $str = '';
            for ($i = 0; $i < 50; $i++) {
                $str .= $stringTest;
            }
        }, $run_times],
        ['String: str_replace', function() use ($string_complex) {
            str_replace(
                ['quick', 'brown', 'fox', 'lazy'],
                ['slow', 'black', 'bear', 'active'],
                $string_complex
            );
        }, $run_times],
        ['String: Regular Expression', function() use ($string_complex, $regexPattern) {
            preg_match_all($regexPattern, $string_complex, $matches);
        }, $run_times],
        ['String: Strpos', function() use ($string_complex) {
            strpos($string_complex, 'quick');
            strpos($string_complex, 'brown');
            strpos($string_complex, 'fox');
            strpos($string_complex, 'lazy');
        }, $run_times],
        ['String: Explode', function() use ($string_complex) {
            explode(' ', $string_complex);
        }, $run_times],
    ],
    'array' => [
        ['Array: Loop', function() use ($array_test) {
            foreach ($array_test as $key => $value) {
                $dummy = $key + $value;
            }
        }, $run_times],
        ['Array: Sorting', function() use ($array_test) {
            $arr = $array_test;
            sort($arr);
        }, $run_times_slow],
        ['Array: Complex Sort', function() use ($array_test) {
            $arr = $array_test;
            usort($arr, function($a, $b) {
                return strlen((string)$a) - strlen((string)$b);
            });
        }, $run_times_slow],
        ['Array: Fill', function() {
            $arr = array_fill(0, 10000, 'test');
        }, $run_times_slow],
        ['Array: Unset', function() {
            $arr = range(0, 500);
            for ($i = 0; $i < 500; $i++) {
                unset($arr[$i]);
            }
        }, $run_times_slow],
        ['Array: Copy', function() use ($array_test) {
            $arr = $array_test;
            $copy = $arr;
        }, $run_times],
    ],
    'crypto' => [
        ['Hash: MD5', function() use ($string_complex) {
            md5($string_complex);
        }, $run_times],
        ['Hash: SHA256', function() use ($string_complex) {
            hash('sha256', $string_complex);
        }, $run_times],
        ['Crypto: Password Hash', function() {
            if (function_exists('password_hash')) {
                $hash = password_hash('test_password', PASSWORD_DEFAULT, ['cost' => 4]);
                password_verify('test_password', $hash);
            }
        }, $run_times_slow / 10],
    ],
    'file' => [
        ['File: Stream Operations', function() use ($string_complex) {
            $stream = fopen('php://memory', 'r+');
            fwrite($stream, $string_complex);
            rewind($stream);
            fread($stream, strlen($string_complex));
            fclose($stream);
        }, $run_times_slow],
        ['File: Memory Stream', function() use ($string_complex) {
            $temp = fopen('php://temp', 'r+');
            fwrite($temp, $string_complex);
            rewind($temp);
            fread($temp, strlen($string_complex));
            fclose($temp);
        }, $run_times_slow],
    ],
    
    'multibyte' => [
        ['String: Multibyte', function() use ($string_complex) {
            if (function_exists('mb_strlen')) {
                mb_strlen($string_complex);
                mb_strtoupper($string_complex);
                mb_substr($string_complex, 5, 10);
            }
        }, $run_times],
    ],
    'compression' => [
        ['Compression: GZIP', function() use ($string_complex) {
            if (function_exists('gzencode')) {
                $compressed = gzencode($string_complex, 9);
                $decompressed = gzdecode($compressed);
            }
        }, $run_times],
        ['Compression: GZIP Raw', function() use ($string_complex) {
            if (function_exists('gzcompress')) {
                $compressed = gzcompress($string_complex, 9);
                $decompressed = gzuncompress($compressed);
            }
        }, $run_times],
        ['Compression: Brotli', function() use ($string_complex) {
            if (function_exists('brotli_compress')) {
                $compressed = brotli_compress($string_complex, 11);
                $decompressed = brotli_uncompress($compressed);
            }
        }, $run_times],
        ['Compression: Zstd', function() use ($has_zstd, $string_complex) {
            if ($has_zstd === "yes") {
                $compressed = zstd_compress($string_complex, 22);
                $decompressed = zstd_uncompress($compressed);
            }
        }, $run_times],
        ['Compression: LZ4', function() use ($has_lz4, $string_complex) {
            if ($has_lz4 === "yes") {
                $compressed = lz4_compress($string_complex);
                $decompressed = lz4_uncompress($compressed);
            }
        }, $run_times],
        ['Compression: BZip2', function() use ($string_complex) {
            if (function_exists('bzcompress')) {
                $compressed = bzcompress($string_complex, 9);
                $decompressed = bzdecompress($compressed);
            }
        }, $run_times],
    ],
    'image' => [
        ['Image: GD QR Code', function() use ($has_gd, $qr) {
            if ($has_gd === "yes") {
                $size = 25;
                $dot = 9;
                $img = imagecreatetruecolor($size * $dot, $size * $dot);
                imagealphablending($img, true);
                imagesavealpha($img, true);
                $back = imagecolorallocatealpha($img, 0, 0, 0, 127);
                $dots = imagecolorallocatealpha($img, 0, 64, 127, 64);
                imagefill($img, 0, 0, $back);
                for ($y = 0, $i = 0; $y < $size; $y++) {
                    for ($x = 0; $x < $size; $x++, $i++) {
                        if ($qr[$i] == '1') {
                            imagefilledrectangle(
                                $img, 
                                $x * $dot, 
                                $y * $dot, 
                                ($x + 1) * $dot - 1, 
                                ($y + 1) * $dot - 1, 
                                $dots
                            );
                        }
                    }
                }
                imagejpeg($img, "/dev/null", 75);
                imagedestroy($img);
            }
        }, $run_times_slowest],
        ['Image: ImageMagick QR Code', function() use ($has_imagick, $qr) {
            if ($has_imagick === "yes") {
                $size = 25;
                $dot = 9;
                $imgW = $imgH = $size;
                $pixelPerPoint = 9;
                $outerFrame = 1;
                $q = 75;
                $col = [
                    new ImagickPixel("white"),
                    new ImagickPixel("black")
                ];
                
                $image = new Imagick();
                $image->newImage($imgW, $imgH, $col[0]);
                
                $image->setCompressionQuality($q);
                $image->setImageFormat('jpeg');
                
                $draw = new ImagickDraw();
                $draw->setFillColor($col[1]);
                for ($y = 0, $i = 0; $y < $size; $y++) {
                    for ($x = 0; $x < $size; $x++, $i++) {
                        if ($qr[$i] == '1') {
                            $draw->point($x, $y);
                        }
                    }
                }
                
                $image->drawImage($draw);
                $image->borderImage($col[0], $outerFrame, $outerFrame);
                $image->scaleImage($imgW * $pixelPerPoint, 0);
                $image->writeImages("/dev/null", true);
                $draw->destroy();
                $image->destroy();
            }
        }, $run_times_slowest],
    ],
    'xml' => [
        ['XML: DOM Advanced', function() use ($has_dom, $string_complex) {
            if ($has_dom === "yes") {
                $doc = new DOMDocument();
                $doc->loadHTML($string_complex);
                $xpath = new DOMXPath($doc);
                $elements = $xpath->query('//span');
                foreach ($elements as $element) {
                    $element->setAttribute('class', 'test');
                }
            }
        }, $run_times_slow],
        ['XML: SimpleXML', function() use ($has_simplexml) {
            if ($has_simplexml === "yes") {
                $xml = simplexml_load_string('<?xml version="1.0"?><root><test>value</test></root>');
                $xml->test = 'new value';
                $xml->asXML();
            }
        }, $run_times],
    ],
    'intl' => [
        ['Intl: Collation', function() use ($has_intl) {
            if ($has_intl === "yes") {
                $coll = new Collator('en_US');
                $array = ['apple', 'Apple', 'APPLE', 'apples'];
                $coll->sort($array);
            }
        }, $run_times],
        ['Intl: DateTime', function() use ($has_intl) {
            if ($has_intl === "yes") {
                $fmt = new IntlDateFormatter(
                    'en_US',
                    IntlDateFormatter::FULL,
                    IntlDateFormatter::FULL,
                    'America/Los_Angeles'
                );
                $fmt->format(time());
            }
        }, $run_times],
        ['Intl: Number Format', function() use ($has_intl) {
            if ($has_intl === "yes") {
                $fmt = new NumberFormatter('en_US', NumberFormatter::DECIMAL);
                for ($i = 0; $i < 50; $i++) {
                    $fmt->format($i / 100);
                }
            }
        }, $run_times_slow],
    ],
    'serialization' => [
        ['Serialize: PHP', function() use ($array_test) {
            serialize($array_test);
        }, $run_times],
        ['Serialize: JSON', function() use ($json_data) {
            json_encode($json_data);
            json_decode(json_encode($json_data), true);
        }, $run_times],
        ['Serialize: igbinary', function() use ($array_test) {
            if (extension_loaded('igbinary')) {
                $serialized = igbinary_serialize($array_test);
                igbinary_unserialize($serialized);
            }
        }, $run_times],
        ['Serialize: MsgPack', function() use ($has_msgpack, $array_test) {
            if ($has_msgpack === "yes") {
                $packed = msgpack_pack($array_test);
                $unpacked = msgpack_unpack($packed);
            }
        }, $run_times],
    ],
];
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PHP Benchmark Performance Test</title>
    <style>
    .container,.timer-main{flex-direction:column;display:flex}.header,.test-results-table tfoot td,.test-results-table th{background:linear-gradient(to right,#1e293b,#1e293b99)}.test-results-table thead,.timer-score{border-bottom:1px solid rgba(56,189,248,.1)}*{margin:0;padding:0;box-sizing:border-box;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}body{background:#0f172a;color:#fff;min-height:100vh;line-height:1.5}.container{height:100vh;max-width:1280px;margin:0 auto;padding:1.25rem;gap:1.25rem}.header{padding:1rem 1.5rem;border-radius:.5rem;border:1px solid rgba(56,189,248,.1);box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.title{display:flex;align-items:baseline;gap:.5rem}.title h1{font-size:1.25rem;color:#38bdf8;letter-spacing:-.025em}.subtitle{color:#64748b;font-size:.875rem}.digital-timer,.grade-display{font-size:2.5rem;font-weight:700;letter-spacing:-.025em;text-shadow:0 0 15px currentColor;transition:color .3s}.system-info{background:linear-gradient(to bottom right,#1e293b,#1e293bcc);border-radius:.5rem;padding:1.5rem;border:1px solid rgba(56,189,248,.1);box-shadow:0 4px 6px rgba(0,0,0,.1),inset 0 1px 0 rgba(255,255,255,.05)}.timer-score{position:relative;display:flex;justify-content:space-between;align-items:center;padding-bottom:1.5rem;margin-bottom:1.5rem}.timer-container{display:flex;align-items:center;gap:2rem}.timer-main{align-items:flex-start}.digital-timer{color:#38bdf8}.grade-container{text-align:center;display:flex;flex-direction:column;align-items:center;gap:.5rem}.grade-display{line-height:1}.grade-description{font-size:.75rem;text-transform:uppercase;letter-spacing:.1em;opacity:.9}.server-info{display:grid;grid-template-columns:repeat(3,1fr);gap:2rem;color:#e2e8f0;font-size:.875rem}.content{flex:1;min-height:0;display:flex;flex-direction:column;gap:1.25rem}.table-container{height:65vh;background:#1e293b;border-radius:.5rem;border:1px solid rgba(56,189,248,.1);display:flex;flex-direction:column;overflow:hidden;box-shadow:0 4px 6px rgba(0,0,0,.1);margin-top:1.25rem}.test-results-table{width:100%;border-collapse:separate;border-spacing:0;font-size:.8125rem;border-radius:.5rem;background:linear-gradient(to bottom,#1e293b,#1e293bcc);box-shadow:0 4px 6px rgba(0,0,0,.1),inset 0 1px 0 rgba(255,255,255,.05);border:1px solid rgba(56,189,248,.1)}.test-results-table thead tr:first-child th:first-child{border-top-left-radius:.5rem}.test-results-table thead tr:first-child th:last-child{border-top-right-radius:.5rem}.test-results-table tfoot tr:last-child td:first-child{border-bottom-left-radius:.5rem}.test-results-table tfoot tr:last-child td:last-child{border-bottom-right-radius:.5rem}.test-results-table tbody{display:block;overflow-y:auto;height:calc(65vh - 7rem);scrollbar-width:thin;scrollbar-color:rgba(56,189,248,0.2) #1e293b}.test-results-table tfoot,.test-results-table thead{display:table;width:calc(100% - 8px);table-layout:fixed}.test-results-table tbody tr{display:table;width:100%;table-layout:fixed;transition:background-color .2s}.test-results-table td,.test-results-table th{width:25%;padding:.5rem 1.25rem}.test-results-table th{color:#38bdf8;font-weight:500;letter-spacing:.05em;padding:1rem 1.25rem;text-shadow:0 0 10px rgba(56,189,248,.3)}.test-results-table tfoot td{color:#38bdf8;font-weight:600;padding:.875rem 1.25rem;border-top:1px solid rgba(56,189,248,.2);text-shadow:0 0 10px rgba(56,189,248,.2)}.test-results-table tbody::-webkit-scrollbar{width:8px;height:8px}.test-results-table tbody::-webkit-scrollbar-track{background:#1e293b;border-radius:4px}.test-results-table tbody::-webkit-scrollbar-thumb{background:rgba(56,189,248,.15);border:2px solid #1e293b;border-radius:4px;transition:background-color .2s}.test-results-table tbody::-webkit-scrollbar-thumb:hover{background:rgba(56,189,248,.3)}.test-results-table tbody::-webkit-scrollbar-corner{background:#1e293b}.loading{display:flex;align-items:center;gap:1rem;color:#38bdf8;font-size:.875rem}.spinner{width:1.5rem;height:1.5rem;border:2px solid rgba(56,189,248,.1);border-top-color:#38bdf8;border-radius:50%;animation:1s linear infinite spin;box-shadow:0 0 15px rgba(56,189,248,.3)}@keyframes spin{to{transform:rotate(360deg)}}.test-results-table tbody tr:nth-child(odd){background-color:rgba(30,41,59,.5)}.test-results-table tbody tr:nth-child(2n){background-color:rgba(15,23,42,.5)}.test-results-table tfoot{position:sticky;bottom:0;background-color:#1e293b!important;box-shadow:0 -4px 6px rgba(0,0,0,.1);border-bottom-left-radius:.5rem}.test-results-table tbody tr:hover{background-color:rgba(56,189,248,.05)!important}@media screen and (max-width:768px){.container{padding:.75rem;gap:.75rem}.server-info{grid-template-columns:1fr;gap:1rem}.timer-score{flex-direction:column;align-items:center;gap:1rem}.loading{position:relative;left:auto;top:auto;transform:none}.timer-container{flex-direction:column;align-items:center;gap:.5rem}.timer-main{align-items:center}.subtimers{text-align:center}.subtimers>div{display:block;margin:.25rem 0}.digital-timer,.grade-display{font-size:2rem}.test-results-table{font-size:.75rem}.test-results-table td,.test-results-table th{padding:.5rem .75rem}.table-container{overflow-x:auto;height:auto;max-height:65vh}.test-results-table tbody{height:auto;max-height:calc(65vh - 7rem)}.title h1{font-size:1.1rem}.subtitle{font-size:.8rem}}@media screen and (max-width:480px){.container{padding:.5rem}.system-info{padding:1rem}.digital-timer,.grade-display{font-size:1.75rem}.test-results-table{font-size:.7rem}.test-results-table td,.test-results-table th{padding:.4rem .5rem}}.subtimers{font-size:.875rem;color:#64748b;display:none}.subtimers>div{display:inline-block;margin-right:1rem}
    </style>
    <script>
        let currentTotalTime=0,startTime=Date.now(),isRunning=!0,testCount=0,totalOps=0,totalOpsMhz=0;function formatTime(e){let t=e%60;return`${Math.floor(e/60).toString().padStart(2,"0")}:${Math.floor(t).toString().padStart(2,"0")}.${Math.floor(t%1*1e3).toString().padStart(3,"0")}`}function updateDigitalTimer(){if(!isRunning)return;let e=Date.now(),t=document.getElementById("digitalTimer");t&&(t.textContent=formatTime((e-startTime)/1e3+currentTotalTime)),requestAnimationFrame(updateDigitalTimer)}function getGrade(e){let t=[{time:3,grade:"A+",color:"#7dd3fc",desc:"Exceptional"},{time:5,grade:"A",color:"#38bdf8",desc:"Excellent"},{time:7,grade:"B+",color:"#0ea5e9",desc:"Very Good"},{time:10,grade:"B",color:"#2563eb",desc:"Good"},{time:12,grade:"C+",color:"#3b82f6",desc:"Above Average"},{time:15,grade:"C",color:"#1d4ed8",desc:"Average"},{time:17,grade:"D+",color:"#6366f1",desc:"Below Average"},{time:20,grade:"D",color:"#4f46e5",desc:"Poor"},{time:22,grade:"E+",color:"#7c3aed",desc:"Very Poor"},{time:25,grade:"E",color:"#9333ea",desc:"Unsatisfactory"},{time:200,grade:"F",color:"#dc2626",desc:"Failed"}];for(let o of t)if(e<=o.time)return o;return t[t.length-1]}function createTest(e,t,o,l,r){testCount++,!r&&(totalOps+=o,l&&(totalOpsMhz+=l));let n=document.getElementById("testResultsTable").getElementsByTagName("tbody")[0],i=n.insertRow();if(i.insertCell(0).textContent=e,r){let a=i.insertCell(1);a.textContent=r,a.colSpan=3,a.style.color="#64748b",a.style.fontStyle="italic"}else i.insertCell(1).textContent=t.toFixed(5)+"s",i.insertCell(2).textContent=o+" op/s",i.insertCell(3).textContent=l?l+" op/s/MHz":"N/A"}function addTotalsRow(){let e=document.getElementById("testResultsTable").getElementsByTagName("tfoot")[0],t=e.insertRow(),o=getGrade(currentTotalTime);t.style.fontWeight="bold",t.style.borderTop="2px solid "+o.color,t.style.backgroundColor="rgba(79, 70, 229, 0.1)",t.insertCell(0).textContent="TOTALS",t.insertCell(1).textContent=currentTotalTime.toFixed(5)+"s",t.insertCell(2).textContent=(totalOps/testCount).toFixed(0)+" op/s avg",t.insertCell(3).textContent=(totalOpsMhz/testCount).toFixed(2)+" op/s/MHz avg";let l=document.querySelector(".grade-container"),r=document.getElementById("gradeDisplay"),n=document.getElementById("gradeDescription");l.style.display="flex",r.textContent=o.grade,r.style.color=o.color,n.textContent=o.desc,document.getElementById("digitalTimer").style.color=o.color}updateDigitalTimer();
    </script>
</head>
<body>
    <div class="container">
        <div class="content">
            <div class="system-info">
            <div class="title">
                <h1>PHP Benchmark Performance Test</h1>
            </div>
                <div class="timer-score">
                    <div class="timer-container">
                        <div class="timer-main">
                            <div id="digitalTimer" class="digital-timer">0.000s</div>
                        </div>
                        <div id="loading" class="loading">
                            <div class="spinner"></div>
                            Running performance tests...
                        </div>
                        <div id="subtimers" class="subtimers">
                            <div>Base PHP: <span id="baseTimer">0.000s</span></div><br>
                            <div>Extensions: <span id="extTimer">0.000s</span></div>
                        </div>
                    </div>
                    <div class="grade-container">
                        <div id="gradeDisplay" class="grade-display">--</div>
                        <div id="gradeDescription" class="grade-description">--</div>
                    </div>
                </div>
                <div class="info-row server-info">
                    <div class="info-col">
                        PHP Version: <?= PHP_VERSION ?><br>
                        PHP Memory: <?= ini_get('memory_limit') ?>
                    </div>
                    <div class="info-col">
                        Host: <?= $hostOrg ?><br>
                        Date: <?= date('Y-m-d H:i:s') ?> 
                    </div>
                    <div class="info-col">
                        CPU Cores/MHz: <?= $cpuInfo['cores'] ?> / <?= $cpuMhz ? number_format($cpuMhz, 0) : 'Unknown' ?> MHz<br>
                        <a style="color:#38bdf8;" href="https://tuner.103.197.52.28.sth.nz/">How does my benchmark compare?</a>
                    </div>
                </div>
            </div>
            <div id="results">
                <table class="test-results-table" id="testResultsTable">
                    <thead>
                        <tr>
                            <th>Test Name</th>
                            <th>Time</th>
                            <th>Op/s</th>
                            <th>Op/s/MHz</th>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                    <tfoot>
                    </tfoot>
                </table>
            </div>
        </div>
    </div>
</body>
</html>
<?php
ob_end_flush();
ob_start(); 
$results = [];
$totalTime = 0;

$baseCategories = ['php_features', 'math', 'string', 'array', 'crypto', 'file'];
$extensionCategories = ['multibyte', 'compression', 'image', 'xml', 'intl', 'serialization'];

foreach ($tests as $category => $categoryTests) {
    foreach ($categoryTests as $test) {
        try {
            $skipTest = false;
            $extensionMessage = '';
            
            if (strpos($test[0], 'Image: GD') === 0 && $has_gd !== 'yes') {
                $skipTest = true;
                $extensionMessage = 'GD extension not available';
            } elseif (strpos($test[0], 'Image: ImageMagick') === 0 && $has_imagick !== 'yes') {
                $skipTest = true;
                $extensionMessage = 'ImageMagick extension not available';
            } elseif (strpos($test[0], 'Compression: Zstd') === 0 && $has_zstd !== 'yes') {
                $skipTest = true;
                $extensionMessage = 'Zstd extension not available';
            } elseif (strpos($test[0], 'Compression: LZ4') === 0 && $has_lz4 !== 'yes') {
                $skipTest = true;
                $extensionMessage = 'LZ4 extension not available';
            } elseif (strpos($test[0], 'Serialize: MsgPack') === 0 && $has_msgpack !== 'yes') {
                $skipTest = true;
                $extensionMessage = 'MsgPack extension not available';
            } elseif (strpos($test[0], 'XML: DOM') === 0 && $has_dom !== 'yes') {
                $skipTest = true;
                $extensionMessage = 'DOM extension not available';
            } elseif (strpos($test[0], 'XML: SimpleXML') === 0 && $has_simplexml !== 'yes') {
                $skipTest = true;
                $extensionMessage = 'SimpleXML extension not available';
            } elseif (strpos($test[0], 'Intl:') === 0 && $has_intl !== 'yes') {
                $skipTest = true;
                $extensionMessage = 'Intl extension not available';
            }

            if ($skipTest) {
                $results[] = [
                    'name' => $test[0],
                    'time' => 0,
                    'ops_per_sec' => 0,
                    'ops_per_sec_mhz' => 0,
                    'message' => $extensionMessage
                ];
                continue;
            }

            $time = runTest($timer, $test[0], $test[1], $test[2]);
            $metrics = calculateMetrics($time, $test[2], $cpuMhz);
            $results[] = [
                'name' => $test[0],
                'time' => $metrics['time'],
                'ops_per_sec' => number_format($metrics['ops_per_sec'], 0),
                'ops_per_sec_mhz' => number_format($metrics['ops_per_sec_mhz'], 0),
                'message' => ''
            ];
        } catch (Exception $e) {
            error_log('Error running test ' . $test[0] . ': ' . $e->getMessage());
        }
    }
}

$baseResults = array_filter($results, function($result) use ($tests, $baseCategories) {
    foreach ($baseCategories as $category) {
        foreach ($tests[$category] as $test) {
            if ($test[0] === $result['name']) return true;
        }
    }
    return false;
});

$extensionResults = array_filter($results, function($result) use ($tests, $extensionCategories) {
    foreach ($extensionCategories as $category) {
        foreach ($tests[$category] as $test) {
            if ($test[0] === $result['name']) return true;
        }
    }
    return false;
});

$baseTime = array_sum(array_map(function($val) { 
    return floatval(str_replace(',', '', $val)); 
}, array_column($baseResults, 'time')));

$baseOps = array_sum(array_map(function($val) { 
    return floatval(str_replace(',', '', $val)); 
}, array_column($baseResults, 'ops_per_sec')));

$baseOpsMhz = array_sum(array_map(function($val) { 
    return floatval(str_replace(',', '', $val)); 
}, array_column($baseResults, 'ops_per_sec_mhz')));

$extTime = array_sum(array_map(function($val) { 
    return floatval(str_replace(',', '', $val)); 
}, array_column($extensionResults, 'time')));

$extOps = array_sum(array_map(function($val) { 
    return floatval(str_replace(',', '', $val)); 
}, array_column($extensionResults, 'ops_per_sec')));

$extOpsMhz = array_sum(array_map(function($val) { 
    return floatval(str_replace(',', '', $val)); 
}, array_column($extensionResults, 'ops_per_sec_mhz')));

echo '<script>';

echo 'function createTest(t,e,l,n,s){testCount++,!s&&(totalOps+=l,n&&(totalOpsMhz+=n));let o=document.getElementById("testResultsTable").getElementsByTagName("tbody")[0],i=o.insertRow();if(i.insertCell(0).textContent=t,s){let C=i.insertCell(1);C.textContent=s,C.colSpan=3,C.style.color="#64748b",C.style.fontStyle="italic"}else i.insertCell(1).textContent=e.toFixed(5)+"s",i.insertCell(2).textContent=l+" op/s",i.insertCell(3).textContent=n?n+" op/s/MHz":"N/A"}';

foreach ($results as $result) {
    echo 'createTest(' . 
        json_encode($result['name']) . ',' . 
        json_encode($result['time']) . ',' . 
        json_encode($result['ops_per_sec']) . ',' .
        ($result['ops_per_sec_mhz'] ? json_encode($result['ops_per_sec_mhz']) : 'null') . ',' .
        json_encode($result['message']) .
    ');';
}

echo '</script>';
echo '<script>';

$firstExtensionTest = reset($extensionResults)['name'];
echo 'const extensionHeader = document.createElement("tr");';
echo 'extensionHeader.style.backgroundColor = "rgba(56, 189, 248, 0.1)";';
echo 'extensionHeader.innerHTML = `
    <td colspan="4" style="padding: 0.75rem 1.25rem; color: #38bdf8; font-weight: 500;">
        PHP Extension Tests (supplementary benchmarks)
    </td>
`;';
echo 'const tbody = document.getElementById("testResultsTable").getElementsByTagName("tbody")[0];';
echo 'const tests = tbody.getElementsByTagName("tr");';
echo 'for (let i = 0; i < tests.length; i++) {';
echo '    if (tests[i].cells[0].textContent === ' . json_encode($firstExtensionTest) . ') {';
echo '        tbody.insertBefore(extensionHeader, tests[i]);';
echo '        break;';
echo '    }';
echo '}';

$baseCount = count($baseResults);
$extCount = count($extensionResults);
$baseAvgOps = $baseCount > 0 ? $baseOps/$baseCount : 0;
$baseAvgOpsMhz = $baseCount > 0 ? $baseOpsMhz/$baseCount : 0;
$extAvgOps = $extCount > 0 ? $extOps/$extCount : 0;
$extAvgOpsMhz = $extCount > 0 ? $extOpsMhz/$extCount : 0;
echo 'const tfoot = document.getElementById("testResultsTable").getElementsByTagName("tfoot")[0];';
echo 'const baseSubtotal = document.createElement("tr");';
echo 'baseSubtotal.innerHTML = `
    <td><strong>Base PHP Subtotal</strong></td>
    <td><strong>' . number_format($baseTime, 5) . 's</strong></td>
    <td><strong>' . number_format($baseAvgOps, 0) . ' op/s avg</strong></td>
    <td><strong>' . number_format($baseAvgOpsMhz, 2) . ' op/s/MHz avg</strong></td>
`;';
echo 'tfoot.appendChild(baseSubtotal);';

echo 'const extSubtotal = document.createElement("tr");';
echo 'extSubtotal.style.borderTop = "1px solid rgba(56, 189, 248, 0.2)";';
echo 'extSubtotal.innerHTML = `
    <td><strong>Extensions Subtotal</strong></td>
    <td><strong>' . number_format($extTime, 5) . 's</strong></td>
    <td><strong>' . number_format($extAvgOps, 0) . ' op/s avg</strong></td>
    <td><strong>' . number_format($extAvgOpsMhz, 2) . ' op/s/MHz avg</strong></td>
`;';
echo 'tfoot.appendChild(extSubtotal);';

echo 'isRunning = false;';
echo 'currentTotalTime = ' . json_encode($baseTime + $extTime) . ';';
echo 'document.getElementById("digitalTimer").textContent = formatTime(' . json_encode($baseTime + $extTime) . ') + "s";';
echo 'const loading = document.getElementById("loading");';
echo 'const subtimers = document.getElementById("subtimers");';
echo 'subtimers.style.display = "block";';
echo 'loading.remove();';
echo 'document.getElementById("baseTimer").textContent = "' . number_format($baseTime, 3) . 's";';
echo 'document.getElementById("extTimer").textContent = "' . number_format($extTime, 3) . 's";';
echo 'const grade = getGrade(' . json_encode($baseTime) . ');';
echo 'document.getElementById("digitalTimer").style.color = grade.color;';
echo 'document.getElementById("gradeDisplay").textContent = grade.grade;';
echo 'document.getElementById("gradeDisplay").style.color = grade.color;';
echo 'document.getElementById("gradeDescription").textContent = grade.desc;';
echo '</script>';

$finalData = [
    'asn' => $hostOrg,
    'php_version' => PHP_VERSION,
    'php_release' => PHP_RELEASE_VERSION,
    'final_score' => $baseTime,
    'benchmark_data' => $results,
    'php_info' => [
        'memory_limit' => ini_get('memory_limit'),
        'max_execution_time' => ini_get('max_execution_time'),
        'opcache_enabled' => ini_get('opcache.enable'),
        'opcache_jit' => ini_get('opcache.jit'),
        'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'unknown'
    ],
    'cpu_cores' => $cpuInfo['cores'],
    'cpu_mhz' => $cpuInfo['frequency'],
    'host_info' => $hostLoc,
    'total_time' => $baseTime + $extTime
];

$endpoints = [
    'https://tuner.103.197.52.28.sth.nz/api/benchmark'
];

echo '<script>';
echo 'async function sendBenchmarkResults() {
    const endpoints = ' . json_encode($endpoints) . ';
    const resultData = ' . json_encode($finalData) . ';
    const results=document.createElement("div");for(const endpoint of(results.className="mt-4",document.querySelector(".grade-container").after(results),endpoints)){let e=document.createElement("div");e.className="text-xs font-mono text-gray-500 flex items-center space-x-2 opacity-75 hover:opacity-100 transition-opacity",e.innerHTML=`
            <div class="grade-display text-xs animate-pulse">•</div>
            <span class="grade-description">Saving results...</span>
        `,results.appendChild(e);try{let s=await fetch(endpoint,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(resultData)}),t=await s.json();if(s.ok)e.innerHTML=`
                    <div class="grade-display text-xs" style="color: #22c55e;">•</div>
                    <span class="grade-description">Results saved</span>
                `;else throw Error(t.message||"Failed to save results")}catch(a){e.innerHTML=`
                <div class="grade-display text-xs" style="color: #ef4444;">•</div>
                <span class="grade-description">Failed to save</span>
            `}}}';

echo 'sendBenchmarkResults();';
echo '</script>';

ob_end_flush();
?>
