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
Output for 8.2.0 - 8.2.28, 8.3.0 - 8.3.20, 8.4.1 - 8.4.6
printf('%d', FooStringable); Warning: Object of class FooStringable could not be converted to int in /in/3pXMc on line 27 1 ------------------------------- printf('%d', FooStringable); Warning: Object of class FooStringable could not be converted to int in /in/3pXMc on line 27 1 ------------------------------- printf('%f', FooStringable); Warning: Object of class FooStringable could not be converted to float in /in/3pXMc on line 27 1.000000 ------------------------------- printf('%*s', '5', 'a'); Width must be an integer ------------------------------- printf('%*s', 5, 'a'); Width must be an integer ------------------------------- printf('%*s', SimpleXMLElement, 'a'); Width must be an integer ------------------------------- printf('%*s', null, 'a'); Width must be an integer ------------------------------- printf('%*s', true, 'a'); Width must be an integer ------------------------------- printf('%.*s', '5', 'a'); Precision must be an integer ------------------------------- printf('%2$s %3$.*s', '1', 5, 'a'); Precision must be an integer ------------------------------- printf('%1$-'X10.2f', FooStringable); Warning: Object of class FooStringable could not be converted to float in /in/3pXMc on line 27 1.00XXXXXX ------------------------------- printf('%s %1$*.*f', FooStringable, 5, 2); Warning: Object of class FooStringable could not be converted to float in /in/3pXMc on line 27 foo 1.00 ------------------------------- printf('%3$f', 1, 2, FooStringable); Warning: Object of class FooStringable could not be converted to float in /in/3pXMc on line 27 1.000000 ------------------------------- printf('%d', 1.23); 1 ------------------------------- printf('%d', 1.23); 1 ------------------------------- printf('%d', 'a'); 0 ------------------------------- printf('%d', '1.23'); 1 ------------------------------- printf('%d', null); 0 ------------------------------- printf('%d', true); 1 ------------------------------- printf('%d', SimpleXMLElement); 0 ------------------------------- printf('%f', 'a'); 0.000000 ------------------------------- printf('%f', null); 0.000000 ------------------------------- printf('%f', true); 1.000000 ------------------------------- printf('%f', SimpleXMLElement); 0.000000 ------------------------------- printf('%s', null); ------------------------------- printf('%s', true); 1 ------------------------------- printf('%d', stdClass); Warning: Object of class stdClass could not be converted to int in /in/3pXMc on line 27 1 ------------------------------- printf('%s', array ( )); Warning: Array to string conversion in /in/3pXMc on line 27 Array ------------------------------- printf('%s'); 2 arguments are required, 1 given ------------------------------- printf('%s', 1, 2); 1 ------------------------------- printf('%s', 'a'); a ------------------------------- printf('%s', FooStringable); foo ------------------------------- printf('%d', 1); 1 ------------------------------- printf('%f', 1); 1.000000 ------------------------------- printf('%f', 1.1); 1.100000 ------------------------------- printf('%*s', 5, 'a'); a ------------------------------- printf('%2$*s', 5, 'a'); a ------------------------------- printf('%s %2$*s', 'a', 5, 'a'); a 5 ------------------------------- printf('%1$-+'X10.2f', 5); +5.00XXXXX ------------------------------- printf('%1$*.*f %s %2$d', 5, 6, FooStringable); 5.000000 foo 6 -------------------------------

preferences:
44.92 ms | 418 KiB | 5 Q