Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a7ae4d1
chore: update zig and translate-c
happystraw Jul 9, 2026
315dcd3
feat(ini): add generic typed directives and setter APIs
happystraw Jul 9, 2026
f835ede
refactor(Ctx): rename expectArg runtime extension API
happystraw Jul 9, 2026
4c914f1
feat: add bailout-safe Zend runtime APIs
happystraw Jul 9, 2026
359834d
feat(module): auto-register INI entries and classes
happystraw Jul 9, 2026
1b6d926
refactor(build): replace apply with addExtension
happystraw Jul 9, 2026
952f0a1
feat(windows): add MSVC PHP extension support
happystraw Jul 9, 2026
97541ad
feat(tools): add Windows skeleton build support
happystraw Jul 9, 2026
1b79b02
feat(windows): improve php windows setup and msvc overflow compatibility
happystraw Jul 10, 2026
1b463ce
chore(ci): remove pull_request trigger from docs workflow
happystraw Jul 10, 2026
4eaddf5
feat(tools): add arginfo validation and improve Windows patcher
happystraw Jul 12, 2026
ce1766d
feat(zend): add file globals and hash table accessors
happystraw Jul 12, 2026
04ad69f
refactor: clarify call and module helpers
happystraw Jul 12, 2026
b75a9bf
feat(windows): validate SDK inputs and expand MSVC tests
happystraw Jul 12, 2026
4aab380
chore: refine examples and benchmark setup
happystraw Jul 12, 2026
7cc8a27
feat(module): add typed module globals
happystraw Jul 12, 2026
9535c71
fix(tools): support Windows hosts and compute stub hashes
happystraw Jul 13, 2026
42273a3
refactor(ini): rename typed → Typed
happystraw Jul 13, 2026
d291867
refactor(build): remove macos _Nullable macro workaround
happystraw Jul 13, 2026
50bfd9c
refactor: use [:0]const u8 for all zend_string slices
happystraw Jul 13, 2026
c644a57
chore: update zig and translate-c
happystraw Jul 13, 2026
94916d4
refactor(zend): organize bailout APIs
happystraw Jul 13, 2026
30002b3
feat(observer): add Zend observer APIs
happystraw Jul 13, 2026
a45998e
refactor(zval): rename native namespace to raw
happystraw Jul 13, 2026
b80407e
feat(example): redesign my_php_extension showcase
happystraw Jul 13, 2026
2545a0b
fix(observer): resolve symbol issues on Windows MSVC
happystraw Jul 14, 2026
3272859
feat(globals): add typed superglobal accessors
happystraw Jul 14, 2026
94a67f1
test(example): add superglobal coverage
happystraw Jul 14, 2026
ff82cf5
refactor(zval): clarify wrapper ownership APIs
happystraw Jul 14, 2026
a8929c2
fix(example): retain borrowed superglobal values
happystraw Jul 14, 2026
c0b7ba6
chore(examples): regenerate arginfo for PHP 8.2
happystraw Jul 14, 2026
69ea980
chore: update zig and translate-c
happystraw Jul 14, 2026
e0843af
feat(tools): refresh skeleton generator and support anyzig
happystraw Jul 14, 2026
cc1fa2e
chore(examples): align extension setup
happystraw Jul 14, 2026
b35df1d
ci: expand phpz_skel platform coverage
happystraw Jul 14, 2026
4273fdd
fix(windows): import additional Zend data symbols
happystraw Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
414 changes: 414 additions & 0 deletions .github/scripts/setup-php-windows.ps1

Large diffs are not rendered by default.

149 changes: 115 additions & 34 deletions .github/scripts/test-phpz-skel.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,70 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"
PHP_BIN="${PHP_BIN:-$(command -v php)}"
SKEL="$ROOT_DIR/tools/phpz_skel.php"
PHPZ_REF="${PHPZ_REF:-dev}"
EXPECTED_VERSION="0.0.1"
TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/phpz-skel.XXXXXX")"

cleanup() {
rm -rf "$TMP_ROOT"
}
trap cleanup EXIT

fail() {
echo "not ok - $*" >&2
exit 1
}

ZIG_BIN="${ZIG:-zig}"
PHP_CONFIG_BIN="${PHP_CONFIG:-$(command -v php-config || true)}"
command -v "$ZIG_BIN" >/dev/null 2>&1 || fail "zig is required"
PHP_INCLUDE_DIR="${PHP_INCLUDE_DIR:-}"
if [ -z "$PHP_INCLUDE_DIR" ]; then
[ -n "$PHP_CONFIG_BIN" ] || fail "php-config or PHP_INCLUDE_DIR is required"
PHP_INCLUDE_DIR="$("$PHP_CONFIG_BIN" --include-dir)"
fi

