From f17c5ad83b67a61ec33c893c2009c0c4aeb50be7 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 3 Mar 2026 20:06:40 +0100 Subject: [PATCH 1/4] Windows build: Add new function CHECK_HEADER() (#21191) The current function `CHECK_HEADER_ADD_INCLUDE()` automatically defines `HAVE_` preprocessor macros, which makes it difficult to sync with other build systems. Specially, if some `HAVE_` macro is used in the code and this function defines this macro but Autotools doesn't. The new `CHECK_HEADER()` function behaves similar except it doesn't define the `HAVE_` preprocessor macro. This removes the following unused compile definitions: HAVE_ARGON2_H HAVE_AVIF_H HAVE_BZLIB_H HAVE_CAPSTONE_CAPSTONE_H HAVE_CURL_EASY_H HAVE_DB_H HAVE_DECODE_H HAVE_DEPOT_H HAVE_EDITLINE_READLINE_H HAVE_ENCHANT_H HAVE_ENCODE_H HAVE_FFI_H HAVE_FIREBIRD_INTERFACE_H HAVE_FT2BUILD_H HAVE_GD_H HAVE_GLIB_H HAVE_GMP_H HAVE_HTTPD_H HAVE_IBASE_H HAVE_IR_IR_H HAVE_KECCAKHASH_H HAVE_LBER_H HAVE_LDAP_H HAVE_LIBEXSLT_EXSLT_H HAVE_LIBINTL_H HAVE_LIBPQ_FE_H HAVE_LIBTIDY_TIDY_H HAVE_LIBXML_PARSER_H HAVE_LIBXML_TREE_H HAVE_LIBXML_XMLWRITER_H HAVE_LIBXSLT_XSLT_H HAVE_LMDB_H HAVE_MBSTRING_H HAVE_MYSQL_H HAVE_ONIGURUMA_H HAVE_OPENSSL_SSL_H HAVE_PNG_H HAVE_SNMP_H HAVE_SODIUM_H HAVE_SQLITE3_H HAVE_SQLITE3EXT_H HAVE_SYBFRONT_H HAVE_TIDY_H HAVE_TIDY_TIDY_H HAVE_TIDYBUFFIO_H HAVE_TIMELIB_CONFIG_H HAVE_UNICODE_USPOOF_H HAVE_UNICODE_UTF_H HAVE_XPM_H HAVE_ZIP_H HAVE_ZIPCONF_H HAVE_ZLIB_H The following compile definitions are defined explicitly: - HAVE_ICONV_H - HAVE_MSCOREE_H - HAVE_SQL_H - HAVE_SQLEXT_H Additionally, the `SETUP_OPENSSL()` function doesn't accept the 6th argument anymore. --- UPGRADING.INTERNALS | 8 +++++ ext/bz2/config.w32 | 2 +- ext/com_dotnet/config.w32 | 6 +++- ext/curl/config.w32 | 2 +- ext/dba/config.w32 | 6 ++-- ext/dom/config.w32 | 2 +- ext/enchant/config.w32 | 4 +-- ext/ffi/config.w32 | 2 +- ext/gd/config.w32 | 25 ++++++++------- ext/gettext/config.w32 | 2 +- ext/gmp/config.w32 | 2 +- ext/hash/config.w32 | 2 +- ext/iconv/config.w32 | 2 +- ext/intl/config.w32 | 4 +-- ext/ldap/config.w32 | 4 +-- ext/libxml/config.w32 | 4 +-- ext/mbstring/config.w32 | 4 +-- ext/mysqlnd/config.w32 | 2 +- ext/odbc/config.w32 | 4 +-- ext/opcache/config.w32 | 4 +-- ext/pdo_dblib/config.w32 | 4 +-- ext/pdo_firebird/config.w32 | 4 +-- ext/pdo_mysql/config.w32 | 2 +- ext/pdo_odbc/config.w32 | 6 ++-- ext/pdo_pgsql/config.w32 | 2 +- ext/pgsql/config.w32 | 2 +- ext/readline/config.w32 | 2 +- ext/simplexml/config.w32 | 2 +- ext/snmp/config.w32 | 2 +- ext/soap/config.w32 | 4 +-- ext/sodium/config.w32 | 2 +- ext/standard/config.w32 | 4 +-- ext/tidy/config.w32 | 8 ++--- ext/xml/config.w32 | 4 +-- ext/xmlreader/config.w32 | 4 +-- ext/xmlwriter/config.w32 | 2 +- ext/xsl/config.w32 | 6 ++-- ext/zip/config.w32 | 4 +-- ext/zlib/config.w32 | 2 +- sapi/apache2handler/config.w32 | 2 +- sapi/cli/config.w32 | 2 +- win32/build/confutils.js | 57 +++++++++++++++++++++++++++++++--- 42 files changed, 141 insertions(+), 77 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index fc672ac54a82..ccdba855ec52 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -92,6 +92,14 @@ PHP 8.6 INTERNALS UPGRADE NOTES . Symbol HAVE_ST_BLOCKS has been removed from php_config.h (use HAVE_STRUCT_STAT_ST_BLOCKS). +- Windows build system changes: + . Function SETUP_OPENSSL() doesn't accept 6th argument anymore and doesn't + define the HAVE_OPENSSL_SSL_H preprocessor macro anymore. + . Function SETUP_SQLITE3() doesn't define HAVE_SQLITE3_H and HAVE_SQLITE3EXT_H + preprocessor macros anymore. + . Added a new function CHECK_HEADER() which is intended to be used instead of + the CHECK_HEADER_ADD_INCLUDE(). + ======================== 3. Module changes ======================== diff --git a/ext/bz2/config.w32 b/ext/bz2/config.w32 index afbb8c648cc5..a716320d2ffb 100644 --- a/ext/bz2/config.w32 +++ b/ext/bz2/config.w32 @@ -4,7 +4,7 @@ ARG_WITH("bz2", "BZip2", "no"); if (PHP_BZ2 != "no") { if (CHECK_LIB("libbz2_a.lib;libbz2.lib", "bz2", PHP_BZ2) && - CHECK_HEADER_ADD_INCLUDE("bzlib.h", "CFLAGS_BZ2")) { + CHECK_HEADER("bzlib.h", "CFLAGS_BZ2")) { EXTENSION("bz2", "bz2.c bz2_filter.c"); AC_DEFINE('HAVE_BZ2', 1, "Define to 1 if the PHP extension 'bz2' is available."); // BZ2 extension does this slightly differently from others diff --git a/ext/com_dotnet/config.w32 b/ext/com_dotnet/config.w32 index c4fba4fc539d..0fca82e1dd75 100644 --- a/ext/com_dotnet/config.w32 +++ b/ext/com_dotnet/config.w32 @@ -9,6 +9,10 @@ if (PHP_COM_DOTNET == "yes") { com_typeinfo.c com_variant.c com_wrapper.c com_saproxy.c com_persist.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE('HAVE_COM_DOTNET', 1, "Define to 1 if the PHP extension 'com_dotnet' is available."); - CHECK_HEADER_ADD_INCLUDE('mscoree.h', 'CFLAGS_COM_DOTNET'); + + if (CHECK_HEADER('mscoree.h', 'CFLAGS_COM_DOTNET')) { + AC_DEFINE('HAVE_MSCOREE_H', 1, 'Define to 1 if you have the header file.'); + } + ADD_MAKEFILE_FRAGMENT(); } diff --git a/ext/curl/config.w32 b/ext/curl/config.w32 index e097a697eb55..a4bdce59ccb1 100644 --- a/ext/curl/config.w32 +++ b/ext/curl/config.w32 @@ -5,7 +5,7 @@ ARG_WITH("curl", "cURL support", "no"); if (PHP_CURL != "no") { var curl_location; if ((curl_location = CHECK_LIB("libcurl_a.lib;libcurl.lib", "curl", PHP_CURL)) && - CHECK_HEADER_ADD_INCLUDE("curl/easy.h", "CFLAGS_CURL") && + CHECK_HEADER("curl/easy.h", "CFLAGS_CURL") && SETUP_OPENSSL("curl", PHP_CURL) >= 2 && CHECK_LIB("winmm.lib", "curl", PHP_CURL) && CHECK_LIB("wldap32.lib", "curl", PHP_CURL) && diff --git a/ext/dba/config.w32 b/ext/dba/config.w32 index 5017097fe758..0bb9bcc3f4ee 100644 --- a/ext/dba/config.w32 +++ b/ext/dba/config.w32 @@ -15,7 +15,7 @@ if (PHP_DBA != "no") { if (PHP_DB != "no") { if (CHECK_LIB("libdb31s.lib;libdb61.lib", "dba", PHP_DBA) && - CHECK_HEADER_ADD_INCLUDE("db.h", "CFLAGS_DBA")) { + CHECK_HEADER("db.h", "CFLAGS_DBA")) { ADD_FLAG("CFLAGS_DBA", "/D DB1_VERSION=\"\\\"Berkeley DB 1.85 emulation in DB3\\\"\" /D DB1_INCLUDE_FILE=\"\\\"db_185.h\\\"\" /D DBA_DB3=1 /D DB3_INCLUDE_FILE=\"\\\"db.h\\\"\""); } else { WARNING("dba: db handlers not enabled; libraries and headers not found"); @@ -24,7 +24,7 @@ if (PHP_DBA != "no") { if (PHP_QDBM != "no") { if (CHECK_LIB("qdbm_a.lib;qdbm.lib", "dba", PHP_DBA) && - CHECK_HEADER_ADD_INCLUDE("depot.h", "CFLAGS_DBA", PHP_DBA + ";" + PHP_PHP_BUILD + "\\include\\qdbm")) { + CHECK_HEADER("depot.h", "CFLAGS_DBA", PHP_DBA + ";" + PHP_PHP_BUILD + "\\include\\qdbm")) { ADD_SOURCES("ext/dba", "dba_qdbm.c", "dba"); AC_DEFINE("QDBM_INCLUDE_FILE", "", "The QDBM handler header file.", false); AC_DEFINE("DBA_QDBM", 1, "Define to 1 if the dba extension uses the QDBM handler."); @@ -35,7 +35,7 @@ if (PHP_DBA != "no") { if (PHP_LMDB != "no") { if (CHECK_LIB("liblmdb_a.lib", "dba", PHP_DBA) && - CHECK_HEADER_ADD_INCLUDE("lmdb.h", "CFLAGS_DBA") && + CHECK_HEADER("lmdb.h", "CFLAGS_DBA") && CHECK_LIB("ntdll.lib", "dba", PHP_DBA)) { ADD_SOURCES("ext/dba", "dba_lmdb.c", "dba"); AC_DEFINE("LMDB_INCLUDE_FILE", "", "The LMDB handler header file.", false); diff --git a/ext/dom/config.w32 b/ext/dom/config.w32 index 2d8f3f3519c4..e045e29c6bab 100644 --- a/ext/dom/config.w32 +++ b/ext/dom/config.w32 @@ -5,7 +5,7 @@ ARG_WITH("dom", "DOM support", "yes"); if (PHP_DOM == "yes") { if (PHP_LIBXML == "yes" && ADD_EXTENSION_DEP('dom', 'libxml') && - CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_DOM", PHP_PHP_BUILD + "\\include\\libxml2") + CHECK_HEADER("libxml/parser.h", "CFLAGS_DOM", PHP_PHP_BUILD + "\\include\\libxml2") ) { EXTENSION("dom", "php_dom.c attr.c document.c infra.c \ xml_document.c html_document.c xml_serializer.c html5_serializer.c html5_parser.c namespace_compat.c private_data.c \ diff --git a/ext/enchant/config.w32 b/ext/enchant/config.w32 index c50f48ffb6c8..45a194cdb7ff 100644 --- a/ext/enchant/config.w32 +++ b/ext/enchant/config.w32 @@ -3,8 +3,8 @@ ARG_WITH("enchant", "Enchant Support", "no"); if (PHP_ENCHANT == "yes") { - if (CHECK_HEADER_ADD_INCLUDE("enchant.h", "CFLAGS_ENCHANT", PHP_ENCHANT+ ";" + PHP_PHP_BUILD + "\\include\\enchant") && - CHECK_HEADER_ADD_INCLUDE("glib.h", "CFLAGS_ENCHANT", PHP_ENCHANT+ ";" + PHP_PHP_BUILD + "\\include\\glib-2.0")) { + if (CHECK_HEADER("enchant.h", "CFLAGS_ENCHANT", PHP_ENCHANT+ ";" + PHP_PHP_BUILD + "\\include\\enchant") && + CHECK_HEADER("glib.h", "CFLAGS_ENCHANT", PHP_ENCHANT+ ";" + PHP_PHP_BUILD + "\\include\\glib-2.0")) { if (CHECK_LIB("libenchant2.lib", "enchant", PHP_ENCHANT)) { have_enchant = true; } else if (CHECK_LIB("libenchant.lib", "enchant", PHP_ENCHANT)) { diff --git a/ext/ffi/config.w32 b/ext/ffi/config.w32 index cfe54706a871..c3d3e7289189 100644 --- a/ext/ffi/config.w32 +++ b/ext/ffi/config.w32 @@ -1,7 +1,7 @@ ARG_WITH('ffi', 'ffi support', 'no'); if (PHP_FFI != 'no') { - if (CHECK_HEADER_ADD_INCLUDE("ffi.h", "CFLAGS_FFI", PHP_FFI+ ";" + PHP_PHP_BUILD + "\\include") && + if (CHECK_HEADER("ffi.h", "CFLAGS_FFI", PHP_FFI+ ";" + PHP_PHP_BUILD + "\\include") && CHECK_LIB("libffi.lib", "ffi", PHP_FFI)) { AC_DEFINE('HAVE_FFI', 1, "Define to 1 if the PHP extension 'ffi' is available."); diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index a86693ad74be..506bb05cf2e0 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -8,28 +8,29 @@ if (PHP_GD != "no") { if ( CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) && CHECK_LIB("freetype_a.lib;freetype.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("ft2build.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\freetype2;" + PHP_PHP_BUILD + "\\include\\freetype") && + CHECK_HEADER("ft2build.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\freetype2;" + PHP_PHP_BUILD + "\\include\\freetype") && CHECK_LIB("libpng_a.lib;libpng.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd") && - (CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng16") || - CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng15") || - CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng12")) && + CHECK_HEADER("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd") && + (CHECK_HEADER("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng16") || + CHECK_HEADER("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng15") || + CHECK_HEADER("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng12")) && (CHECK_LIB("libiconv_a.lib;libiconv.lib", "gd", PHP_GD) || CHECK_LIB("iconv_a.lib;iconv.lib", "gd", PHP_GD)) && - CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_GD", PHP_GD) && + CHECK_HEADER("iconv.h", "CFLAGS_GD", PHP_GD) && SETUP_ZLIB_LIB("gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects) + CHECK_HEADER("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects) ) { + AC_DEFINE('HAVE_ICONV_H', 1, 'Define to 1 if you have the header'); if (CHECK_LIB("libXpm_a.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("xpm.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\X11") + CHECK_HEADER("xpm.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\X11") ) { AC_DEFINE('HAVE_XPM', 1, "Define to 1 if you have the xpm library."); AC_DEFINE('HAVE_GD_XPM', 1, "Define to 1 if gd extension has XPM support."); } if (PHP_LIBWEBP != "no") { if ((CHECK_LIB("libwebp_a.lib", "gd", PHP_GD) || CHECK_LIB("libwebp.lib", "gd", PHP_GD)) && - CHECK_HEADER_ADD_INCLUDE("decode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") && - CHECK_HEADER_ADD_INCLUDE("encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp")) { + CHECK_HEADER("decode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") && + CHECK_HEADER("encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp")) { AC_DEFINE("HAVE_LIBWEBP", 1, "Define to 1 if you have the libwebp library."); AC_DEFINE("HAVE_GD_WEBP", 1, "Define to 1 if gd extension has WebP support."); } else { @@ -39,10 +40,10 @@ if (PHP_GD != "no") { if (PHP_LIBAVIF != "no") { if (CHECK_LIB("avif_a.lib", "gd", PHP_GD) && CHECK_LIB("aom_a.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) { + CHECK_HEADER("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) { ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBAVIF /D HAVE_GD_AVIF"); } else if (CHECK_LIB("avif.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) { + CHECK_HEADER("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) { ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBAVIF /D HAVE_GD_AVIF"); } else { WARNING("libavif not enabled; libraries and headers not found"); diff --git a/ext/gettext/config.w32 b/ext/gettext/config.w32 index 3e644655426b..e4a4168d949b 100644 --- a/ext/gettext/config.w32 +++ b/ext/gettext/config.w32 @@ -3,7 +3,7 @@ ARG_WITH("gettext", "gettext support", "no"); if (PHP_GETTEXT != "no") { - if (CHECK_LIB("libintl_a.lib;libintl.lib", "gettext", PHP_GETTEXT) && CHECK_HEADER_ADD_INCLUDE("libintl.h", "CFLAGS_GETTEXT")) { + if (CHECK_LIB("libintl_a.lib;libintl.lib", "gettext", PHP_GETTEXT) && CHECK_HEADER("libintl.h", "CFLAGS_GETTEXT")) { EXTENSION("gettext", "gettext.c", PHP_GETTEXT_SHARED, "-DHAVE_BIND_TEXTDOMAIN_CODESET=1 -DHAVE_DNGETTEXT=1 -DHAVE_NGETTEXT=1 -DHAVE_LIBINTL=1 -DHAVE_DCNGETTEXT=1"); } else { WARNING("gettext not enabled; libraries and headers not found"); diff --git a/ext/gmp/config.w32 b/ext/gmp/config.w32 index 2bb4aa63ad0f..dc0c1e978d31 100644 --- a/ext/gmp/config.w32 +++ b/ext/gmp/config.w32 @@ -4,7 +4,7 @@ ARG_WITH("gmp", "Include GNU MP support.", "no"); if (PHP_GMP != "no") { if (CHECK_LIB("mpir_a.lib", "gmp", PHP_GMP) && - CHECK_HEADER_ADD_INCLUDE("gmp.h", "CFLAGS_GMP", PHP_GMP + ";" + PHP_PHP_BUILD + "\\include\\mpir")) { + CHECK_HEADER("gmp.h", "CFLAGS_GMP", PHP_GMP + ";" + PHP_PHP_BUILD + "\\include\\mpir")) { EXTENSION("gmp", "gmp.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); PHP_INSTALL_HEADERS("ext/gmp", "php_gmp_int.h"); AC_DEFINE('HAVE_GMP', 1, "Define to 1 if the PHP extension 'gmp' is available."); diff --git a/ext/hash/config.w32 b/ext/hash/config.w32 index dd4c050bcd25..e63efcfd84cb 100644 --- a/ext/hash/config.w32 +++ b/ext/hash/config.w32 @@ -22,7 +22,7 @@ if(X64) { ADD_SOURCES(hash_sha3_dir, 'KeccakHash.c KeccakSponge.c KeccakP-1600-inplace32BI.c', 'hash'); } -if (!CHECK_HEADER_ADD_INCLUDE('KeccakHash.h', 'CFLAGS_HASH', hash_sha3_dir)) { +if (!CHECK_HEADER('KeccakHash.h', 'CFLAGS_HASH', hash_sha3_dir)) { // Should NEVER happen ERROR('Unable to locate SHA3 headers'); } diff --git a/ext/iconv/config.w32 b/ext/iconv/config.w32 index d99c53fb9363..b8fe6804d526 100644 --- a/ext/iconv/config.w32 +++ b/ext/iconv/config.w32 @@ -5,7 +5,7 @@ ARG_WITH("iconv", "iconv support", "yes"); if (PHP_ICONV != "no") { if ((CHECK_LIB("libiconv_a.lib", "iconv", PHP_ICONV) || CHECK_LIB("libiconv.lib", "iconv", PHP_ICONV) || CHECK_LIB("iconv_a.lib", "iconv", PHP_ICONV) || CHECK_LIB("iconv.lib", "iconv", PHP_ICONV)) && - CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_ICONV", PHP_ICONV)) { + CHECK_HEADER("iconv.h", "CFLAGS_ICONV", PHP_ICONV)) { EXTENSION("iconv", "iconv.c", PHP_ICONV_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index d5c86d123671..da8285b50d0c 100644 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -7,7 +7,7 @@ if (PHP_INTL != "no") { CHECK_LIB("icuin.lib", "intl", PHP_INTL) && CHECK_LIB("icuio.lib", "intl", PHP_INTL) && CHECK_LIB("icuuc.lib", "intl", PHP_INTL) && - CHECK_HEADER_ADD_INCLUDE("unicode/utf.h", "CFLAGS_INTL")) { + CHECK_HEADER("unicode/utf.h", "CFLAGS_INTL")) { // always build as shared - zend_strtod.c/ICU type conflict EXTENSION("intl", "php_intl.c intl_convert.c intl_convertcpp.cpp intl_error.c ", true, "/I \"" + configure_module_dirname + "\" /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); @@ -92,7 +92,7 @@ if (PHP_INTL != "no") { resourcebundle_iterator.cpp", "intl"); - if (CHECK_HEADER_ADD_INCLUDE("unicode/uspoof.h", "CFLAGS_INTL")) { + if (CHECK_HEADER("unicode/uspoof.h", "CFLAGS_INTL")) { ADD_SOURCES(configure_module_dirname + "/spoofchecker", "\ spoofchecker_class.cpp \ spoofchecker_create.cpp \ diff --git a/ext/ldap/config.w32 b/ext/ldap/config.w32 index f9bc8662ac50..7dbb353dd80b 100644 --- a/ext/ldap/config.w32 +++ b/ext/ldap/config.w32 @@ -4,8 +4,8 @@ ARG_WITH("ldap", "LDAP support", "no"); if (PHP_LDAP != "no") { - if (CHECK_HEADER_ADD_INCLUDE("ldap.h", "CFLAGS_LDAP", PHP_PHP_BUILD + "\\include\\openldap;" + PHP_PHP_BUILD + "\\openldap\\include;" + PHP_LDAP) && - CHECK_HEADER_ADD_INCLUDE("lber.h", "CFLAGS_LDAP", PHP_PHP_BUILD + "\\include\\openldap;" + PHP_PHP_BUILD + "\\openldap\\include;" + PHP_LDAP) && + if (CHECK_HEADER("ldap.h", "CFLAGS_LDAP", PHP_PHP_BUILD + "\\include\\openldap;" + PHP_PHP_BUILD + "\\openldap\\include;" + PHP_LDAP) && + CHECK_HEADER("lber.h", "CFLAGS_LDAP", PHP_PHP_BUILD + "\\include\\openldap;" + PHP_PHP_BUILD + "\\openldap\\include;" + PHP_LDAP) && SETUP_OPENSSL("ldap", PHP_LDAP) >= 2 && CHECK_LIB("oldap32_a.lib", "ldap", PHP_LDAP) && CHECK_LIB("olber32_a.lib", "ldap", PHP_LDAP)&& diff --git a/ext/libxml/config.w32 b/ext/libxml/config.w32 index 2362ea0c2ba3..072dd691f214 100644 --- a/ext/libxml/config.w32 +++ b/ext/libxml/config.w32 @@ -5,8 +5,8 @@ ARG_WITH("libxml", "LibXML support", "yes"); if (PHP_LIBXML == "yes") { if (CHECK_LIB("libxml2_a_dll.lib;libxml2_a.lib", "libxml") && ((PHP_ICONV != "no" && !PHP_ICONV_SHARED) || CHECK_LIB("libiconv_a.lib;iconv_a.lib;libiconv.lib;iconv.lib", "libxml")) && - CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2") && - CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2")) { + CHECK_HEADER("libxml/parser.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2") && + CHECK_HEADER("libxml/tree.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2")) { if (GREP_HEADER("libxml/xmlversion.h", "#define\\s+LIBXML_VERSION\\s+(\\d+)", PHP_PHP_BUILD + "\\include\\libxml2") && +RegExp.$1 >= 20904) { diff --git a/ext/mbstring/config.w32 b/ext/mbstring/config.w32 index 070d3d73137a..7874da85a25d 100644 --- a/ext/mbstring/config.w32 +++ b/ext/mbstring/config.w32 @@ -5,7 +5,7 @@ ARG_ENABLE("mbregex", "multibyte regex support", "no"); if (PHP_MBSTRING != "no") { - if (CHECK_HEADER_ADD_INCLUDE("mbstring.h", "CFLAGS_MBSTRING", PHP_MBSTRING + ";" + PHP_PHP_BUILD + "\\include")) { + if (CHECK_HEADER("mbstring.h", "CFLAGS_MBSTRING", PHP_MBSTRING + ";" + PHP_PHP_BUILD + "\\include")) { EXTENSION("mbstring", "mbstring.c php_unicode.c mb_gpc.c", PHP_MBSTRING_SHARED); ADD_EXTENSION_DEP('mbstring', 'pcre'); @@ -42,7 +42,7 @@ if (PHP_MBSTRING != "no") { AC_DEFINE('HAVE_MBSTRING', 1, "Define to 1 if the PHP extension 'mbstring' is available."); if (PHP_MBREGEX != "no") { - if (CHECK_HEADER_ADD_INCLUDE("oniguruma.h", "CFLAGS_MBSTRING", PHP_MBREGEX) && + if (CHECK_HEADER("oniguruma.h", "CFLAGS_MBSTRING", PHP_MBREGEX) && CHECK_LIB("onig_a.lib;libonig_a.lib", "mbstring", PHP_MBSTRING)) { AC_DEFINE('HAVE_MBREGEX', 1, 'Define to 1 if mbstring has multibyte regex support enabled.'); diff --git a/ext/mysqlnd/config.w32 b/ext/mysqlnd/config.w32 index cf6bf4b61ccc..e88b269c4863 100644 --- a/ext/mysqlnd/config.w32 +++ b/ext/mysqlnd/config.w32 @@ -29,7 +29,7 @@ if (PHP_MYSQLND != "no") { "php_mysqlnd.c "; EXTENSION("mysqlnd", mysqlnd_source, false, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); if (SETUP_ZLIB_LIB("mysqlnd", PHP_MYSQLND) && - CHECK_HEADER_ADD_INCLUDE("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects) + CHECK_HEADER("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects) ) { AC_DEFINE("MYSQLND_COMPRESSION_ENABLED", 1, "Define to 1 if mysqlnd has compressed protocol support."); AC_DEFINE("MYSQLND_SSL_SUPPORTED", 1, "Define to 1 if mysqlnd core SSL is enabled."); diff --git a/ext/odbc/config.w32 b/ext/odbc/config.w32 index 7afa9ce8b649..242cc5992d46 100644 --- a/ext/odbc/config.w32 +++ b/ext/odbc/config.w32 @@ -4,8 +4,8 @@ ARG_ENABLE("odbc", "ODBC support", "no"); if (PHP_ODBC == "yes") { if (CHECK_LIB("odbc32.lib", "odbc") && CHECK_LIB("odbccp32.lib", "odbc") - && CHECK_HEADER_ADD_INCLUDE("sql.h", "CFLAGS_ODBC") - && CHECK_HEADER_ADD_INCLUDE("sqlext.h", "CFLAGS_ODBC")) { + && CHECK_HEADER("sql.h", "CFLAGS_ODBC") + && CHECK_HEADER("sqlext.h", "CFLAGS_ODBC")) { EXTENSION("odbc", "php_odbc.c odbc_utils.c", PHP_ODBC_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("HAVE_UODBC", 1, "Define to 1 if the PHP extension 'odbc' is available."); } else { diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32 index 9b8f2a7e5107..397fa1bdd87d 100644 --- a/ext/opcache/config.w32 +++ b/ext/opcache/config.w32 @@ -23,7 +23,7 @@ ADD_EXTENSION_DEP('opcache', 'pcre'); if (PHP_OPCACHE_JIT == "yes") { if (TARGET_ARCH == 'arm64') { WARNING("JIT not enabled; not yet supported for ARM64"); - } else if (CHECK_HEADER_ADD_INCLUDE("ir/ir.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) { + } else if (CHECK_HEADER("ir/ir.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) { var dasm_flags = (X64 ? "-D X64=1" : "") + (X64 ? " -D X64WIN=1" : "") + " -D WIN=1"; var ir_target = (X64 ? "IR_TARGET_X64" : "IR_TARGET_X86"); var ir_src = "ir_strtab.c ir_cfg.c ir_sccp.c ir_gcm.c ir_ra.c ir_save.c \ @@ -41,7 +41,7 @@ if (PHP_OPCACHE_JIT == "yes") { ADD_FLAG("CFLAGS_OPCACHE", "/D IR_DEBUG"); } - if (CHECK_HEADER_ADD_INCLUDE("capstone\\capstone.h", "CFLAGS_OPCACHE", PHP_OPCACHE+ ";" + PHP_PHP_BUILD + "\\include") && + if (CHECK_HEADER("capstone\\capstone.h", "CFLAGS_OPCACHE", PHP_OPCACHE+ ";" + PHP_PHP_BUILD + "\\include") && CHECK_LIB("capstone.lib", "opcache", PHP_OPCACHE)) { AC_DEFINE('HAVE_CAPSTONE', 1, 'Define to 1 if Capstone is available.'); ir_src += " ir_disasm.c"; diff --git a/ext/pdo_dblib/config.w32 b/ext/pdo_dblib/config.w32 index 4b1c76130f52..07e98d16a4af 100644 --- a/ext/pdo_dblib/config.w32 +++ b/ext/pdo_dblib/config.w32 @@ -7,7 +7,7 @@ if (PHP_PDO_DBLIB != "no") { * otherwise we'll poke around and look for MSSQL libs */ if (CHECK_LIB("sybdb.lib", "pdo_dblib", PHP_PDO_DBLIB) && - CHECK_HEADER_ADD_INCLUDE("sybfront.h", "CFLAGS_PDO_DBLIB", + CHECK_HEADER("sybfront.h", "CFLAGS_PDO_DBLIB", PHP_PDO_DBLIB, null, null, true)) { EXTENSION("pdo_dblib", "pdo_dblib.c dblib_driver.c dblib_stmt.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); @@ -24,7 +24,7 @@ if (PHP_PDO_MSSQL != "no") { PDO_DBLIB_FLAVOUR = 0; if (CHECK_LIB("sybdb.lib", "pdo_mssql", PHP_PDO_MSSQL) && - CHECK_HEADER_ADD_INCLUDE("sybfront.h", "CFLAGS_PDO_MSSQL", + CHECK_HEADER("sybfront.h", "CFLAGS_PDO_MSSQL", PHP_PDO_MSSQL, null, null, true)) { /* smells like FreeTDS (or maybe native sybase dblib) */ PDO_DBLIB_FLAVOUR = "freetds"; diff --git a/ext/pdo_firebird/config.w32 b/ext/pdo_firebird/config.w32 index 003a1a677082..1c5cb4214ad7 100644 --- a/ext/pdo_firebird/config.w32 +++ b/ext/pdo_firebird/config.w32 @@ -5,9 +5,9 @@ ARG_WITH("pdo-firebird", "Firebird support for PDO", "no"); if (PHP_PDO_FIREBIRD != "no") { if (CHECK_LIB("fbclient_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD) - && CHECK_HEADER_ADD_INCLUDE("ibase.h", "CFLAGS_PDO_FIREBIRD", + && CHECK_HEADER("ibase.h", "CFLAGS_PDO_FIREBIRD", PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) - && CHECK_HEADER_ADD_INCLUDE("firebird\\Interface.h", "CFLAGS_PDO_FIREBIRD", + && CHECK_HEADER("firebird\\Interface.h", "CFLAGS_PDO_FIREBIRD", PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) ) { diff --git a/ext/pdo_mysql/config.w32 b/ext/pdo_mysql/config.w32 index ece466975c55..95899d2270c8 100644 --- a/ext/pdo_mysql/config.w32 +++ b/ext/pdo_mysql/config.w32 @@ -12,7 +12,7 @@ if (PHP_PDO_MYSQL != "no") { ADD_MAKEFILE_FRAGMENT(); } else { if (CHECK_LIB("libmysql.lib", "pdo_mysql", PHP_PDO_MYSQL) && - CHECK_HEADER_ADD_INCLUDE("mysql.h", "CFLAGS_PDO_MYSQL", + CHECK_HEADER("mysql.h", "CFLAGS_PDO_MYSQL", PHP_PDO_MYSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\mysql;" + PHP_PDO_MYSQL)) { diff --git a/ext/pdo_odbc/config.w32 b/ext/pdo_odbc/config.w32 index 6a94da7f7953..e70516195718 100644 --- a/ext/pdo_odbc/config.w32 +++ b/ext/pdo_odbc/config.w32 @@ -4,11 +4,13 @@ ARG_WITH("pdo-odbc", "ODBC support for PDO", "no"); if (PHP_PDO_ODBC != "no") { if (CHECK_LIB("odbc32.lib", "pdo_odbc") && CHECK_LIB("odbccp32.lib", "pdo_odbc") - && CHECK_HEADER_ADD_INCLUDE('sql.h', 'CFLAGS_PDO_ODBC') - && CHECK_HEADER_ADD_INCLUDE('sqlext.h', 'CFLAGS_PDO_ODBC')) { + && CHECK_HEADER('sql.h', 'CFLAGS_PDO_ODBC') + && CHECK_HEADER('sqlext.h', 'CFLAGS_PDO_ODBC')) { EXTENSION("pdo_odbc", "pdo_odbc.c odbc_driver.c odbc_stmt.c"); ADD_EXTENSION_DEP('pdo_odbc', 'pdo'); + AC_DEFINE('HAVE_SQL_H', 1, 'Define to 1 if you have the header.'); + AC_DEFINE('HAVE_SQLEXT_H', 1, 'Define to 1 if you have the header.'); } else { WARNING("pdo_odbc support can't be enabled, headers or libraries are missing (SDK)") diff --git a/ext/pdo_pgsql/config.w32 b/ext/pdo_pgsql/config.w32 index aec5db508d07..5fc25f215900 100644 --- a/ext/pdo_pgsql/config.w32 +++ b/ext/pdo_pgsql/config.w32 @@ -4,7 +4,7 @@ ARG_WITH("pdo-pgsql", "PostgreSQL support for PDO", "no"); if (PHP_PDO_PGSQL != "no") { if (CHECK_LIB("libpq.lib", "pdo_pgsql", PHP_PDO_PGSQL) && - CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PDO_PGSQL", PHP_PDO_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;")) { + CHECK_HEADER("libpq-fe.h", "CFLAGS_PDO_PGSQL", PHP_PDO_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;")) { EXTENSION("pdo_pgsql", "pdo_pgsql.c pgsql_driver.c pgsql_statement.c pgsql_sql_parser.c"); AC_DEFINE('HAVE_PDO_PGSQL', 1, "Define to 1 if the PHP extension 'pdo_pgsql' is available."); diff --git a/ext/pgsql/config.w32 b/ext/pgsql/config.w32 index 3ca5fc2f1691..14eb5a07a0e9 100644 --- a/ext/pgsql/config.w32 +++ b/ext/pgsql/config.w32 @@ -4,7 +4,7 @@ ARG_WITH("pgsql", "PostgreSQL support", "no"); if (PHP_PGSQL != "no") { if (CHECK_LIB("libpq.lib", "pgsql", PHP_PGSQL) && - CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PGSQL", PHP_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;" + PHP_PGSQL)) { + CHECK_HEADER("libpq-fe.h", "CFLAGS_PGSQL", PHP_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;" + PHP_PGSQL)) { EXTENSION("pgsql", "pgsql.c", PHP_PGSQL_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE('HAVE_PGSQL', 1, "Define to 1 if the PHP extension 'pgsql' is available."); ADD_FLAG("CFLAGS_PGSQL", "/D PGSQL_EXPORTS"); diff --git a/ext/readline/config.w32 b/ext/readline/config.w32 index 8f3a2db61f23..2ff9cc8a2bbc 100644 --- a/ext/readline/config.w32 +++ b/ext/readline/config.w32 @@ -4,7 +4,7 @@ ARG_WITH("readline", "Readline support", "yes"); if (PHP_READLINE != "no") { if (CHECK_LIB("edit_a.lib;edit.lib", "readline", PHP_READLINE) && - CHECK_HEADER_ADD_INCLUDE("editline/readline.h", "CFLAGS_READLINE")) { + CHECK_HEADER("editline/readline.h", "CFLAGS_READLINE")) { EXTENSION("readline", "readline.c readline_cli.c"); ADD_FLAG("CFLAGS_READLINE", "/D HAVE_LIBEDIT"); ADD_FLAG("CFLAGS_READLINE", "/D HAVE_RL_COMPLETION_MATCHES"); diff --git a/ext/simplexml/config.w32 b/ext/simplexml/config.w32 index 8942e6c93e3b..0c2e7c5f5a79 100644 --- a/ext/simplexml/config.w32 +++ b/ext/simplexml/config.w32 @@ -6,7 +6,7 @@ if (PHP_SIMPLEXML == "yes") { if(PHP_LIBXML == "yes" && ADD_EXTENSION_DEP('simplexml', 'libxml') && ADD_EXTENSION_DEP('simplexml', 'spl') && - CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_SIMPLEXML", PHP_PHP_BUILD + "\\include\\libxml2") + CHECK_HEADER("libxml/tree.h", "CFLAGS_SIMPLEXML", PHP_PHP_BUILD + "\\include\\libxml2") ) { EXTENSION("simplexml", "simplexml.c"); AC_DEFINE("HAVE_SIMPLEXML", 1, "Define to 1 if the PHP extension 'simplexml' is available."); diff --git a/ext/snmp/config.w32 b/ext/snmp/config.w32 index a2facb6946d6..0e3887c0de68 100644 --- a/ext/snmp/config.w32 +++ b/ext/snmp/config.w32 @@ -3,7 +3,7 @@ ARG_WITH("snmp", "SNMP support", "no"); if (PHP_SNMP != "no") { - if (CHECK_HEADER_ADD_INCLUDE("snmp.h", "CFLAGS_SNMP", PHP_PHP_BUILD + "\\include\\net-snmp;" + PHP_SNMP) && + if (CHECK_HEADER("snmp.h", "CFLAGS_SNMP", PHP_PHP_BUILD + "\\include\\net-snmp;" + PHP_SNMP) && SETUP_OPENSSL("snmp", PHP_SNMP) >= 2) { if (CHECK_LIB("netsnmp.lib", "snmp", PHP_SNMP)) { EXTENSION('snmp', 'snmp.c'); diff --git a/ext/soap/config.w32 b/ext/soap/config.w32 index 583f6a2b2e0d..7cecb8e8afed 100644 --- a/ext/soap/config.w32 +++ b/ext/soap/config.w32 @@ -5,8 +5,8 @@ ARG_ENABLE("soap", "SOAP support", "no"); if (PHP_SOAP != "no") { if (PHP_LIBXML == "yes" && ADD_EXTENSION_DEP('soap', 'libxml') && - CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_SOAP", PHP_PHP_BUILD + "\\include\\libxml2") && - CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_SOAP", PHP_PHP_BUILD + "\\include\\libxml2") + CHECK_HEADER("libxml/parser.h", "CFLAGS_SOAP", PHP_PHP_BUILD + "\\include\\libxml2") && + CHECK_HEADER("libxml/tree.h", "CFLAGS_SOAP", PHP_PHP_BUILD + "\\include\\libxml2") ) { EXTENSION('soap', 'soap.c php_encoding.c php_http.c php_packet_soap.c php_schema.c php_sdl.c php_xml.c', null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE('HAVE_SOAP', 1, "Define to 1 if the PHP extension 'soap' is available."); diff --git a/ext/sodium/config.w32 b/ext/sodium/config.w32 index bde640629460..19c548898ab9 100644 --- a/ext/sodium/config.w32 +++ b/ext/sodium/config.w32 @@ -3,7 +3,7 @@ ARG_WITH("sodium", "for libsodium support", "no"); if (PHP_SODIUM != "no") { - if (CHECK_LIB("libsodium.lib", "sodium", PHP_SODIUM) && CHECK_HEADER_ADD_INCLUDE("sodium.h", "CFLAGS_SODIUM")) { + if (CHECK_LIB("libsodium.lib", "sodium", PHP_SODIUM) && CHECK_HEADER("sodium.h", "CFLAGS_SODIUM")) { EXTENSION("sodium", "libsodium.c sodium_pwhash.c"); AC_DEFINE('HAVE_LIBSODIUMLIB', 1 , "Define to 1 if the PHP extension 'sodium' is available."); PHP_INSTALL_HEADERS("ext/sodium", "php_libsodium.h"); diff --git a/ext/standard/config.w32 b/ext/standard/config.w32 index c7c14b8705ca..bb88e0931d24 100644 --- a/ext/standard/config.w32 +++ b/ext/standard/config.w32 @@ -4,7 +4,7 @@ ARG_WITH("password-argon2", "Argon2 support", "no"); if (PHP_PASSWORD_ARGON2 != "no") { if (CHECK_LIB("argon2_a.lib;argon2.lib", null, PHP_PASSWORD_ARGON2) - && CHECK_HEADER_ADD_INCLUDE("argon2.h", "CFLAGS")) { + && CHECK_HEADER("argon2.h", "CFLAGS")) { if (!CHECK_FUNC_IN_HEADER("argon2.h", "argon2id_hash_raw", PHP_PHP_BUILD + "\\include", "CFLAGS")) { ERROR("Please verify that Argon2 header and libraries >= 20161029 are installed"); } @@ -19,7 +19,7 @@ ARG_WITH("config-file-scan-dir", "Dir to check for additional php ini files", "" AC_DEFINE("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR); AC_DEFINE("PHP_USE_PHP_CRYPT_R", 1, "Define to 1 if PHP uses its own crypt_r, and to 0 if using the external crypt library."); -CHECK_HEADER_ADD_INCLUDE("timelib_config.h", "CFLAGS_STANDARD", "ext/date/lib"); +CHECK_HEADER("timelib_config.h", "CFLAGS_STANDARD", "ext/date/lib"); ADD_FLAG("LIBS_STANDARD", "iphlpapi.lib"); diff --git a/ext/tidy/config.w32 b/ext/tidy/config.w32 index 1b2436ac9dfa..8cbb5b9e681c 100644 --- a/ext/tidy/config.w32 +++ b/ext/tidy/config.w32 @@ -7,12 +7,12 @@ if (PHP_TIDY != "no") { if ((CHECK_LIB("libtidy_a.lib;tidy_a.lib", "tidy", PHP_TIDY) && (tidy_static = true) || CHECK_LIB("libtidy.lib;tidy.lib", "tidy", PHP_TIDY)) && ( - CHECK_HEADER_ADD_INCLUDE("tidy.h", "CFLAGS_TIDY") || - CHECK_HEADER_ADD_INCLUDE("tidy/tidy.h", "CFLAGS_TIDY", null, null, true) || - CHECK_HEADER_ADD_INCLUDE("libtidy/tidy.h", "CFLAGS_TIDY", null, null, true) + CHECK_HEADER("tidy.h", "CFLAGS_TIDY") || + CHECK_HEADER("tidy/tidy.h", "CFLAGS_TIDY", null, null, true) || + CHECK_HEADER("libtidy/tidy.h", "CFLAGS_TIDY", null, null, true) )) { - if (CHECK_HEADER_ADD_INCLUDE("tidybuffio.h", "CFLAGS_TIDY")) { + if (CHECK_HEADER("tidybuffio.h", "CFLAGS_TIDY")) { AC_DEFINE('HAVE_TIDYBUFFIO_H', 1, 'Define to 1 if you have the header file.'); } diff --git a/ext/xml/config.w32 b/ext/xml/config.w32 index 00ef36841c38..69fdcd4a0944 100644 --- a/ext/xml/config.w32 +++ b/ext/xml/config.w32 @@ -5,8 +5,8 @@ ARG_WITH("xml", "XML support", "yes"); if (PHP_XML == "yes") { if (PHP_LIBXML == "yes" && ADD_EXTENSION_DEP('xml', 'libxml') && - CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_XML", PHP_PHP_BUILD + "\\include\\libxml2") && - CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_XML", PHP_PHP_BUILD + "\\include\\libxml2") + CHECK_HEADER("libxml/parser.h", "CFLAGS_XML", PHP_PHP_BUILD + "\\include\\libxml2") && + CHECK_HEADER("libxml/tree.h", "CFLAGS_XML", PHP_PHP_BUILD + "\\include\\libxml2") ) { EXTENSION("xml", "xml.c compat.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("HAVE_XML", 1, "Define to 1 if the PHP extension 'xml' is available."); diff --git a/ext/xmlreader/config.w32 b/ext/xmlreader/config.w32 index d92672d427da..803323931d6b 100644 --- a/ext/xmlreader/config.w32 +++ b/ext/xmlreader/config.w32 @@ -4,8 +4,8 @@ ARG_ENABLE("xmlreader", "XMLReader support", "yes"); if (PHP_XMLREADER == "yes" && PHP_LIBXML == "yes" && - CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_XMLREADER", PHP_PHP_BUILD + "\\include\\libxml2") && - CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_XMLREADER", PHP_PHP_BUILD + "\\include\\libxml2") + CHECK_HEADER("libxml/parser.h", "CFLAGS_XMLREADER", PHP_PHP_BUILD + "\\include\\libxml2") && + CHECK_HEADER("libxml/tree.h", "CFLAGS_XMLREADER", PHP_PHP_BUILD + "\\include\\libxml2") ) { EXTENSION("xmlreader", "php_xmlreader.c"); AC_DEFINE("HAVE_XMLREADER", 1, "Define to 1 if the PHP extension 'xmlreader' is available."); diff --git a/ext/xmlwriter/config.w32 b/ext/xmlwriter/config.w32 index 737e3fcd38c5..35459cdd9c4c 100644 --- a/ext/xmlwriter/config.w32 +++ b/ext/xmlwriter/config.w32 @@ -3,7 +3,7 @@ ARG_ENABLE("xmlwriter", "XMLWriter support", "yes"); if (PHP_XMLWRITER == "yes" && PHP_LIBXML == "yes") { - if (CHECK_HEADER_ADD_INCLUDE('libxml/xmlwriter.h', 'CFLAGS_XMLWRITER', PHP_XMLWRITER + ";" + PHP_PHP_BUILD + "\\include\\libxml2")) { + if (CHECK_HEADER('libxml/xmlwriter.h', 'CFLAGS_XMLWRITER', PHP_XMLWRITER + ";" + PHP_PHP_BUILD + "\\include\\libxml2")) { EXTENSION("xmlwriter", "php_xmlwriter.c"); AC_DEFINE("HAVE_XMLWRITER", 1, "Define to 1 if the PHP extension 'xmlwriter' is available."); if (!PHP_XMLWRITER_SHARED) { diff --git a/ext/xsl/config.w32 b/ext/xsl/config.w32 index 4990c3c5bd07..84d463decb94 100644 --- a/ext/xsl/config.w32 +++ b/ext/xsl/config.w32 @@ -6,7 +6,7 @@ if (PHP_XSL != "no") { if (PHP_DOM == "yes" && PHP_LIBXML == "yes" && ADD_EXTENSION_DEP('xsl', 'libxml') && ADD_EXTENSION_DEP('xsl', 'dom') - && CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_XSL", PHP_PHP_BUILD + "\\include\\libxml2") + && CHECK_HEADER("libxml/tree.h", "CFLAGS_XSL", PHP_PHP_BUILD + "\\include\\libxml2") ) { var ext_xsl_lib_found = false; var ext_exslt_lib_found = false; @@ -25,9 +25,9 @@ if (PHP_XSL != "no") { } } - if (ext_xsl_lib_found && CHECK_HEADER_ADD_INCLUDE("libxslt\\xslt.h", "CFLAGS_XSL")) { + if (ext_xsl_lib_found && CHECK_HEADER("libxslt\\xslt.h", "CFLAGS_XSL")) { if (ext_exslt_lib_found) { - if (CHECK_HEADER_ADD_INCLUDE("libexslt\\exslt.h", "CFLAGS_XSL")) { + if (CHECK_HEADER("libexslt\\exslt.h", "CFLAGS_XSL")) { AC_DEFINE("HAVE_XSL_EXSLT", 1, "Define to 1 if the system has the EXSLT extension library for XSLT."); } } diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index 9b80aefaaad0..3f05d8454c1e 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -3,8 +3,8 @@ ARG_ENABLE("zip", "ZIP support", "yes,shared"); if (PHP_ZIP != "no") { - if (CHECK_HEADER_ADD_INCLUDE("zip.h", "CFLAGS_ZIP", PHP_PHP_BUILD + "\\include;" + PHP_EXTRA_INCLUDES) && - CHECK_HEADER_ADD_INCLUDE("zipconf.h", "CFLAGS_ZIP", PHP_PHP_BUILD + "\\lib\\libzip\\include;" + PHP_EXTRA_LIBS + "\\libzip\\include;" + PHP_ZIP) && + if (CHECK_HEADER("zip.h", "CFLAGS_ZIP", PHP_PHP_BUILD + "\\include;" + PHP_EXTRA_INCLUDES) && + CHECK_HEADER("zipconf.h", "CFLAGS_ZIP", PHP_PHP_BUILD + "\\lib\\libzip\\include;" + PHP_EXTRA_LIBS + "\\libzip\\include;" + PHP_ZIP) && (PHP_ZIP_SHARED && CHECK_LIB("libzip.lib", "zip", PHP_ZIP) || CHECK_LIB("libzip_a.lib", "zip", PHP_ZIP) && CHECK_LIB("libbz2_a.lib", "zip", PHP_ZIP) && CHECK_LIB("zlib_a.lib", "zip", PHP_ZIP) && CHECK_LIB("liblzma_a.lib", "zip", PHP_ZIP)) ) { diff --git a/ext/zlib/config.w32 b/ext/zlib/config.w32 index 63ca949813ce..520ab11cd84d 100644 --- a/ext/zlib/config.w32 +++ b/ext/zlib/config.w32 @@ -4,7 +4,7 @@ ARG_ENABLE("zlib", "ZLIB support", "yes"); if (PHP_ZLIB == "yes") { if (CHECK_LIB("zlib_a.lib;zlib.lib", "zlib", PHP_ZLIB) && - CHECK_HEADER_ADD_INCLUDE("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects)) { + CHECK_HEADER("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects)) { EXTENSION("zlib", "zlib.c zlib_fopen_wrapper.c zlib_filter.c", PHP_ZLIB_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("HAVE_ZLIB", 1, "Define to 1 if the PHP extension 'zlib' is available."); diff --git a/sapi/apache2handler/config.w32 b/sapi/apache2handler/config.w32 index 710d6438f53d..2ce4511666f1 100644 --- a/sapi/apache2handler/config.w32 +++ b/sapi/apache2handler/config.w32 @@ -10,7 +10,7 @@ if(PHP_APACHE2_4HANDLER != "no" && PHP_APACHE2HANDLER == "no") { if (PHP_APACHE2HANDLER != "no") { if (PHP_ZTS == "no") { WARNING("Apache module requires an --enable-zts build of PHP on windows"); - } else if (CHECK_HEADER_ADD_INCLUDE("httpd.h", "CFLAGS_APACHE2HANDLER", PHP_PHP_BUILD + "\\include\\apache2_4") && + } else if (CHECK_HEADER("httpd.h", "CFLAGS_APACHE2HANDLER", PHP_PHP_BUILD + "\\include\\apache2_4") && CHECK_LIB("libhttpd.lib", "apache2handler", PHP_PHP_BUILD + "\\lib\\apache2_4") && CHECK_LIB("libapr-1.lib", "apache2handler", PHP_PHP_BUILD + "\\lib\\apache2_4") && CHECK_LIB("libaprutil-1.lib", "apache2handler", PHP_PHP_BUILD + "\\lib\\apache2_4") diff --git a/sapi/cli/config.w32 b/sapi/cli/config.w32 index 093bf03a51d3..5dff4054b69d 100644 --- a/sapi/cli/config.w32 +++ b/sapi/cli/config.w32 @@ -12,7 +12,7 @@ if (PHP_CLI == "yes") { PHP_INSTALL_HEADERS("sapi/cli", "cli.h"); if (CHECK_LIB("edit_a.lib;edit.lib", "cli", PHP_CLI) && - CHECK_HEADER_ADD_INCLUDE("editline/readline.h", "CFLAGS_CLI")) { + CHECK_HEADER("editline/readline.h", "CFLAGS_CLI")) { ADD_FLAG("CFLAGS_CLI", "/D HAVE_LIBEDIT"); } } diff --git a/win32/build/confutils.js b/win32/build/confutils.js index e516fd410bcd..587d89c27f47 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -996,6 +996,55 @@ function GREP_HEADER(header_name, regex, path_to_check) return false; } +/** + * Checks if specified header exists and adds its include path to C flags. + */ +function CHECK_HEADER(header_name, flag_name, path_to_check, use_env, add_dir_part) +{ + var dir_part_to_add = ""; + + if (use_env == null) { + use_env = true; + } + + // if true, add the dir part of the header_name to the include path + if (add_dir_part == null) { + add_dir_part = false; + } else if (add_dir_part) { + var basename = FSO.GetFileName(header_name); + dir_part_to_add = "\\" + header_name.substr(0, header_name.length - basename.length - 1); + } + + if (path_to_check == null) { + path_to_check = php_usual_include_suspects; + } else { + path_to_check += ";" + php_usual_include_suspects; + } + + var p = search_paths(header_name, path_to_check, use_env ? "INCLUDE" : null); + + if (typeof(p) == "string") { + ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); + } else if (p == false) { + /* Not found in the defaults or the explicit paths, + * so check the general extra includes; if we find + * it here, no need to add another /I for it as we + * already have it covered, unless we are adding + * the dir part.... */ + p = search_paths(header_name, PHP_EXTRA_INCLUDES, null); + if (typeof(p) == "string" && add_dir_part) { + ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); + } + } + + return p; +} + +/** + * Obsolete. Checks if specified header exists, adds its include path to C flags + * and defines the 'HAVE_' C preprocessor macro. In new code, use + * CHECK_HEADER() instead, and define the 'HAVE_' macro manually as needed. + */ function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env, add_dir_part, add_to_flag_only) { var dir_part_to_add = ""; @@ -3657,7 +3706,7 @@ function SETUP_ZLIB_LIB(target, path_to_check) return (PHP_ZLIB != "no" && !PHP_ZLIB_SHARED) || CHECK_LIB("zlib_a.lib;zlib.lib", target, path_to_check); } -function SETUP_OPENSSL(target, path_to_check, common_name, use_env, add_dir_part, add_to_flag_only) +function SETUP_OPENSSL(target, path_to_check, common_name, use_env, add_dir_part) { var ret = 0; var cflags_var = "CFLAGS_" + target.toUpperCase(); @@ -3665,7 +3714,7 @@ function SETUP_OPENSSL(target, path_to_check, common_name, use_env, add_dir_part if (CHECK_LIB("libcrypto.lib", target, path_to_check) && CHECK_LIB("libssl.lib", target, path_to_check) && CHECK_LIB("crypt32.lib", target, path_to_check, common_name) && - CHECK_HEADER_ADD_INCLUDE("openssl/ssl.h", cflags_var, path_to_check, use_env, add_dir_part, add_to_flag_only)) { + CHECK_HEADER("openssl/ssl.h", cflags_var, path_to_check, use_env, add_dir_part)) { /* Openssl 1.1.x or later */ return 2; } @@ -3678,8 +3727,8 @@ function SETUP_SQLITE3(target, path_to_check, shared) { var libs = (shared ? "libsqlite3.lib;libsqlite3_a.lib" : "libsqlite3_a.lib;libsqlite3.lib"); return CHECK_LIB(libs, target, path_to_check) && - CHECK_HEADER_ADD_INCLUDE("sqlite3.h", cflags_var) && - CHECK_HEADER_ADD_INCLUDE("sqlite3ext.h", cflags_var); + CHECK_HEADER("sqlite3.h", cflags_var) && + CHECK_HEADER("sqlite3ext.h", cflags_var); } function check_binary_tools_sdk() From 84b0a73685d1218abe21764fdabb54d1a0b42b79 Mon Sep 17 00:00:00 2001 From: Nora Dossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 3 Mar 2026 22:29:07 +0100 Subject: [PATCH 2/4] Fix GH-13204: glob() fails if square bracket is in current directory (#19647) The problem is not limited to square brackets, but to every meta character. The solution is to override the glob functions for handling paths with the VCWD ones in PHP. If that is not available, use the old but limited workaround. --- NEWS | 2 + ext/standard/dir.c | 56 ++++++++++++++++--- ext/standard/tests/file/gh13204.phpt | 12 ++++ .../tests/file/gh13204[brackets]/empty.txt | 0 4 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 ext/standard/tests/file/gh13204.phpt create mode 100644 ext/standard/tests/file/gh13204[brackets]/empty.txt diff --git a/NEWS b/NEWS index cf36b1bad7c7..75332b89a1ef 100644 --- a/NEWS +++ b/NEWS @@ -123,6 +123,8 @@ PHP NEWS defaulted to 0. (Jorg Sowa) . Fixed bug GH-21058 (error_log() crashes with message_type 3 and null destination). (David Carlier) + . Fixed bug GH-13204 (glob() fails if square bracket is in current directory). + (ndossche) - Streams: . Added so_keepalive, tcp_keepidle, tcp_keepintvl and tcp_keepcnt stream diff --git a/ext/standard/dir.c b/ext/standard/dir.c index 7c1f8efe6887..730ef6154907 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -400,13 +400,34 @@ PHP_FUNCTION(getcwd) /* }}} */ /* {{{ Find pathnames matching a pattern */ +#if defined(ZTS) && defined(PHP_GLOB_ALTDIRFUNC) +static void *php_glob_opendir_wrapper(const char *path) +{ + return VCWD_OPENDIR(path); +} + +static void php_glob_closedir_wrapper(void *dir) +{ + (void) closedir(dir); +} + +static int php_glob_lstat_wrapper(const char *buf, zend_stat_t *sb) +{ + return VCWD_LSTAT(buf, sb); +} + +static int php_glob_stat_wrapper(const char *buf, zend_stat_t *sb) +{ + return VCWD_STAT(buf, sb); +} +#endif + PHP_FUNCTION(glob) { size_t cwd_skip = 0; -#ifdef ZTS +#if defined(ZTS) && !defined(PHP_GLOB_ALTDIRFUNC) char cwd[MAXPATHLEN]; char work_pattern[MAXPATHLEN]; - char *result; #endif char *pattern = NULL; size_t pattern_len; @@ -433,28 +454,45 @@ PHP_FUNCTION(glob) RETURN_FALSE; } + memset(&globbuf, 0, sizeof(globbuf)); + + int passed_glob_flags = flags & PHP_GLOB_FLAGMASK; + #ifdef ZTS if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) { - result = VCWD_GETCWD(cwd, MAXPATHLEN); + /* System glob uses the current work directory which is not thread safe. + * The first fix is to override the functions used to open/read/... paths + * with the VCWD ones used in PHP. + * If that functionality is unavailable for whatever reason, fall back + * to prepending the current working directory to the passed path. + * However, that comes with limitations regarding meta characters + * that is not solvable in general (GH-13204). */ +# ifdef PHP_GLOB_ALTDIRFUNC + globbuf.gl_opendir = php_glob_opendir_wrapper; + globbuf.gl_readdir = (struct dirent *(*)(void *)) readdir; + globbuf.gl_closedir = php_glob_closedir_wrapper; + globbuf.gl_lstat = php_glob_lstat_wrapper; + globbuf.gl_stat = php_glob_stat_wrapper; + passed_glob_flags |= PHP_GLOB_ALTDIRFUNC; +# else + char *result = VCWD_GETCWD(cwd, MAXPATHLEN); if (!result) { cwd[0] = '\0'; } -#ifdef PHP_WIN32 +# ifdef PHP_WIN32 if (IS_SLASH(*pattern)) { cwd[2] = '\0'; } -#endif +# endif cwd_skip = strlen(cwd)+1; snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern); pattern = work_pattern; +# endif } #endif - - memset(&globbuf, 0, sizeof(globbuf)); - globbuf.gl_offs = 0; - if (0 != (ret = php_glob(pattern, flags & PHP_GLOB_FLAGMASK, NULL, &globbuf))) { + if (0 != (ret = php_glob(pattern, passed_glob_flags, NULL, &globbuf))) { #ifdef PHP_GLOB_NOMATCH if (PHP_GLOB_NOMATCH == ret) { /* Some glob implementation simply return no data if no matches diff --git a/ext/standard/tests/file/gh13204.phpt b/ext/standard/tests/file/gh13204.phpt new file mode 100644 index 000000000000..1af66539195a --- /dev/null +++ b/ext/standard/tests/file/gh13204.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-13204 (glob() fails if square bracket is in current directory) +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(11) "./empty.txt" +} diff --git a/ext/standard/tests/file/gh13204[brackets]/empty.txt b/ext/standard/tests/file/gh13204[brackets]/empty.txt new file mode 100644 index 000000000000..e69de29bb2d1 From 7324cd7f210d255e86fef478a7fad89f0797cd02 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 3 Mar 2026 16:53:42 +0100 Subject: [PATCH 3/4] Fix enabling of opcache in benchmark job in older branches 8.4 still needs a zend_extension=opcache.so in the ini file. Closes GH-21332 --- .github/matrix.php | 2 +- .github/workflows/test-suite.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/matrix.php b/.github/matrix.php index 9164dd4b3c00..64bb60519de6 100644 --- a/.github/matrix.php +++ b/.github/matrix.php @@ -73,7 +73,7 @@ function select_jobs($repository, $trigger, $nightly, $labels, $php_version, $re && ($all_jobs || !$no_jobs || $test_benchmarking) // push trigger is restricted to official repository. && ($repository === 'php/php-src' || $trigger === 'pull_request')) { - $jobs['BENCHMARKING'] = true; + $jobs['BENCHMARKING']['config']['integrated_opcache'] = version_compare($php_version, '8.5', '>='); } if ($all_jobs || $test_community) { $jobs['COMMUNITY']['matrix'] = version_compare($php_version, '8.4', '>=') diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 0fd95f67f9c4..9f5496d1d69c 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -1036,6 +1036,7 @@ jobs: sudo mkdir -p /etc/php.d sudo chmod 777 /etc/php.d echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini + ${{ !fromJson(inputs.branch).jobs.BENCHMARKING.config.integrated_opcache && 'echo zend_extension=opcache.so >> /etc/php.d/opcache.ini' || '' }} echo opcache.enable=1 >> /etc/php.d/opcache.ini echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini - name: Setup From 7a1c2612c01d9bd4d0c2d128fb5b2bf8f0a2e671 Mon Sep 17 00:00:00 2001 From: tekimen Date: Wed, 4 Mar 2026 09:47:26 +0900 Subject: [PATCH 4/4] [RFC] Add grapheme_strrev function (#20949) * [RFC] Add grapheme_strrev function Add more tests Arabic for grapheme_strrev function. --- NEWS | 1 + UPGRADING | 4 ++ ext/intl/grapheme/grapheme_string.cpp | 59 ++++++++++++++++++++++++++ ext/intl/php_intl.stub.php | 2 + ext/intl/php_intl_arginfo.h | 8 +++- ext/intl/tests/grapheme_strrev.phpt | Bin 0 -> 866 bytes 6 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 ext/intl/tests/grapheme_strrev.phpt diff --git a/NEWS b/NEWS index 75332b89a1ef..4e1196fb0946 100644 --- a/NEWS +++ b/NEWS @@ -37,6 +37,7 @@ PHP NEWS (BogdanUngureanu) . Fixed bug GH-20426 (Spoofchecker::setRestrictionLevel() error message suggests missing constants). (DanielEScherzer) + . Added grapheme_strrev (Yuya Hamada) - JSON: . Enriched JSON last error / exception message with error location. diff --git a/UPGRADING b/UPGRADING index 7e47d0ba4817..454a7b900f35 100644 --- a/UPGRADING +++ b/UPGRADING @@ -137,6 +137,10 @@ PHP 8.6 UPGRADE NOTES . Added ReflectionProperty::isReadable() and ReflectionProperty::isWritable(). RFC: https://wiki.php.net/rfc/isreadable-iswriteable +- Intl: + . `grapheme_strrev()` returns strrev for grapheme cluster unit. + RFC: https://wiki.php.net/rfc/grapheme_strrev + - Standard: . `clamp()` returns the given value if in range, else return the nearest bound. diff --git a/ext/intl/grapheme/grapheme_string.cpp b/ext/intl/grapheme/grapheme_string.cpp index 6dd5a002a65b..36c0cc0f732c 100644 --- a/ext/intl/grapheme/grapheme_string.cpp +++ b/ext/intl/grapheme/grapheme_string.cpp @@ -1135,4 +1135,63 @@ U_CFUNC PHP_FUNCTION(grapheme_levenshtein) efree(ustring1); } +U_CFUNC PHP_FUNCTION(grapheme_strrev) +{ + zend_string *string; + UText *ut = nullptr; + UErrorCode ustatus = U_ZERO_ERROR; + UBreakIterator *bi; + char *pstr, *end, *p; + zend_string *ret; + int32_t pos = 0, current = 0, end_len = 0; + unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(string) + ZEND_PARSE_PARAMETERS_END(); + + if (ZSTR_LEN(string) == 0) { + RETURN_EMPTY_STRING(); + } + + pstr = ZSTR_VAL(string); + ut = utext_openUTF8(ut, pstr, ZSTR_LEN(string), &ustatus); + + if (U_FAILURE(ustatus)) { + intl_error_set_code(nullptr, ustatus); + intl_error_set_custom_msg(nullptr, "Error opening UTF-8 text"); + + RETVAL_FALSE; + goto close; + } + + bi = nullptr; + ustatus = U_ZERO_ERROR; + + bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &ustatus ); + ret = zend_string_alloc(ZSTR_LEN(string), 0); + p = ZSTR_VAL(ret); + + ubrk_setUText(bi, ut, &ustatus); + pos = ubrk_last(bi); + if (pos == UBRK_DONE) { + goto ubrk_end; + } + + current = ZSTR_LEN(string); + for (end = pstr; pos != UBRK_DONE; ) { + pos = ubrk_previous(bi); + end_len = current - pos; + for (int32_t j = 0; j < end_len; j++) { + *p++ = *(pstr + pos + j); + } + current = pos; + } +ubrk_end: + RETVAL_NEW_STR(ret); + ubrk_close(bi); +close: + utext_close(ut); +} + /* }}} */ diff --git a/ext/intl/php_intl.stub.php b/ext/intl/php_intl.stub.php index 9a8f036865cd..4bcb8587f786 100644 --- a/ext/intl/php_intl.stub.php +++ b/ext/intl/php_intl.stub.php @@ -445,6 +445,8 @@ function grapheme_str_split(string $string, int $length = 1): array|false {} function grapheme_levenshtein(string $string1, string $string2, int $insertion_cost = 1, int $replacement_cost = 1, int $deletion_cost = 1, string $locale = ""): int|false {} +function grapheme_strrev(string $string): string|false {} + /** @param int $next */ function grapheme_extract(string $haystack, int $size, int $type = GRAPHEME_EXTR_COUNT, int $offset = 0, &$next = null): string|false {} diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h index e00e51420d46..81160349980c 100644 --- a/ext/intl/php_intl_arginfo.h +++ b/ext/intl/php_intl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit php_intl.stub.php instead. - * Stub hash: d9e331c3a1ae46f8eae07ef0d39cb9990e74a0d1 */ + * Stub hash: c52fd0def2530be628beedbbcdcfecdcb07449a8 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intlcal_create_instance, 0, 0, IntlCalendar, 1) ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") @@ -501,6 +501,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_grapheme_levenshtein, 0, 2, MAY_ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_grapheme_strrev, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_grapheme_extract, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, haystack, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, size, IS_LONG, 0) @@ -922,6 +926,7 @@ ZEND_FUNCTION(grapheme_strstr); ZEND_FUNCTION(grapheme_stristr); ZEND_FUNCTION(grapheme_str_split); ZEND_FUNCTION(grapheme_levenshtein); +ZEND_FUNCTION(grapheme_strrev); ZEND_FUNCTION(grapheme_extract); ZEND_FUNCTION(idn_to_ascii); ZEND_FUNCTION(idn_to_utf8); @@ -1113,6 +1118,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(grapheme_stristr, arginfo_grapheme_stristr) ZEND_FE(grapheme_str_split, arginfo_grapheme_str_split) ZEND_FE(grapheme_levenshtein, arginfo_grapheme_levenshtein) + ZEND_FE(grapheme_strrev, arginfo_grapheme_strrev) ZEND_FE(grapheme_extract, arginfo_grapheme_extract) ZEND_FE(idn_to_ascii, arginfo_idn_to_ascii) ZEND_FE(idn_to_utf8, arginfo_idn_to_utf8) diff --git a/ext/intl/tests/grapheme_strrev.phpt b/ext/intl/tests/grapheme_strrev.phpt new file mode 100644 index 0000000000000000000000000000000000000000..dff84fbba8e97cdee5af5c0c3ce346df018afd14 GIT binary patch literal 866 zcma))F>As=6vsQ?r+5Ux1dO<+)}f>z6kE`tP>Wo`*$6R)%cWFAkb-oOF5LvdF)kh4 zN&oh2N>~~ zhg4O+Y3Yq-{i@OA-93ldT)U`W>byFwxt5DEhtE2F+;e0FjS%psK#3<}p$f&Kh7v7~ zpL{;O3I~7vYP>*2{tVm3dszxmwbT&$-Mr|tXu_Y#|BK>_ZXqTBOv9Zf{Q8c!zfO>t=x@4(z1DF zqvtWZl$5Z%Gbm67sqLh$aqOjp`P9kCX=scPF|7e)Y&BFni?`xhKi}V