Skip to content

Commit 3741782

Browse files
feat: '-r' option for php-cli (#1482)
1 parent a6e1d35 commit 3741782

File tree

7 files changed

+51
-11
lines changed

7 files changed

+51
-11
lines changed

.github/workflows/static.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ jobs:
177177
"${BINARY}" list-modules | grep http.handlers.mercure
178178
"${BINARY}" list-modules | grep http.handlers.mercure
179179
"${BINARY}" list-modules | grep http.handlers.vulcain
180+
"${BINARY}" php-cli -r "echo 'Sanity check passed';"
180181
env:
181182
BINARY: ./frankenphp-linux-${{ matrix.platform == 'linux/amd64' && 'x86_64' || 'aarch64' }}${{ matrix.debug && '-debug' || '' }}${{ matrix.mimalloc && '-mimalloc' || '' }}
182183

@@ -277,6 +278,7 @@ jobs:
277278
"${BINARY}" list-modules | grep http.handlers.mercure
278279
"${BINARY}" list-modules | grep http.handlers.mercure
279280
"${BINARY}" list-modules | grep http.handlers.vulcain
281+
"${BINARY}" php-cli -r "echo 'Sanity check passed';"
280282
env:
281283
BINARY: ./frankenphp-linux-${{ matrix.platform == 'linux/amd64' && 'x86_64' || 'aarch64' }}-gnu
282284

@@ -393,5 +395,6 @@ jobs:
393395
"${BINARY}" list-modules | grep http.handlers.mercure
394396
"${BINARY}" list-modules | grep http.handlers.mercure
395397
"${BINARY}" list-modules | grep http.handlers.vulcain
398+
"${BINARY}" php-cli -r "echo 'Sanity check passed';"
396399
env:
397400
BINARY: dist/frankenphp-mac-${{ matrix.platform }}

caddy/php-cli.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ func init() {
1919
Long: `
2020
Executes a PHP script similarly to the CLI SAPI.`,
2121
CobraFunc: func(cmd *cobra.Command) {
22-
cmd.DisableFlagParsing = true
22+
cmd.Flags().StringP("code", "r", "", "Execute PHP code directly without <php ... ?> tags")
2323
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdPHPCLI)
2424
},
2525
})
2626
}
2727

