From ca6c7dd26100c39bb0f0204ba72a6cf86e1ffafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3zsa=20Zolt=C3=A1n?= <67325669+rozsazoltan@users.noreply.github.com> Date: Tue, 28 Jul 2026 16:07:05 +0200 Subject: [PATCH] feat(windows): allow forced PHP extensions --- README.md | 24 ++++++++++++++++++++++++ hooks/mise_env.lua | 5 +++++ lib/env.lua | 13 +++++++++++++ lib/windows_php.lua | 13 +++++++++++-- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 482cea7..19bdd65 100644 --- a/README.md +++ b/README.md @@ -507,6 +507,30 @@ The following installation options can be set through `mise config set env._.php | `configure_options` | `PHP_CONFIGURE_OPTIONS` | empty | Replace configure options entirely while preserving the install prefix. | | `pecl_extensions` | `PHP_PECL_EXTENSIONS` | empty | Install PECL extensions after source builds where PECL is available. | | `pie_extensions` | `PHP_PIE_EXTENSIONS` | empty | Install PIE extension packages after source builds where PIE is available. | +| `windows_force_extensions` | `PHP_WINDOWS_FORCE_EXTENSIONS` | empty | Enable listed Windows extensions even when they are disabled by default because they require external native dependencies. | + +### Windows extensions with external dependencies + +Some PHP for Windows packages include extensions that need native dependencies not bundled with PHP. They are disabled by default so PHP installs work without those dependencies. To enable one explicitly, make its dependency available on `PATH` before installation. + +```powershell +# One-time use (Windows / PowerShell) +$env:PHP_WINDOWS_FORCE_EXTENSIONS="oci8_19 pdo_oci"; mise install php@8.3 +``` + +To persist the setting in a project `mise.toml`, use either the mise CLI or the configuration file: + +```powershell +mise config set env._.php.windows_force_extensions "oci8_19 pdo_oci" +``` + +```toml +[env] +_.php = { windows_force_extensions = "oci8_19 pdo_oci" } +``` + +PHP still verifies that forced extensions load successfully. For example, `oci8_19` and `pdo_oci` require Oracle Instant Client to be available on `PATH`. + Static PHP flavor notes: diff --git a/hooks/mise_env.lua b/hooks/mise_env.lua index b3853ee..f1d2c06 100644 --- a/hooks/mise_env.lua +++ b/hooks/mise_env.lua @@ -56,5 +56,10 @@ function PLUGIN:MiseEnv(ctx) set_env(env_vars, "PHP_PIE_EXTENSIONS", pie_extensions) end + local windows_force_extensions = options.get(ctx, "windows_force_extensions") + if windows_force_extensions ~= nil and windows_force_extensions ~= "" and windows_force_extensions ~= false then + set_env(env_vars, "PHP_WINDOWS_FORCE_EXTENSIONS", windows_force_extensions) + end + return env_vars end diff --git a/lib/env.lua b/lib/env.lua index 13dd982..b7cbf64 100644 --- a/lib/env.lua +++ b/lib/env.lua @@ -70,11 +70,23 @@ local function parse_pie_extensions() return extensions end +local function parse_windows_force_extensions() + local val = os.getenv("PHP_WINDOWS_FORCE_EXTENSIONS") + if val == nil or val == "" then return {} end + local extensions = {} + for ext in val:gmatch("[^,%s]+") do + validate_package_token("PHP_WINDOWS_FORCE_EXTENSIONS", ext, false) + table.insert(extensions, ext:lower()) + end + return extensions +end + local VERBOSE = is_verbose() local QUIET = quiet_redirect() local SKIP_DEPS = is_enabled("PHP_SKIP_DEPS") local PECL_EXTENSIONS = parse_pecl_extensions() local PIE_EXTENSIONS = parse_pie_extensions() +local WINDOWS_FORCE_EXTENSIONS = parse_windows_force_extensions() local PREBUILT_STATIC = is_enabled("PHP_PREBUILT_STATIC") local PREBUILT_STATIC_FLAVOR = os.getenv("PHP_PREBUILT_STATIC_FLAVOR") or "" @@ -84,6 +96,7 @@ return { SKIP_DEPS = SKIP_DEPS, PECL_EXTENSIONS = PECL_EXTENSIONS, PIE_EXTENSIONS = PIE_EXTENSIONS, + WINDOWS_FORCE_EXTENSIONS = WINDOWS_FORCE_EXTENSIONS, PREBUILT_STATIC = PREBUILT_STATIC, PREBUILT_STATIC_FLAVOR = PREBUILT_STATIC_FLAVOR, } diff --git a/lib/windows_php.lua b/lib/windows_php.lua index 42f51ab..f15def3 100644 --- a/lib/windows_php.lua +++ b/lib/windows_php.lua @@ -5,6 +5,7 @@ local php_extensions = require("lib/php_extensions") local tools = require("lib/tools") local QUIET = env.QUIET +local WINDOWS_FORCE_EXTENSIONS = env.WINDOWS_FORCE_EXTENSIONS local M = {} @@ -218,6 +219,10 @@ local function configure_php_ini(sdk_path, timezone) pdo_oci = true, snmp = true, } + local forced_extensions = {} + for _, extension in ipairs(WINDOWS_FORCE_EXTENSIONS) do + forced_extensions[extension] = true + end local enabled_extensions = {} local expected_extensions = {} php_extensions.add(expected_extensions, { @@ -233,14 +238,18 @@ local function configure_php_ini(sdk_path, timezone) for _, extension in ipairs(extension_dlls) do local name = extension:lower() - if blacklist[name] then + if blacklist[name] and not forced_extensions[name] then print("Skipping " .. extension .. " - requires external dependencies") elseif set_contains(php_modules, name) then print("Skipping " .. extension .. " - already compiled statically") else enabled_extensions[name] = true php_extensions.add(expected_extensions, name) - print("Enabled " .. extension) + if blacklist[name] then + print("Forcing " .. extension .. " - enabled by PHP_WINDOWS_FORCE_EXTENSIONS") + else + print("Enabled " .. extension) + end end end