Skip to content

Commit bfd7d89

Browse files
authored
[PHP] Add PHP 5.2 WebAssembly builds and runtime support (#3501)
## Summary - Introduce `LegacyPHPVersions` / `AllPHPVersions` type system and register PHP 5.2.17 in the version registry - Add Dockerfile and C-source changes for PHP 5.2 compilation: autoconf 2.13, pre-generated parser/scanner downloads, flex wrapper, polyfill extension compat (`ZEND_FE_END`/`PHP_FE_END`), yytext duplicate-definition handling, mysqlnd gating, CLI getopt linking, `php_cli_process_title` version guard - Commit pre-built PHP 5.2 WASM binaries for all four targets (web/node × JSPI/Asyncify) - Wire PHP 5.2 into the web worker and CLI: legacy PHP ini pre-creation (disables `ini_get_all`, OPcache), single-instance mode for PROXYFS, correct SQLite plugin selection, extension gating, PHP 5.2-compatible mu-plugin stub - Support downloading non-minified legacy WordPress versions from wordpress.org (1.0–6.2) ## Test plan - [x] `npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=5.2` succeeds - [x] `npx nx recompile-php:asyncify php-wasm-web -- --PHP_VERSION=5.2` succeeds - [x] `npx nx recompile-php:jspi php-wasm-node -- --PHP_VERSION=5.2` succeeds - [x] `npx nx recompile-php:asyncify php-wasm-node -- --PHP_VERSION=5.2` succeeds - [x] `npx nx typecheck playground-website` passes - [x] `npx nx run-many -t lint --projects=php-wasm-web,php-wasm-node,php-wasm-universal,playground-website` passes
1 parent 6468205 commit bfd7d89

62 files changed

Lines changed: 43478 additions & 647 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎package-lock.json‎

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/php-wasm/compile/build.js‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,17 @@ await cleanupOldMinorVersions();
287287
// Build the base image
288288
await asyncSpawn('make', ['base-image'], { cwd: sourceDir, stdio: 'inherit' });
289289

290+
const phpVersionForDockerfile = getArg('PHP_VERSION').replace('PHP_VERSION=', '');
291+
const dockerfile = phpVersionForDockerfile.startsWith('5.2')
292+
? 'php/Dockerfile-5-2'
293+
: 'php/Dockerfile';
294+
290295
await asyncSpawn(
291296
'docker',
292297
[
293298
'build',
294299
'-f',
295-
'php/Dockerfile',
300+
dockerfile,
296301
'..',
297302
'--tag=php-wasm',
298303
'--progress=plain',

‎packages/php-wasm/compile/php-post-message-to-js/post_message_to_js.c‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
#include "ext/standard/info.h"
44
#include <emscripten.h>
55

6+
/* PHP_FE_END was added in PHP 5.3.7; provide fallback for PHP 5.2 */
7+
#ifndef PHP_FE_END
8+
#define PHP_FE_END {NULL, NULL, NULL}
9+
#endif
10+
611
/**
712
* Provided by php_wasm.c:
813
*/
@@ -14,16 +19,22 @@ PHP_FUNCTION(post_message_to_js)
1419
char *data;
1520
int data_len;
1621

17-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data, &data_len) == FAILURE) {
22+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == FAILURE) {
1823
return;
1924
}
2025

2126
char *response;
2227
size_t response_len = js_module_onMessage(data, &response);
23-
if (response_len != -1) {
28+
if (response_len != (size_t)-1) {
29+
#if PHP_MAJOR_VERSION >= 7
2430
zend_string *return_string = zend_string_init(response, response_len, 0);
2531
free(response);
2632
RETURN_NEW_STR(return_string);
33+
#else
34+
RETVAL_STRINGL(response, response_len, 1);
35+
free(response);
36+
return;
37+
#endif
2738
} else {
2839
RETURN_NULL();
2940
}
@@ -39,6 +50,12 @@ PHP_MINFO_FUNCTION(post_message_to_js)
3950
}
4051
/* }}} */
4152

53+
/* {{{ arginfo */
54+
ZEND_BEGIN_ARG_INFO_EX(arginfo_post_message_to_js, 0, 1, 1)
55+
ZEND_ARG_INFO(0, data)
56+
ZEND_END_ARG_INFO()
57+
/* }}} */
58+
4259
/* {{{ post_message_to_js_functions[] */
4360
const zend_function_entry post_message_to_js_functions[] = {
4461
PHP_FE(post_message_to_js, arginfo_post_message_to_js)

‎packages/php-wasm/compile/php-post-message-to-js/post_message_to_js.h‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
extern zend_module_entry post_message_to_js_module_entry;
55
#define phpext_post_message_to_js_ptr &post_message_to_js_module_entry
66

7-
ZEND_BEGIN_ARG_INFO_EX(arginfo_post_message_to_js, 0, 1, 1)
8-
ZEND_ARG_INFO(0, data)
9-
ZEND_END_ARG_INFO()
10-
117
PHP_FUNCTION(post_message_to_js);
128

139
#define PHP_POST_MESSAGE_TO_JS_VERSION "1.0.0"

‎packages/php-wasm/compile/php-wasm-dns-polyfill/dns_polyfill.c‎

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
#include "dns_polyfill.h"
66
#include "ext/standard/info.h"
77

8+
/* ZEND_FE_END was added in PHP 5.3.7; provide fallback for PHP 5.2 */
9+
#ifndef ZEND_FE_END
10+
#define ZEND_FE_END {NULL, NULL, NULL}
11+
#endif
12+
813
#ifdef HAVE_SYS_SOCKET_H
914
#include <sys/socket.h>
1015
#endif
@@ -119,21 +124,27 @@ PHP_FUNCTION(dns_check_record)
119124
HEADER *hp;
120125
querybuf answer = {0};
121126
char *hostname;
127+
#if PHP_MAJOR_VERSION >= 7
122128
size_t hostname_len;
123129
size_t rectype_len = 0;
124130
zend_string *rectype = NULL;
131+
#else
132+
int hostname_len;
133+
int rectype_len = 0;
134+
char *rectype = NULL;
135+
#endif
125136
int type = DNS_T_MX, i;
126137

127-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", &hostname, &hostname_len, &rectype, &rectype_len) == FAILURE) {
138+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &hostname, &hostname_len, &rectype, &rectype_len) == FAILURE) {
128139
return;
129140
}
130141