28-
func cmdPHPCLI(caddycmd.Flags) (int, error) {
28+
func cmdPHPCLI(fs caddycmd.Flags) (int, error) {
2929
args := os.Args[2:]
3030
if len(args) < 1 {
3131
return 1, errors.New("the path to the PHP script is required")
@@ -37,7 +37,13 @@ func cmdPHPCLI(caddycmd.Flags) (int, error) {
3737
}
3838
}
3939

40-
status := frankenphp.ExecuteScriptCLI(args[0], args)
40+
var status int
41+
if evalCode := fs.String("code"); evalCode != "" {
42+
status = frankenphp.ExecutePHPCode(evalCode)
43+
} else {
44+
status = frankenphp.ExecuteScriptCLI(args[0], args)
45+
}
46+
4147
os.Exit(status)
4248

4349
return status, nil

frankenphp.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,7 @@ static void sapi_cli_register_variables(zval *track_vars_array) /* {{{ */
11081108

11091109
static void *execute_script_cli(void *arg) {
11101110
void *exit_status;
1111+
bool eval = (bool)arg;
11111112

11121113
/*
11131114
* 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) {
11201121

11211122
cli_register_file_handles(false);
11221123
zend_first_try {
1123-
zend_file_handle file_handle;
1124-
zend_stream_init_filename(&file_handle, cli_script);
1124+
if (eval) {
1125+
/* evaluate the cli_script as literal PHP code (php-cli -r "...") */
1126+
zend_eval_string_ex(cli_script, NULL, "Command line code", 1);
1127+
} else {
1128+
zend_file_handle file_handle;
1129+
zend_stream_init_filename(&file_handle, cli_script);
11251130

1126-
CG(skip_shebang) = 1;
1127-
php_execute_script(&file_handle);
1131+
CG(skip_shebang) = 1;
1132+
php_execute_script(&file_handle);
1133+
}
11281134
}
11291135
zend_end_try();
11301136

@@ -1135,7 +1141,8 @@ static void *execute_script_cli(void *arg) {
11351141
return exit_status;
11361142
}
11371143

1138-
int frankenphp_execute_script_cli(char *script, int argc, char **argv) {
1144+
int frankenphp_execute_script_cli(char *script, int argc, char **argv,
1145+
bool eval) {
11391146
pthread_t thread;
11401147
int err;
11411148
void *exit_status;
@@ -1148,7 +1155,7 @@ int frankenphp_execute_script_cli(char *script, int argc, char **argv) {
11481155
* Start the script in a dedicated thread to prevent conflicts between Go and
11491156
* PHP signal handlers
11501157
*/
1151-
err = pthread_create(&thread, NULL, execute_script_cli, NULL);
1158+
err = pthread_create(&thread, NULL, execute_script_cli, (void *)eval);
11521159
if (err != 0) {
11531160
return err;
11541161
}

frankenphp.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,13 @@ func ExecuteScriptCLI(script string, args []string) int {
613613
argc, argv := convertArgs(args)
614614
defer freeArgs(argv)
615615

616-
return int(C.frankenphp_execute_script_cli(cScript, argc, (**C.char)(unsafe.Pointer(&argv[0]))))
616+
return int(C.frankenphp_execute_script_cli(cScript, argc, (**C.char)(unsafe.Pointer(&argv[0])), false))
617+
}
618+
619+
func ExecutePHPCode(phpCode string) int {
620+
cCode := C.CString(phpCode)
621+
defer C.free(unsafe.Pointer(cCode))
622+
return int(C.frankenphp_execute_script_cli(cCode, 0, nil, true))
617623
}
618624

619625
func convertArgs(args []string) (C.int, []*C.char) {

frankenphp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ int frankenphp_update_server_context(bool is_worker_request,
6161
int frankenphp_request_startup();
6262
int frankenphp_execute_script(char *file_name);
6363

64-
int frankenphp_execute_script_cli(char *script, int argc, char **argv);
64+
int frankenphp_execute_script_cli(char *script, int argc, char **argv,
65+
bool eval);
6566

6667
void frankenphp_register_variables_from_request_info(
6768
zval *track_vars_array, zend_string *content_type,

frankenphp_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,19 @@ func TestExecuteScriptCLI(t *testing.T) {
791791
assert.Contains(t, stdoutStderrStr, "From the CLI")
792792
}
793793

794+
func TestExecuteCLICode(t *testing.T) {
795+
if _, err := os.Stat("internal/testcli/testcli"); err != nil {
796+
t.Skip("internal/testcli/testcli has not been compiled, run `cd internal/testcli/ && go build`")
797+
}
798+
799+
cmd := exec.Command("internal/testcli/testcli", "-r", "echo 'Hello World';")
800+
stdoutStderr, err := cmd.CombinedOutput()
801+
assert.NoError(t, err)
802+
803+
stdoutStderrStr := string(stdoutStderr)
804+
assert.Equal(t, stdoutStderrStr, `Hello World`)
805+
}
806+
794807
func ExampleServeHTTP() {
795808
if err := frankenphp.Init(); err != nil {
796809
panic(err)

internal/testcli/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,9 @@ func main() {
1313
os.Exit(1)
1414
}
1515

16+
if len(os.Args) == 3 && os.Args[1] == "-r" {
17+
os.Exit(frankenphp.ExecutePHPCode(os.Args[2]))
18+
}
19+
1620
os.Exit(frankenphp.ExecuteScriptCLI(os.Args[1], os.Args))
1721
}

0 commit comments

Comments
 (0)