3v4l.org

run code in 300+ PHP versions simultaneously
<?php const SOMECONST = 'Const hello'; enum SomeEnum { case Hearts; case Diamonds; case Clubs; case Spades; } function SomeFunction() { } $SomeFunctionClosure = function() { }; $SomeFunctionFirstClassCallable = SomeFunction(...); $someFunctionClosureFromCallabe = Closure::fromCallable('SomeFunction'); class ShouldTypeError { public function __construct($returnValue) { if ($returnValue !== 'no-return') { if ($returnValue === '$this') { return $this; } elseif ($returnValue === 'no-return-value') { return; } elseif ($returnValue === 'void') { return void; } elseif ($returnValue === 'never') { return never; } return $returnValue; } } } $testcases = [ 'no-return', 'no-return-value', '$this', new ShouldTypeError('no-return'), SOMECONST, 'abc', 1, 1.23, null, true, false, ['a', 'b', 'c'], ['a' => 'a', 'b' => 'b', 'c' => 'c', 0 => 'Zero'], 'never', 'void', SomeEnum::Spades, function() { echo 'Hi'.PHP_EOL; }, $SomeFunctionClosure, $SomeFunctionFirstClassCallable, $someFunctionClosureFromCallabe, new DateTimeImmutable(), ]; foreach($testcases as $testcase) { echo "--------------[ TESTCASE ]--------------\n"; var_dump($testcase); echo "\n"; try { $didReturn = new ShouldTypeError($testcase); switch($testcase) { case 'no-return': echo "Success: without a return statement is always valid.\n"; break; case 'no-return-value': echo "Success: a return statement without a value is always valid.\n"; break; case '$this': echo "Dubious: return $this is dubious.\n"; echo "- it fullfills the return type, so it could be allowed.\n"; echo "- but returning anything from a constructor is nonsense, because it is discarded.\n"; echo " As shown by the third testcase new SomeTypeError('no-return').\n"; break; default: echo "Error: why is it not a return TypeError?\n"; break; } if (!($didReturn instanceof ShouldTypeError)) { echo "Failed to new a ShouldTypeError.\n"; } } catch (Throwable $ex) { echo "Success: throwable: ".$ex->getMessage()."\n"; } }
Output for 8.5.2
--------------[ TESTCASE ]-------------- string(9) "no-return" Success: without a return statement is always valid. --------------[ TESTCASE ]-------------- string(15) "no-return-value" Success: a return statement without a value is always valid. --------------[ TESTCASE ]-------------- string(5) "$this" Success: throwable: Using $this when not in object context --------------[ TESTCASE ]-------------- object(ShouldTypeError)#4 (0) { } Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- string(11) "Const hello" Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- string(3) "abc" Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- int(1) Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- float(1.23) Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- NULL Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- bool(true) Success: without a return statement is always valid. --------------[ TESTCASE ]-------------- bool(false) Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" } Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- array(4) { ["a"]=> string(1) "a" ["b"]=> string(1) "b" ["c"]=> string(1) "c" [0]=> string(4) "Zero" } Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- string(5) "never" Success: throwable: Undefined constant "never" --------------[ TESTCASE ]-------------- string(4) "void" Success: throwable: Undefined constant "void" --------------[ TESTCASE ]-------------- enum(SomeEnum::Spades) Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- object(Closure)#6 (3) { ["name"]=> string(22) "{closure:/in/sXXe8:67}" ["file"]=> string(9) "/in/sXXe8" ["line"]=> int(67) } Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- object(Closure)#1 (3) { ["name"]=> string(22) "{closure:/in/sXXe8:17}" ["file"]=> string(9) "/in/sXXe8" ["line"]=> int(17) } Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- object(Closure)#2 (1) { ["function"]=> string(12) "SomeFunction" } Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- object(Closure)#3 (1) { ["function"]=> string(12) "SomeFunction" } Error: why is it not a return TypeError? --------------[ TESTCASE ]-------------- object(DateTimeImmutable)#7 (3) { ["date"]=> string(26) "2026-01-30 13:31:14.025598" ["timezone_type"]=> int(3) ["timezone"]=> string(16) "Europe/Amsterdam" } Error: why is it not a return TypeError?

preferences:
53.84 ms | 415 KiB | 5 Q