131142
if (hostname_len == 0) {
132-
php_error_docref(NULL, E_WARNING, "Host cannot be empty");
143+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host cannot be empty");
133144
RETURN_FALSE;
134145
}
135146

136-
php_error_docref(NULL, E_WARNING, "dns_check_record() always returns false in PHP.wasm.");
147+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "dns_check_record() always returns false in PHP.wasm.");
137148

138149
RETURN_FALSE;
139150
}
@@ -143,8 +154,13 @@ PHP_FUNCTION(dns_check_record)
143154
PHP_FUNCTION(dns_get_record)
144155
{
145156
char *hostname;
157+
#if PHP_MAJOR_VERSION >= 7
146158
size_t hostname_len;
147159
zend_long type_param = PHP_DNS_ANY;
160+
#else
161+
int hostname_len;
162+
long type_param = PHP_DNS_ANY;
163+
#endif
148164
zval *authns = NULL, *addtl = NULL;
149165
int type_to_fetch;
150166
int dns_errno;
@@ -155,7 +171,7 @@ PHP_FUNCTION(dns_get_record)
155171
int type, first_query = 1, store_results = 1;
156172
zend_bool raw = 0;
157173

158-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lz!z!b",
174+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz!z!b",
159175
&hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) {
160176
return;
161177
}
@@ -173,7 +189,7 @@ PHP_FUNCTION(dns_get_record)
173189
}
174190
}
175191

176-
php_error_docref(NULL, E_WARNING, "dns_get_record() always returns an empty array in PHP.wasm.");
192+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "dns_get_record() always returns an empty array in PHP.wasm.");
177193

178194
/* Initialize the return array */
179195
array_init(return_value);
@@ -186,7 +202,11 @@ PHP_FUNCTION(dns_get_record)
186202
PHP_FUNCTION(dns_get_mx)
187203
{
188204
char *hostname;
205+
#if PHP_MAJOR_VERSION >= 7
189206
size_t hostname_len;
207+
#else
208+
int hostname_len;
209+
#endif
190210
zval *mx_list, *weight_list = NULL;
191211
int count, qdc;
192212
u_short type, weight;
@@ -196,12 +216,18 @@ PHP_FUNCTION(dns_get_mx)
196216
uint8_t *cp, *end;
197217
int i;
198218

219+
#if PHP_MAJOR_VERSION >= 7
199220
ZEND_PARSE_PARAMETERS_START(2, 3)
200221
Z_PARAM_STRING(hostname, hostname_len)
201222
Z_PARAM_ZVAL(mx_list)
202223
Z_PARAM_OPTIONAL
203224
Z_PARAM_ZVAL(weight_list)
204225
ZEND_PARSE_PARAMETERS_END();
226+
#else
227+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) {
228+
return;
229+
}
230+
#endif
205231

206232
array_init(mx_list);
207233
if (!mx_list) {
@@ -215,7 +241,7 @@ PHP_FUNCTION(dns_get_mx)
215241
}
216242
}
217243