ZIG_BUILD_ARGS=()
[ -n "${ZIG_TARGET:-}" ] && ZIG_BUILD_ARGS+=("-Dtarget=$ZIG_TARGET")
[ -n "${LIBC_FILE:-}" ] && ZIG_BUILD_ARGS+=("-Dlibc-file=$LIBC_FILE")
[ -n "${PHP_INCLUDE_DIR:-}" ] && ZIG_BUILD_ARGS+=("-Dphp-include-dir=$PHP_INCLUDE_DIR")
[ -n "${PHP_LIB_DIR:-}" ] && ZIG_BUILD_ARGS+=("-Dphp-lib-dir=$PHP_LIB_DIR")
[ -n "${WINDOWS_ZTS:-}" ] && ZIG_BUILD_ARGS+=("-Dwindows-zts=$WINDOWS_ZTS")

case "$(uname -s)" in
MINGW* | MSYS* | CYGWIN*)
IS_WINDOWS=1
DEFAULT_EXTENSION_FILENAME="php_demo_ext.dll"
;;
*)
IS_WINDOWS=0
DEFAULT_EXTENSION_FILENAME="demo_ext.so"
;;
esac
EXTENSION_FILENAME="${PHPZ_EXTENSION_FILENAME:-$DEFAULT_EXTENSION_FILENAME}"

php_path() {
if [ "$IS_WINDOWS" -eq 1 ] && command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
printf '%s' "$1"
fi
}

SKEL_ARGS=()
while [ "$#" -gt 0 ]; do
case "$1" in
--)
shift
SKEL_ARGS=("$@")
break
;;
*)
echo "unsupported test script argument: $1"
exit 1
;;
esac
done

cleanup() {
rm -rf "$TMP_ROOT"
}
trap cleanup EXIT

