8000 Deprecate returning non-string values from a user output handler by DanielEScherzer · Pull Request #18932 · php/php-src · GitHub
[go: up one dir, main page]

Skip to content

Deprecate returning non-string values from a user output handler #18932

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jul 7, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Test returning objects
  • Loading branch information
DanielEScherzer committed Jul 3, 2025
commit 198a391d41c6622ad95d8e7e38bc8aff604c3786
53 changes: 52 additions & 1 deletion tests/output/ob_start_callback_bad_return/exception_handler.phpt
8000
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ ob_start(): Check behaviour with deprecation converted to exception
--FILE--
<?php

class NotStringable {
public function __construct(public string $val) {}
}
class IsStringable {
public function __construct(public string $val) {}
public function __toString() {
return __CLASS__ . ": " . $this->val;
}
}

$log = [];

set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
Expand Down Expand Up @@ -33,7 +43,26 @@ function return_zero($string) {
return 0;
}

$cases = ['return_null', 'return_false', 'return_true', 'return_zero'];
function return_non_stringable($string) {
global $log;
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
return new NotStringable($string);
}

function return_stringable($string) {
global $log;
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
return new IsStringable($string);
}

$cases = [
'return_null',
'return_false',
'return_true',
'return_zero',
'return_non_stringable',
'return_stringable',
];
foreach ($cases as $case) {
$log = [];
echo "\n\nTesting: $case\n";
Expand Down Expand Up @@ -94,3 +123,25 @@ Stack trace:
End of return_zero, log was:
return_zero: <<<Inside of return_zero
>>>

Testing: return_non_stringable
ErrorException: ob_end_flush(): Returning a non-string result from user output handler return_non_stringable is deprecated in %s:%d
Stack trace:
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', '/usr/src/php/te...', 69)
#1 %s(%d): ob_end_flush()
#2 {main}

End of return_non_stringable, log was:
return_non_stringable: <<<Inside of return_non_stringable
>>>

Testing: return_stringable
ErrorException: ob_end_flush(): Returning a non-string result from user output handler return_stringable is deprecated in %s:%d
Stack trace:
#0 [internal function]: {closure:%s:%d}(8192, 'ob_end_flush():...', '/usr/src/php/te...', 69)
#1 %s(%d): ob_end_flush()
#2 {main}

End of return_stringable, log was:
return_stringable: <<<Inside of return_stringable
>>>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ ob_start(): Check behaviour with deprecation converted to exception
--FILE--
<?php

class NotStringable {
public function __construct(public string $val) {}
}
class IsStringable {
public function __construct(public string $val) {}
public function __toString() {
return __CLASS__ . ": " . $this->val;
}
}

$log = [];

set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
Expand Down Expand Up @@ -33,12 +43,40 @@ function return_zero($string) {
return 0;
}

function return_non_stringable($string) {
global $log;
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
return new NotStringable($string);
}

function return_stringable($string) {
global $log;
$log[] = __FUNCTION__ . ": <<<" . $string . ">>>";
return new IsStringable($string);
}

ob_start('return_null');
ob_start('return_false');
ob_start('return_true');
ob_start('return_zero');
ob_start('return_non_stringable');
ob_start('return_stringable');

echo "In all of them\n\n";
try {
ob_end_flush();
} catch (\ErrorException $e) {
echo $e->getMessage() . "\n";
}
echo "Ended return_stringable handler\n\n";

try {
ob_end_flush();
} catch (\ErrorException $e) {
echo $e->getMessage() . "\n";
}
echo "Ended return_non_stringable handler\n\n";

try {
ob_end_flush();
} catch (\ErrorException $e) {
Expand Down Expand Up @@ -77,7 +115,15 @@ Ended return_null handler

All handlers are over

return_zero: <<<In all of them
return_stringable: <<<In all of them

>>>
return_non_stringable: <<<ob_end_flush(): Returning a non-string result from user output handler return_stringable is deprecated
Ended return_stringable handler

>>>
return_zero: <<<ob_end_flush(): Returning a non-string result from user output handler return_non_stringable is deprecated
Ended return_non_stringable handler

>>>
return_true: <<<0ob_end_flush(): Returning a non-string result from user output handler return_zero is deprecated
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--TEST--
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns stringable object)
--INI--
memory_limit=2M
--FILE--
<?php

class IsStringable {
public function __construct(public string $val) {}
public function __toString() {
return __CLASS__ . ": " . $this->val;
}
}

ob_start(function() {
// We are out of memory, now trigger a deprecation
return new IsStringable("");
});

$a = [];
// trigger OOM in a resize operation
while (1) {
$a[] = 1;
}

?>
--EXPECTF--
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d

Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
ob_start(): Check behaviour with deprecation when OOM triggers handler removal (handler returns non-stringable object)
--INI--
memory_limit=2M
--FILE--
<?php

class NotStringable {
public function __construct(public string $val) {}
}

ob_start(function() {
// We are out of memory, now trigger a deprecation
return new NotStringable("");
});

$a = [];
// trigger OOM in a resize operation
while (1) {
$a[] = 1;
}

?>
--EXPECTF--
Deprecated: main(): Returning a non-string result from user output handler {closure:%s:%d} is deprecated in %s on line %d

Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d

Fatal error: Uncaught Error: Object of class NotStringable could not be converted to string in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
Loading
0