feat: '-r' option for php-cli (#1482)

This commit is contained in:
Alexander Stecher
2025-05-01 02:06:31 +02:00
committed by GitHub
parent a6e1d3554d
commit 3741782330
7 changed files with 51 additions and 11 deletions

View File

@@ -177,6 +177,7 @@ jobs:
"${BINARY}" list-modules | grep http.handlers.mercure
"${BINARY}" list-modules | grep http.handlers.mercure
"${BINARY}" list-modules | grep http.handlers.vulcain
"${BINARY}" php-cli -r "echo 'Sanity check passed';"
env:
BINARY: ./frankenphp-linux-${{ matrix.platform == 'linux/amd64' && 'x86_64' || 'aarch64' }}${{ matrix.debug && '-debug' || '' }}${{ matrix.mimalloc && '-mimalloc' || '' }}
@@ -277,6 +278,7 @@ jobs:
"${BINARY}" list-modules | grep http.handlers.mercure
"${BINARY}" list-modules | grep http.handlers.mercure
"${BINARY}" list-modules | grep http.handlers.vulcain
"${BINARY}" php-cli -r "echo 'Sanity check passed';"
env:
BINARY: ./frankenphp-linux-${{ matrix.platform == 'linux/amd64' && 'x86_64' || 'aarch64' }}-gnu
@@ -393,5 +395,6 @@ jobs:
"${BINARY}" list-modules | grep http.handlers.mercure
"${BINARY}" list-modules | grep http.handlers.mercure
"${BINARY}" list-modules | grep http.handlers.vulcain
"${BINARY}" php-cli -r "echo 'Sanity check passed';"
env:
BINARY: dist/frankenphp-mac-${{ matrix.platform }}

View File

@@ -19,13 +19,13 @@ func init() {
Long: `
Executes a PHP script similarly to the CLI SAPI.`,
CobraFunc: func(cmd *cobra.Command) {
cmd.DisableFlagParsing = true
cmd.Flags().StringP("code", "r", "", "Execute PHP code directly without <php ... ?> tags")
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdPHPCLI)
},
})
}
func cmdPHPCLI(caddycmd.Flags) (int, error) {
func cmdPHPCLI(fs caddycmd.Flags) (int, error) {
args := os.Args[2:]
if len(args) < 1 {
return 1, errors.New("the path to the PHP script is required")
@@ -37,7 +37,13 @@ func cmdPHPCLI(caddycmd.Flags) (int, error) {
}
}
status := frankenphp.ExecuteScriptCLI(args[0], args)
var status int
if evalCode := fs.String("code"); evalCode != "" {
status = frankenphp.ExecutePHPCode(evalCode)
} else {
status = frankenphp.ExecuteScriptCLI(args[0], args)
}
os.Exit(status)
return status, nil

View File

@@ -1108,6 +1108,7 @@ static void sapi_cli_register_variables(zval *track_vars_array) /* {{{ */
static void *execute_script_cli(void *arg) {
void *exit_status;
bool eval = (bool)arg;
/*
* The SAPI name "cli" is hardcoded into too many programs... let's usurp it.
@@ -1120,11 +1121,16 @@ static void *execute_script_cli(void *arg) {
cli_register_file_handles(false);
zend_first_try {
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, cli_script);
if (eval) {
/* evaluate the cli_script as literal PHP code (php-cli -r "...") */
zend_eval_string_ex(cli_script, NULL, "Command line code", 1);
} else {
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, cli_script);
CG(skip_shebang) = 1;
php_execute_script(&file_handle);
CG(skip_shebang) = 1;
php_execute_script(&file_handle);
}
}
zend_end_try();
@@ -1135,7 +1141,8 @@ static void *execute_script_cli(void *arg) {
return exit_status;
}
int frankenphp_execute_script_cli(char *script, int argc, char **argv) {
int frankenphp_execute_script_cli(char *script, int argc, char **argv,
bool eval) {
pthread_t thread;
int err;
void *exit_status;
@@ -1148,7 +1155,7 @@ int frankenphp_execute_script_cli(char *script, int argc, char **argv) {
* Start the script in a dedicated thread to prevent conflicts between Go and
* PHP signal handlers
*/
err = pthread_create(&thread, NULL, execute_script_cli, NULL);
err = pthread_create(&thread, NULL, execute_script_cli, (void *)eval);
if (err != 0) {
return err;
}

View File

@@ -613,7 +613,13 @@ func ExecuteScriptCLI(script string, args []string) int {
argc, argv := convertArgs(args)
defer freeArgs(argv)
return int(C.frankenphp_execute_script_cli(cScript, argc, (**C.char)(unsafe.Pointer(&argv[0]))))
return int(C.frankenphp_execute_script_cli(cScript, argc, (**C.char)(unsafe.Pointer(&argv[0])), false))
}
func ExecutePHPCode(phpCode string) int {
cCode := C.CString(phpCode)
defer C.free(unsafe.Pointer(cCode))
return int(C.frankenphp_execute_script_cli(cCode, 0, nil, true))
}
func convertArgs(args []string) (C.int, []*C.char) {

View File

@@ -61,7 +61,8 @@ int frankenphp_update_server_context(bool is_worker_request,
int frankenphp_request_startup();
int frankenphp_execute_script(char *file_name);
int frankenphp_execute_script_cli(char *script, int argc, char **argv);
int frankenphp_execute_script_cli(char *script, int argc, char **argv,
bool eval);
void frankenphp_register_variables_from_request_info(
zval *track_vars_array, zend_string *content_type,

View File

@@ -791,6 +791,19 @@ func TestExecuteScriptCLI(t *testing.T) {
assert.Contains(t, stdoutStderrStr, "From the CLI")
}
func TestExecuteCLICode(t *testing.T) {
if _, err := os.Stat("internal/testcli/testcli"); err != nil {
t.Skip("internal/testcli/testcli has not been compiled, run `cd internal/testcli/ && go build`")
}
cmd := exec.Command("internal/testcli/testcli", "-r", "echo 'Hello World';")
stdoutStderr, err := cmd.CombinedOutput()
assert.NoError(t, err)
stdoutStderrStr := string(stdoutStderr)
assert.Equal(t, stdoutStderrStr, `Hello World`)
}
func ExampleServeHTTP() {
if err := frankenphp.Init(); err != nil {
panic(err)

View File

@@ -13,5 +13,9 @@ func main() {
os.Exit(1)
}
if len(os.Args) == 3 && os.Args[1] == "-r" {
os.Exit(frankenphp.ExecutePHPCode(os.Args[2]))
}
os.Exit(frankenphp.ExecuteScriptCLI(os.Args[1], os.Args))
}