note() {
echo "==> $*"
}
Expand Down Expand Up @@ -69,35 +121,51 @@ target_dir() {
run_skel() {
local stdout="$CASE_DIR/stdout"
local stderr="$CASE_DIR/stderr"
if ! env ZIG="$ZIG_BIN" "$PHP_BIN" "$SKEL" "$@" > >(tee "$stdout") 2> >(tee "$stderr" >&2); then
fail "command failed unexpectedly: php tools/phpz_skel.php $*"
if ! env ZIG="$ZIG_BIN" "$PHP_BIN" "$SKEL" "${SKEL_ARGS[@]}" "$@" > >(tee "$stdout") 2> >(tee "$stderr" >&2); then
fail "command failed unexpectedly: php tools/phpz_skel.php ${SKEL_ARGS[*]} $*"
fi
}

run_zig() {
local label="$1"
shift
if ! (cd "$(target_dir)" && "$ZIG_BIN" "$@"); then
fail "$ZIG_BIN $* failed"
if ! (cd "$(target_dir)" && "$ZIG_BIN" "$@" "${ZIG_BUILD_ARGS[@]}"); then
fail "$ZIG_BIN $* ${ZIG_BUILD_ARGS[*]} failed for $label"
fi
}

run_php_ri() {
local label="$1"
local stdout="$CASE_DIR/$label.stdout"
local stderr="$CASE_DIR/$label.stderr"
if ! (cd "$(target_dir)" && "$PHP_BIN" -dextension=modules/demo_ext.so --ri demo_ext \
if ! (cd "$(target_dir)" && "$PHP_BIN" "-dextension=modules/$EXTENSION_FILENAME" --ri demo_ext \
> >(tee "$stdout") 2> >(tee "$stderr" >&2)); then
fail "php --ri demo_ext failed"
fi
assert_contains "$stdout" "demo_ext"
assert_contains "$stdout" "0.1.0"
assert_contains "$stdout" "$EXPECTED_VERSION"
}

ZIG_BIN="${ZIG:-zig}"
PHP_CONFIG_BIN="${PHP_CONFIG:-$(command -v php-config || true)}"
command -v "$ZIG_BIN" >/dev/null 2>&1 || fail "zig is required"
[ -n "$PHP_CONFIG_BIN" ] || fail "php-config is required"
PHP_INCLUDE_DIR="$("$PHP_CONFIG_BIN" --include-dir)"
has_skel_arg() {
local expected="$1"
local arg
for arg in "${SKEL_ARGS[@]}"; do
[ "$arg" = "$expected" ] && return 0
done
return 1
}

assert_platform_template() {
local build_file
build_file="$(target_dir)/build.zig"
if has_skel_arg "--onlyunix"; then
assert_contains "$build_file" "This extension only supports Unix targets"
assert_not_contains "$build_file" "php-lib-dir"
elif has_skel_arg "--onlywindows"; then
assert_contains "$build_file" "This extension only supports Windows targets"
assert_contains "$build_file" "php-lib-dir"
fi
}

note "lint and help"
"$PHP_BIN" -l "$SKEL" >/dev/null
Expand All @@ -109,40 +177,52 @@ note "default + zig build test"
new_case default_build
run_skel \
--ext DemoExt \
--dir "$CASE_DIR/out" \
--dir "$(php_path "$CASE_DIR/out")" \
--phpz "$PHPZ_REF"
assert_file "$(target_dir)/build.zig"
assert_dir "$(target_dir)/tests"
assert_executable "$(target_dir)/run-tests.php"
assert_contains "$(target_dir)/build.zig" 'const ext_name = "demo_ext";'
assert_contains "$(target_dir)/src/root.zig" '.name = "demo_ext",'
if [ "$IS_WINDOWS" -eq 1 ]; then
assert_file "$(target_dir)/run-tests.php"
else
assert_executable "$(target_dir)/run-tests.php"
fi
assert_platform_template
assert_contains "$(target_dir)/build.zig" "const extension_name = @tagName(package.name);"
assert_contains "$(target_dir)/build.zig" 'extension_info.addOption([:0]const u8, "version", extension_version);'
assert_contains "$(target_dir)/src/root.zig" ".name = extension.name,"
assert_contains "$(target_dir)/demo_ext.h" "extern zend_module_entry demo_ext_module_entry;"
assert_contains "$CASE_DIR/stdout" "extension: demo_ext"
run_zig default-build-test build test
run_php_ri default-ri

note "explicit php-config + zig build test"
new_case explicit_php_config
run_skel \
--ext demo_ext \
--dir "$CASE_DIR/out" \
--phpz "$PHPZ_REF" \
--with-php-config "$PHP_CONFIG_BIN"
assert_contains "$CASE_DIR/stderr" "checking php-config... $PHP_CONFIG_BIN"
assert_contains "$(target_dir)/build.zig" "orelse \"$PHP_INCLUDE_DIR\""
assert_not_contains "$(target_dir)/build.zig" "php-config"
run_zig explicit-php-config-build-test build test
run_php_ri explicit-php-config-ri
if [ -n "$PHP_CONFIG_BIN" ]; then
note "explicit php-config + zig build test"
new_case explicit_php_config
run_skel \
--ext demo_ext \
--dir "$(php_path "$CASE_DIR/out")" \
--phpz "$PHPZ_REF" \
--with-php-config "$PHP_CONFIG_BIN"
assert_platform_template
assert_contains "$CASE_DIR/stderr" "checking php-config... $PHP_CONFIG_BIN"
assert_contains "$(target_dir)/build.zig" "orelse \"$PHP_INCLUDE_DIR\""
assert_not_contains "$(target_dir)/build.zig" "php-config"
run_zig explicit-php-config-build-test build test
run_php_ri explicit-php-config-ri
else
note "explicit php-config + zig build test skipped"
fi

note "without run-tests"
new_case without_run_tests
run_skel \
--ext demo_ext \
--dir "$CASE_DIR/out" \
--dir "$(php_path "$CASE_DIR/out")" \
--phpz "$PHPZ_REF" \
--without-run-tests
assert_no_path "$(target_dir)/tests"
assert_no_path "$(target_dir)/run-tests.php"
assert_platform_template
assert_not_contains "$(target_dir)/build.zig" "Run PHPT tests"
assert_not_contains "$(target_dir)/build.zig" "run-tests.php"
assert_not_contains "$(target_dir)/README.md" "zig build test"
Expand All @@ -153,12 +233,13 @@ note "without gen-stub + zig build test"
new_case without_gen_stub
run_skel \
--ext demo_ext \
--dir "$CASE_DIR/out" \
--dir "$(php_path "$CASE_DIR/out")" \
--phpz "$PHPZ_REF" \
--without-gen-stub
assert_no_path "$(target_dir)/build/gen_stub.php"
assert_file "$(target_dir)/demo_ext_arginfo.h"
assert_dir "$(target_dir)/tests"
assert_platform_template
run_zig without-gen-stub-build-test build test
run_php_ri without-gen-stub-ri

Expand Down
7 changes: 0 additions & 7 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ on:
- "build.zig"
- "build.zig.zon"
- ".github/workflows/docs.yml"
pull_request:
branches: ["dev"]
paths:
- "src/**"
- "build.zig"
- "build.zig.zon"
- ".github/workflows/docs.yml"
workflow_dispatch:

permissions:
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/test-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,17 @@ jobs:
PHP_INCLUDE_DIR=$(php-config --include-dir)
zig build test-examples -Dphp-include-dir="$PHP_INCLUDE_DIR"
- name: Run example tests (ReleaseSafe)
if: ${{ matrix.debug == false }}
run: |
PHP_INCLUDE_DIR=$(php-config --include-dir)
zig build test-examples -Dphp-include-dir="$PHP_INCLUDE_DIR" -Doptimize=ReleaseSafe
- name: Run example tests (ReleaseFast)
if: ${{ matrix.debug == false }}
run: |
PHP_INCLUDE_DIR=$(php-config --include-dir)
zig build test-examples -Dphp-include-dir="$PHP_INCLUDE_DIR" -Doptimize=ReleaseFast
- name: Run example tests (ReleaseSmall)
if: ${{ matrix.debug == false }}
run: |
PHP_INCLUDE_DIR=$(php-config --include-dir)
zig build test-examples -Dphp-include-dir="$PHP_INCLUDE_DIR" -Doptimize=ReleaseSmall
7 changes: 7 additions & 0 deletions .github/workflows/test-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,17 @@ jobs:
PHP_INCLUDE_DIR=$(php-config --include-dir)
zig build test-examples -Dphp-include-dir="$PHP_INCLUDE_DIR"
- name: Run example tests (ReleaseSafe)
if: ${{ matrix.debug == false }}
run: |
PHP_INCLUDE_DIR=$(php-config --include-dir)
zig build test-examples -Dphp-include-dir="$PHP_INCLUDE_DIR" -Doptimize=ReleaseSafe
- name: Run example tests (ReleaseFast)
if: ${{ matrix.debug == false }}
run: |
PHP_INCLUDE_DIR=$(php-config --include-dir)
zig build test-examples -Dphp-include-dir="$PHP_INCLUDE_DIR" -Doptimize=ReleaseFast
- name: Run example tests (ReleaseSmall)
if: ${{ matrix.debug == false }}
run: |
PHP_INCLUDE_DIR=$(php-config --include-dir)
zig build test-examples -Dphp-include-dir="$PHP_INCLUDE_DIR" -Doptimize=ReleaseSmall
44 changes: 42 additions & 2 deletions .github/workflows/test-phpz-skel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ on:
paths:
- "tools/phpz_skel.php"
- ".github/scripts/test-phpz-skel.sh"
- ".github/scripts/setup-php-windows.ps1"
- ".github/workflows/test-phpz-skel.yml"
pull_request:
branches: ["dev"]
paths:
- "tools/phpz_skel.php"
- ".github/scripts/test-phpz-skel.sh"
- ".github/scripts/setup-php-windows.ps1"
- ".github/workflows/test-phpz-skel.yml"
workflow_dispatch:

jobs:
test:
name: test (${{ matrix.os }}, PHP 8.2)
unix:
name: test (${{ matrix.os }}, php 8.2)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand All @@ -38,3 +40,41 @@ jobs:
env:
PHPZ_REF: ${{ github.head_ref || github.ref_name || 'dev' }}
run: bash .github/scripts/test-phpz-skel.sh
- name: Run phpz_skel tests (--onlyunix)
shell: bash
env:
PHPZ_REF: ${{ github.head_ref || github.ref_name || 'dev' }}
run: bash .github/scripts/test-phpz-skel.sh -- --onlyunix

windows:
name: test (windows-latest, php 8.2)
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: mlugg/setup-zig@v2
- name: Install pkg-config
shell: pwsh
run: |
choco install pkgconfiglite --no-progress -y
where.exe pkg-config
- name: Setup PHP runtime and development files
shell: pwsh
run: |
.\.github\scripts\setup-php-windows.ps1 `
-PhpVersion "8.2" `
-Arch "x64" `
-ThreadSafety "nts" `
-Destination (Join-Path $env:RUNNER_TEMP "php-sdk")
- name: Run phpz_skel tests
shell: bash
env:
PHPZ_REF: ${{ github.head_ref || github.ref_name || 'dev' }}
ZIG_TARGET: native-native-msvc
run: bash .github/scripts/test-phpz-skel.sh
- name: Run phpz_skel tests (--onlywindows)
shell: bash
env:
PHPZ_REF: ${{ github.head_ref || github.ref_name || 'dev' }}
ZIG_TARGET: native-native-msvc
run: bash .github/scripts/test-phpz-skel.sh -- --onlywindows
Loading
Loading