Skip to content

Commit ce5e43c

Browse files
committed
provide stable machine interface for ini on command line with json
1 parent 17d4002 commit ce5e43c

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

sapi/cli/cli.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ typedef enum php_cli_mode {
5050
PHP_CLI_MODE_REFLECTION_ZEND_EXTENSION = 12,
5151
PHP_CLI_MODE_SHOW_INI_CONFIG = 13,
5252
PHP_CLI_MODE_SHOW_INI_DIFF = 14,
53+
PHP_CLI_MODE_SHOW_INI_JSON = 15,
5354
} php_cli_mode;
5455

5556
typedef struct php_cli_server_context {

sapi/cli/php_cli.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
#include "zend_hash.h"
2626
#include "zend_modules.h"
2727
#include "zend_interfaces.h"
28+
#include "zend_smart_str.h"
2829

2930
#include "ext/reflection/php_reflection.h"
31+
#include "ext/json/php_json.h"
3032

3133
#include "SAPI.h"
3234

@@ -826,6 +828,8 @@ static int do_cli(int argc, char **argv) /* {{{ */
826828
if (php_optarg) {
827829
if (strcmp(php_optarg, "diff") == 0) {
828830
context.mode = PHP_CLI_MODE_SHOW_INI_DIFF;
831+
} else if(strcmp(php_optarg, "json") == 0) {
832+
context.mode = PHP_CLI_MODE_SHOW_INI_JSON;
829833
} else {
830834
param_error = "Unknown argument for --ini\n";
831835
}
@@ -1148,6 +1152,56 @@ static int do_cli(int argc, char **argv) /* {{{ */
11481152
zend_array_destroy(sorted);
11491153
break;
11501154
}
1155+
case PHP_CLI_MODE_SHOW_INI_JSON:
1156+
{
1157+
zval out;
1158+
array_init_size(&out, 4);
1159+
1160+
add_assoc_string(&out, "path", PHP_CONFIG_FILE_PATH);
1161+
if (php_ini_opened_path) {
1162+
add_assoc_string(&out, "file", php_ini_opened_path);
1163+
}
1164+
if (php_ini_scanned_path) {
1165+
add_assoc_string(&out, "scan", php_ini_scanned_path);
1166+
}
1167+
if (php_ini_scanned_files) {
1168+
char* scanning = estrdup(php_ini_scanned_files);
1169+
char* token;
1170+
char* next = php_strtok_r(scanning, ",\n", &token);
1171+
zval scanned;
1172+
array_init(&scanned);
1173+
1174+
while (next) {
1175+
while (*next == ' ' || *next == '\t') {
1176+
next++;
1177+
}
1178+
if (*next != '\0') {
1179+
char *end = next + strlen(next) - 1;
1180+
while (end > next && (*end == ' ' || *end == '\t')) {
1181+
*end = '\0';
1182+
end--;
1183+
}
1184+
add_next_index_string(&scanned, next);
1185+
}
1186+
next = php_strtok_r(NULL, ",\n", &token);
1187+
}
1188+
add_assoc_zval(&out, "scanned", &scanned);
1189+
efree(scanning);
1190+
}
1191+
smart_str buf = {0};
1192+
if (php_json_encode(&buf, &out,
1193+
PHP_JSON_PRETTY_PRINT) == SUCCESS) {
1194+
fwrite(ZSTR_VAL(buf.s), 1, ZSTR_LEN(buf.s), stdout);
1195+
fwrite("\n", 1, sizeof(char)-1, stdout);
1196+
} else {
1197+
fprintf(stderr,
1198+
"An error occured while trying to encode configuration\n");
1199+
EG(exit_status) = 1;
1200+
}
1201+
smart_str_free(&buf);
1202+
zval_dtor(&out);
1203+
break;
1204+
}
11511205
}
11521206
} zend_end_try();
11531207

sapi/cli/tests/026.phpt

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--TEST--
2+
CLI php --ini=json
3+
--SKIPIF--
4+
<?php
5+
include "skipif.inc";
6+
?>
7+
--FILE--
8+
<?php
9+
$php = \getenv('TEST_PHP_EXECUTABLE');
10+
11+
$interface = \shell_exec(\sprintf(
12+
"%s --ini=json",
13+
$php));
14+
$script = \shell_exec(\sprintf(
15+
"%s -r 'echo json_encode([
16+
\"file\" => php_ini_loaded_file(),
17+
\"scanned\" => php_ini_scanned_files() ?: []]);'",
18+
$php));
19+
20+
$response["interface"] = \json_decode($interface,
21+
JSON_THROW_ON_ERROR|JSON_OBJECT_AS_ARRAY);
22+
$response["script"] = \json_decode($script,
23+
JSON_THROW_ON_ERROR);
24+
if (isset($response["script"]["scanned"]) &&
25+
$response["script"]["scanned"]) {
26+
$response["script"]["scanned"] =
27+
\array_map('trim',\explode(
28+
",\n", $response["script"]["scanned"]));
29+
}
30+
31+
if (!isset($response["interface"]["file"]) &&
32+
isset($response["script"]["file"]) &&
33+
$response["script"]["file"]) {
34+
echo "interface is missing file\n";
35+
var_dump($response);
36+
}
37+
38+
if (!isset($response["interface"]["scanned"]) &&
39+
isset($response["script"]["scanned"]) &&
40+
$response["script"]["scanned"]) {
41+
echo "interface is missing scanned\n";
42+
var_dump($response);
43+
}
44+
45+
if (isset($response["interface"]["scanned"]) &&
46+
$response["interface"]["scanned"] != $response["script"]["scanned"]) {
47+
echo "interface and script scanned do not match\n";
48+
var_dump($response);
49+
}
50+
51+
echo "OK\n";
52+
?>
53+
--EXPECT--
54+
OK

0 commit comments

Comments
 (0)