Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
17 changes: 16 additions & 1 deletion sapi/cli/php_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "zend_hash.h"
#include "zend_modules.h"
#include "zend_interfaces.h"
#include "zend_closures.h"

#include "ext/reflection/php_reflection.h"

Expand Down Expand Up @@ -930,7 +931,21 @@ static int do_cli(int argc, char **argv) /* {{{ */
if (interactive) {
EG(exit_status) = cli_shell_callbacks.cli_shell_run();
} else {
php_execute_script(&file_handle);
zval retval;
ZVAL_UNDEF(&retval);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does php_execute_script_ex not set this to UNDEF?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't trust passing values to zval_ptr_dtor() unless I initialize them myself.

php_execute_script_ex(&file_handle, &retval);

/* Check if the primary script returned a Closure and execute it: This allows
* a script to act both as a library and as an executable when executed directly.
*/
if (Z_TYPE(retval) == IS_OBJECT && Z_OBJCE(retval) == zend_ce_closure) {
zend_fcall_info_cache fcc = {0};
Z_OBJ_HANDLER(retval, get_closure)(Z_OBJ(retval), &fcc.calling_scope, &fcc.function_handler, &fcc.object, /* check_only */ false);
fcc.called_scope = fcc.calling_scope;
fcc.closure = Z_OBJ(retval);
zend_call_known_fcc(&fcc, /* retval */ NULL, /* param_count */ 0, /* params */ NULL, /* named_params */ NULL);
}
Comment thread
TimWolla marked this conversation as resolved.
zval_ptr_dtor(&retval);
}
break;
case PHP_CLI_MODE_LINT:
Expand Down
7 changes: 7 additions & 0 deletions sapi/cli/tests/primary_script_closure.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

return function () {
echo "Called", PHP_EOL;
};

?>
16 changes: 16 additions & 0 deletions sapi/cli/tests/primary_script_closure_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
Execute closures returned by the primary script
--SKIPIF--
<?php
include "skipif.inc";
?>
--FILE--
<?php

return function () {
echo "Called", PHP_EOL;
};

?>
--EXPECT--
Called
18 changes: 18 additions & 0 deletions sapi/cli/tests/primary_script_closure_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
Execute closures returned by the primary script (First Class Callable)
--SKIPIF--
<?php
include "skipif.inc";
?>
--FILE--
<?php

function main() {
echo "Called", PHP_EOL;
}

return main(...);

?>
--EXPECT--
Called
14 changes: 14 additions & 0 deletions sapi/cli/tests/primary_script_closure_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
Execute closures returned by the primary script (From different file)
--SKIPIF--
<?php
include "skipif.inc";
?>
--FILE--
<?php

return include "primary_script_closure.inc";

?>
--EXPECT--
Called
13 changes: 13 additions & 0 deletions sapi/cli/tests/primary_script_closure_004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
Execute closures returned by the primary script (Included file returns closure, but primary script does not)
--SKIPIF--
<?php
include "skipif.inc";
?>
--FILE--
<?php

$closure = include "primary_script_closure.inc";

?>
--EXPECT--
Loading