218-
php_error_docref(NULL, E_WARNING, "dns_get_mx() always returns an empty array in PHP.wasm.");
244+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "dns_get_mx() always returns an empty array in PHP.wasm.");
219245

220246
RETURN_FALSE;
221247
}
@@ -256,6 +282,31 @@ PHP_MSHUTDOWN_FUNCTION(dns_polyfill)
256282
return SUCCESS;
257283
}
258284

285+
/* {{{ arginfo definitions */
286+
ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_check_record, 0, 0, 1)
287+
ZEND_ARG_INFO(0, host)
288+
ZEND_ARG_INFO(0, type)
289+
ZEND_END_ARG_INFO()
290+
291+
#define arginfo_checkdnsrr arginfo_dns_check_record
292+
293+
ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_record, 0, 0, 1)
294+
ZEND_ARG_INFO(0, hostname)
295+
ZEND_ARG_INFO(0, type)
296+
ZEND_ARG_ARRAY_INFO(1, authns, 1)
297+
ZEND_ARG_ARRAY_INFO(1, addtl, 1)
298+
ZEND_ARG_INFO(0, raw)
299+
ZEND_END_ARG_INFO()
300+
301+
ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_mx, 0, 0, 2)
302+
ZEND_ARG_INFO(0, hostname)
303+
ZEND_ARG_INFO(1, mxhosts)
304+
ZEND_ARG_INFO(1, weight)
305+
ZEND_END_ARG_INFO()
306+
307+
#define arginfo_getmxrr arginfo_dns_get_mx
308+
/* }}} */
309+
259310
/* {{{ dns_polyfill_functions[] */
260311
const zend_function_entry dns_polyfill_functions[] = {
261312
ZEND_FE(dns_get_mx, arginfo_dns_get_mx)

‎packages/php-wasm/compile/php-wasm-dns-polyfill/dns_polyfill.h‎

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,33 +53,8 @@
5353
extern zend_module_entry dns_polyfill_module_entry;
5454
#define phpext_dns_polyfill_ptr &dns_polyfill_module_entry
5555

56-
ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_check_record, 0, 0, 1)
57-
ZEND_ARG_INFO(0, host)
58-
ZEND_ARG_INFO(0, type)
59-
ZEND_END_ARG_INFO()
60-
61-
#define arginfo_checkdnsrr arginfo_dns_check_record
62-
6356
PHP_FUNCTION(dns_check_record);
64-
65-
ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_record, 0, 0, 1)
66-
ZEND_ARG_INFO(0, hostname)
67-
ZEND_ARG_INFO(0, type)
68-
ZEND_ARG_ARRAY_INFO(1, authns, 1)
69-
ZEND_ARG_ARRAY_INFO(1, addtl, 1)
70-
ZEND_ARG_INFO(0, raw)
71-
ZEND_END_ARG_INFO()
72-
7357
PHP_FUNCTION(dns_get_record);
74-
75-
ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_mx, 0, 0, 2)
76-
ZEND_ARG_INFO(0, hostname)
77-
ZEND_ARG_INFO(1, mxhosts) /* ARRAY_INFO(1, mxhosts, 1) */
78-
ZEND_ARG_INFO(1, weight) /* ARRAY_INFO(1, weight, 1) */
79-
ZEND_END_ARG_INFO()
80-
81-
#define arginfo_getmxrr arginfo_dns_get_mx
82-
8358
PHP_FUNCTION(dns_get_mx);
8459

8560
#define PHP_DNS_POLYFILL_VERSION "1.0.0"

‎packages/php-wasm/compile/php-wasm-memory-storage/wasm_memory_storage.c‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "Zend/zend_alloc.h"
2323
#include "php_wasm_memory_storage.h"
2424

25+
#if PHP_MAJOR_VERSION >= 7
26+
2527
/**
2628
* Allocate a chunk of memory.
2729
*
@@ -112,6 +114,22 @@ PHP_MSHUTDOWN_FUNCTION(wasm_memory_storage)
112114
return SUCCESS;
113115
}
114116

117+
#else /* PHP < 7 */
118+
119+
/* Custom memory storage is not available in PHP 5.x.
120+
* Provide no-op MINIT/MSHUTDOWN. */
121+
PHP_MINIT_FUNCTION(wasm_memory_storage)
122+
{
123+
return SUCCESS;
124+
}
125+
126+
PHP_MSHUTDOWN_FUNCTION(wasm_memory_storage)
127+
{
128+
return SUCCESS;
129+
}
130+
131+
#endif /* PHP_MAJOR_VERSION >= 7 */
132+
115133
/* {{{ PHP_MINFO_FUNCTION */
116134
PHP_MINFO_FUNCTION(wasm_memory_storage)
117135
{

0 commit comments

Comments
 (0)