Skip to content

Fix native php blueprint#3491

Merged
fredrikekelund merged 48 commits into
trunkfrom
fix-native-php-blueprint
May 19, 2026
Merged

Fix native php blueprint#3491
fredrikekelund merged 48 commits into
trunkfrom
fix-native-php-blueprint

Conversation

@bcotrim
Copy link
Copy Markdown
Contributor

@bcotrim bcotrim commented May 14, 2026

Related issues

  • None.

How AI was used in this PR

Codex was used interactively to debug the native PHP blueprint startup failure, inspect daemon/PHP behavior on Windows, and draft the focused fix. The behavior was manually reproduced before the fix and validated afterward in both CLI and Studio flows.

Proposed Changes

  • Add a temporary native PHP subprocess php.ini for blueprint PHAR execution.
  • Load Studio's bundled Windows PHP extensions in that subprocess config, including pdo_sqlite and sqlite3, so the PHAR can detect the SQLite-backed WordPress install correctly.
  • Generate a temporary CA bundle from Node's trusted root certificates and pass it to PHP via openssl.cafile and curl.cainfo, fixing HTTPS downloads from blueprint steps under native PHP.
  • Allow native PHP subprocess callers to pass scoped environment variables and extra PHP args.
  • Clean up the temporary blueprint php.ini directory after the blueprint run.
  • Add focused tests for the native PHP helper behavior.

Testing Instructions

  • Confirm automated checks pass:
    • npx eslint --fix apps/cli/lib/native-php.ts apps/cli/php-server-child.ts apps/cli/lib/tests/native-php.test.ts
    • npm run typecheck
    • npm test -- apps/cli/lib/tests/native-php.test.ts apps/cli/lib/tests/wordpress-server-manager.test.ts
  • Build the CLI before manual testing:
    • npm run cli:build
  • On Windows, create an empty blueprint file containing {} and verify native PHP site creation succeeds:
    • $env:STUDIO_RUNTIME = "native-php"
    • node apps/cli/dist/cli/main.mjs --path "$env:USERPROFILE\Studio\native-empty-blueprint-test" site create --name "Empty Blueprint" --wp latest --php 8.4 --blueprint "$env:TEMP\empty-blueprint.json" --skip-browser
  • In the Studio desktop app, create a native PHP site from the Quick Start blueprint and verify the site starts successfully.
  • Optional: enable Xdebug for the created native PHP site and confirm the running PHP process loads php_xdebug.dll.

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

@bcotrim bcotrim self-assigned this May 14, 2026
@bcotrim bcotrim changed the base branch from trunk to f26d/load-xdebug May 14, 2026 14:07
@bcotrim bcotrim requested a review from fredrikekelund May 14, 2026 14:08
@wpmobilebot
Copy link
Copy Markdown
Collaborator

wpmobilebot commented May 14, 2026

📊 Performance Test Results

Comparing e8a9402 vs trunk

app-size

Metric trunk e8a9402 Diff Change
App Size (Mac) 1354.95 MB 1355.45 MB +0.49 MB ⚪ 0.0%

site-editor

Metric trunk e8a9402 Diff Change
load 1515 ms 1470 ms 45 ms ⚪ 0.0%

site-startup

Metric trunk e8a9402 Diff Change
siteCreation 8572 ms 8579 ms +7 ms ⚪ 0.0%
siteStartup 4951 ms 4932 ms 19 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

Copy link
Copy Markdown
Contributor

@fredrikekelund fredrikekelund left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the problem, which is great! @bcotrim, you mentioned seeing some trouble with images on this branch, but I can upload and view images on the site fine. Let me know what problems you were experiencing.

Really, the only thing I think we should explore here (although it could be a follow-up PR) is using php.ini for all PHP processes on Windows, not just when running blueprints. This would help with simplicity in the implementation and predictability at runtime.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you patch this file somehow, @bcotrim? php-toolkit has had a new release, so we shouldn't have to commit this file anymore since #3437

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now know you did patch it with the changes from WordPress/php-toolkit#280. I've since also patched it with the changes from WordPress/php-toolkit#281

Comment thread apps/cli/lib/tests/native-php.test.ts Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it doesn't hurt, but I'm a little bit allergic to unit tests that LLMs generate out of habit. I think E2E tests serve us much better for truly testing this functionality (we already have E2E tests that do that)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and removed the test file in e834425

Comment thread apps/cli/lib/native-php.ts Outdated
Comment on lines +154 to +171
// blueprints.phar spawns its own PHP subprocesses while applying a blueprint.
// Those subprocesses inherit PHPRC but not the parent process's `-d` argv, so
// this php.ini carries the bundled extension and CA settings they need.
export async function createNativePhpSubprocessIniDirectory(
phpVersion: NativePhpSupportedVersion
): Promise< string > {
const tempRoot =
process.platform === 'win32' ? fs.realpathSync.native( os.tmpdir() ) : os.tmpdir();
const phpIniDirectory = await fs.promises.mkdtemp( path.join( tempRoot, 'studio-native-php-' ) );
const caBundlePath = getNativePhpCaBundlePath( phpIniDirectory );
await fs.promises.writeFile( caBundlePath, rootCertificates.join( os.EOL ), 'utf8' );
await fs.promises.writeFile(
path.join( phpIniDirectory, 'php.ini' ),
getNativePhpSubprocessIniContents( phpVersion, caBundlePath ),
'utf8'
);
return phpIniDirectory;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The php.ini contents only change with PHP versions. To keep things simple, I think we should explore writing the php.ini file to the PHP executable's directory and using that as the source of truth for the PHP config for all Windows PHP processes. Did you try this already, @bcotrim?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented this in 3f3977c

@fredrikekelund
Copy link
Copy Markdown
Contributor

I implemented my suggestion to always load the php.ini file (that lives next to the binary) and verified that creating a site with a blueprint still works. In fact, I even took it one step further and made it so we create that file on macOS, too. Streamlining the implementation between platforms will make things more predictable.

Base automatically changed from f26d/load-xdebug to trunk May 19, 2026 05:38
// and is fussy about backslashes (which also act as escape characters). Use
// forward slashes everywhere and escape stray double quotes.
function toPhpIniPath( filePath: string ): string {
return filePath.replace( /\\/g, '/' ).replace( /"/g, '\\"' );
@fredrikekelund
Copy link
Copy Markdown
Contributor

The E2E tests aren't passing on Windows, but that's expected. We need to build and upload the new PHP packages to the CDN before it'll work

@fredrikekelund fredrikekelund merged commit 53c1153 into trunk May 19, 2026
8 of 10 checks passed
@fredrikekelund fredrikekelund deleted the fix-native-php-blueprint branch May 19, 2026 07:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants