3v4l.org

run code in 300+ PHP versions simultaneously
<?php declare(strict_types=1); class FooStringable implements \Stringable { public function __toString(): string { return 'foo'; } } function my_printf(mixed ...$args): void { $printArg = fn (mixed $arg) => match (true) { is_bool($arg) => $arg ? 'true' : 'false', is_string($arg) => "'{$arg}'", is_numeric($arg) => $arg, is_null($arg) => 'null', is_object($arg) => $arg::class, default => var_export($arg, true), }; $argsTxt = array_map($printArg, $args); $argsTxt = implode(', ', $argsTxt); echo "printf({$argsTxt});\n"; try { printf(...$args); } catch (Throwable $e) { echo $e->getMessage() . "\n"; } echo "\n-------------------------------\n"; }; $stream = fopen('php://stdout', 'w'); // Error my_printf('%d', new FooStringable()); my_printf('%d', rand() ? new FooStringable() : 5); my_printf('%f', new FooStringable()); my_printf('%*s', '5', 'a'); my_printf('%*s', 5.0, 'a'); my_printf('%*s', new \SimpleXMLElement('<a>7</a>'), 'a'); my_printf('%*s', null, 'a'); my_printf('%*s', true, 'a'); my_printf('%.*s', '5', 'a'); my_printf('%2$s %3$.*s', '1', 5, 'a'); // * is the first ordinary placeholder, so it matches '1' my_printf('%1$-\'X10.2f', new FooStringable()); my_printf('%s %1$*.*f', new FooStringable(), 5, 2); my_printf('%3$f', 1, 2, new FooStringable()); // Strict error my_printf('%d', 1.23); my_printf('%d', rand() ? 1.23 : 1); my_printf('%d', 'a'); my_printf('%d', '1.23'); my_printf('%d', null); my_printf('%d', true); my_printf('%d', new \SimpleXMLElement('<a>aaa</a>')); my_printf('%f', 'a'); my_printf('%f', null); my_printf('%f', true); my_printf('%f', new \SimpleXMLElement('<a>aaa</a>')); my_printf('%s', null); my_printf('%s', true); // Error, but already reported by CallToFunctionParametersRule my_printf('%d', new \stdClass()); my_printf('%s', []); // Error, but already reported by my_printfParametersRule my_printf('%s'); my_printf('%s', 1, 2); // OK my_printf('%s', 'a'); my_printf('%s', new FooStringable()); my_printf('%d', 1); my_printf('%f', 1); my_printf('%f', 1.1); my_printf('%*s', 5, 'a'); my_printf('%2$*s', 5, 'a'); my_printf('%s %2$*s', 'a', 5, 'a'); my_printf('%1$-+\'X10.2f', 5); my_printf('%1$*.*f %s %2$d', 5, 6, new FooStringable()); // 5.000000 foo 6

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.60.0360.01218.22
8.4.50.0360.01017.96
8.4.40.0220.00717.75
8.4.30.0400.00917.66
8.4.20.0370.01017.78
8.4.10.0390.01217.91
8.3.200.0390.00717.08
8.3.190.0400.00916.85
8.3.180.0400.00716.45
8.3.170.0330.01316.73
8.3.160.0420.00516.84
8.3.150.0530.00717.11
8.3.140.0350.00716.92
8.3.130.0120.00716.79
8.3.120.0320.00716.84
8.3.110.0350.00717.14
8.3.100.0400.00816.79
8.3.90.0400.00816.74
8.3.80.0370.01016.67
8.3.70.0360.01116.61
8.3.60.0420.00616.82
8.3.50.0340.00816.76
8.3.40.0330.00417.81
8.3.30.0360.00717.93
8.3.20.0310.01217.77
8.3.10.0320.00917.68
8.3.00.0320.00917.65
8.2.280.0270.01316.93
8.2.270.0300.01116.78
8.2.260.0300.01017.15
8.2.250.0290.00317.01
8.2.240.0220.01116.79
8.2.230.0320.01016.75
8.2.220.0260.00417.00
8.2.210.0190.00716.81
8.2.200.0160.00416.77
8.2.190.0130.00516.94
8.2.180.0190.00417.16
8.2.170.0270.01017.81
8.2.160.0330.00818.17
8.2.150.0220.00417.82
8.2.140.0310.00418.06
8.2.130.0320.01117.84
8.2.120.0320.01117.97
8.2.110.0310.01218.00
8.2.100.0330.01017.89
8.2.90.0370.00717.85
8.2.80.0360.00817.57
8.2.70.0330.00817.88
8.2.60.0350.01017.79
8.2.50.0350.00817.77
8.2.40.0350.01117.93
8.2.30.0340.00617.55
8.2.20.0280.01017.98
8.2.10.0280.00917.88
8.2.00.0270.00717.72

preferences:
34.38 ms | 403 KiB | 5 Q