From 6f98b16564c7ad187d57fefcd49f218db5e2158e Mon Sep 17 00:00:00 2001 From: Alliballibaba Date: Sat, 5 Apr 2025 17:49:47 +0200 Subject: [PATCH 1/6] Adds -r option to PHP cli. --- .github/workflows/static.yaml | 5 ++++- caddy/php-cli.go | 12 +++++++++--- frankenphp.c | 18 ++++++++++++------ frankenphp.go | 8 +++++++- frankenphp.h | 2 +- frankenphp_test.go | 8 ++++++++ 6 files changed, 41 insertions(+), 12 deletions(-) diff --git a/.github/workflows/static.yaml b/.github/workflows/static.yaml index a6ed634c32..122b75555e 100644 --- a/.github/workflows/static.yaml +++ b/.github/workflows/static.yaml @@ -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 @@ -392,6 +394,7 @@ jobs: "${BINARY}" list-modules | grep http.encoders.br "${BINARY}" list-modules | grep http.handlers.mercure "${BINARY}" list-modules | grep http.handlers.mercure - "${BINARY}" list-modules | grep http.handlers.vulcain + "${BINARY}" list-modules | grep http.handlers.vulcain# + "${BINARY}" php-cli -r "echo 'Sanity check passed';" env: BINARY: dist/frankenphp-mac-${{ matrix.platform }} diff --git a/caddy/php-cli.go b/caddy/php-cli.go index 3e75e20fdd..0a0172cd3e 100644 --- a/caddy/php-cli.go +++ b/caddy/php-cli.go @@ -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 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 diff --git a/frankenphp.c b/frankenphp.c index 1c67d2b640..9620f51678 100644 --- a/frankenphp.c +++ b/frankenphp.c @@ -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,7 @@ 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 +1154,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; } diff --git a/frankenphp.go b/frankenphp.go index 17caea1c9b..216071c5a5 100644 --- a/frankenphp.go +++ b/frankenphp.go @@ -635,7 +635,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) { diff --git a/frankenphp.h b/frankenphp.h index 7839bcf7e0..c995453f6f 100644 --- a/frankenphp.h +++ b/frankenphp.h @@ -61,7 +61,7 @@ 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, diff --git a/frankenphp_test.go b/frankenphp_test.go index 59312c9045..5f249c799a 100644 --- a/frankenphp_test.go +++ b/frankenphp_test.go @@ -790,6 +790,14 @@ func TestExecuteScriptCLI(t *testing.T) { assert.Contains(t, stdoutStderrStr, "From the CLI") } +func TestExecuteCLICode(t *testing.T) { + var exitCode int + + exitCode = frankenphp.ExecutePHPCode("exit(123);") + + assert.Equal(t, 123, exitCode) +} + func ExampleServeHTTP() { if err := frankenphp.Init(); err != nil { panic(err) From c0f87a246a83dd5c27d8100e2eac106c6f345666 Mon Sep 17 00:00:00 2001 From: Alliballibaba Date: Sat, 5 Apr 2025 17:50:45 +0200 Subject: [PATCH 2/6] clang-format --- frankenphp.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/frankenphp.c b/frankenphp.c index 9620f51678..496b772aa0 100644 --- a/frankenphp.c +++ b/frankenphp.c @@ -1122,14 +1122,14 @@ static void *execute_script_cli(void *arg) { cli_register_file_handles(false); zend_first_try { if (eval) { - /* evaluate the cli_script as literal PHP code (php-cli -r "...") */ - zend_eval_string_ex(cli_script, NULL, "Command line code", 1); + /* 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); + 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(); @@ -1141,7 +1141,8 @@ static void *execute_script_cli(void *arg) { return exit_status; } -int frankenphp_execute_script_cli(char *script, int argc, char **argv, bool eval) { +int frankenphp_execute_script_cli(char *script, int argc, char **argv, + bool eval) { pthread_t thread; int err; void *exit_status; From 69dabb89958d385352277ee146f85ca1bc54d6ce Mon Sep 17 00:00:00 2001 From: Alliballibaba Date: Sat, 5 Apr 2025 18:00:04 +0200 Subject: [PATCH 3/6] trigger From 1a22d650fa8381f2c3e567969fa00e30ef658a1f Mon Sep 17 00:00:00 2001 From: Alliballibaba Date: Sat, 5 Apr 2025 18:24:23 +0200 Subject: [PATCH 4/6] Fixes test --- frankenphp.h | 3 ++- frankenphp_test.go | 11 ++++++++--- internal/testcli/main.go | 4 ++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/frankenphp.h b/frankenphp.h index c995453f6f..6636bfbf02 100644 --- a/frankenphp.h +++ b/frankenphp.h @@ -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, bool eval); +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, diff --git a/frankenphp_test.go b/frankenphp_test.go index 5f249c799a..e6caa42711 100644 --- a/frankenphp_test.go +++ b/frankenphp_test.go @@ -791,11 +791,16 @@ func TestExecuteScriptCLI(t *testing.T) { } func TestExecuteCLICode(t *testing.T) { - var exitCode int + if _, err := os.Stat("internal/testcli/testcli"); err != nil { + t.Skip("internal/testcli/testcli has not been compiled, run `cd internal/testcli/ && go build`") + } - exitCode = frankenphp.ExecutePHPCode("exit(123);") + cmd := exec.Command("internal/testcli/testcli", "-r", "echo 'Hello World';") + stdoutStderr, err := cmd.CombinedOutput() + assert.NoError(t, err) - assert.Equal(t, 123, exitCode) + stdoutStderrStr := string(stdoutStderr) + assert.Equal(t, stdoutStderrStr, `Hello World`) } func ExampleServeHTTP() { diff --git a/internal/testcli/main.go b/internal/testcli/main.go index 47a4ca1862..c03c836c4d 100644 --- a/internal/testcli/main.go +++ b/internal/testcli/main.go @@ -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)) } From e05ca97fe6571b4515cb3d632aa6ce1a08de00da Mon Sep 17 00:00:00 2001 From: Alliballibaba Date: Sat, 12 Apr 2025 21:26:42 +0200 Subject: [PATCH 5/6] Test with changes from #1493 --- static-builder-gnu.Dockerfile | 2 +- static-builder-musl.Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/static-builder-gnu.Dockerfile b/static-builder-gnu.Dockerfile index 120126bb0c..9288a62018 100644 --- a/static-builder-gnu.Dockerfile +++ b/static-builder-gnu.Dockerfile @@ -107,7 +107,7 @@ ENV CC='/opt/rh/devtoolset-10/root/usr/bin/gcc' ENV CXX='/opt/rh/devtoolset-10/root/usr/bin/g++' ENV AR='/opt/rh/devtoolset-10/root/usr/bin/ar' ENV LD='/opt/rh/devtoolset-10/root/usr/bin/ld' -ENV SPC_DEFAULT_C_FLAGS='-fPIE -fPIC -O3 -march=native' +ENV SPC_DEFAULT_C_FLAGS='-fPIE -fPIC -O3' ENV SPC_LIBC='glibc' ENV SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM='-Wl,-O3 -pie' ENV SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS='-ldl -lpthread -lm -lresolv -lutil -lrt' diff --git a/static-builder-musl.Dockerfile b/static-builder-musl.Dockerfile index e122862b27..3f7ab48327 100644 --- a/static-builder-musl.Dockerfile +++ b/static-builder-musl.Dockerfile @@ -90,7 +90,7 @@ RUN go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get WORKDIR /go/src/app COPY --link . ./ -ENV SPC_DEFAULT_C_FLAGS='-fPIE -fPIC -O3 -march=native' +ENV SPC_DEFAULT_C_FLAGS='-fPIE -fPIC -O3' ENV SPC_LIBC='musl' ENV SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM='-Wl,-O3 -pie' From 22216b832cd62869a7d90cf90422a46c901e0656 Mon Sep 17 00:00:00 2001 From: Alliballibaba2 Date: Sun, 13 Apr 2025 14:46:42 +0200 Subject: [PATCH 6/6] Fixes command --- .github/workflows/static.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/static.yaml b/.github/workflows/static.yaml index 122b75555e..976def3140 100644 --- a/.github/workflows/static.yaml +++ b/.github/workflows/static.yaml @@ -394,7 +394,7 @@ jobs: "${BINARY}" list-modules | grep http.encoders.br "${BINARY}" list-modules | grep http.handlers.mercure "${BINARY}" list-modules | grep http.handlers.mercure - "${BINARY}" list-modules | grep http.handlers.vulcain# + "${BINARY}" list-modules | grep http.handlers.vulcain "${BINARY}" php-cli -r "echo 'Sanity check passed';" env: BINARY: dist/frankenphp-mac-${{ matrix.platform }}