Skip to content

Browser WASM: file_get_contents() returns 'Permission denied' on files written via php.writeFile() #3433

@CrochetFeve0251

Description

@CrochetFeve0251

Note: We're not PrestaShop contributors, we're building an independent project inspired by WordPress Playground. We're reporting this here because the issue is in @php-wasm/web (your packages), not in PrestaShop itself. Any guidance or workaround would be greatly appreciated!

Description

When using @php-wasm/web in the browser, files written via the JavaScript php.writeFile() API cannot be read back by PHP's file_get_contents() or include(). Both return "Permission denied".

This works correctly with @php-wasm/node (Node.js runtime).

Steps to reproduce

  1. Boot PHP in browser via @php-wasm/web with loadWebRuntime("8.2", { loadAllExtensions: true })
  2. Write a file via JS: php.writeFile("/test.php", new TextEncoder().encode("<?php echo 'hello';"))
  3. Try to read it from PHP:
<?php
echo file_get_contents('/test.php'); // → Warning: Permission denied
include '/test.php'; // → Warning: Permission denied

Expected behavior

file_get_contents() and include() should be able to read files written via php.writeFile(), as they do in the Node.js runtime.

Actual behavior

PHP Warning: file_get_contents(/path/to/file.php): Failed to open stream: Permission denied

The file exists (verified via file_exists()) but cannot be read or included.

Environment

  • @php-wasm/web v0.9.46
  • @php-wasm/universal v0.9.46
  • PHP 8.2 (kitchen-sink build)
  • Chromium (via Playwright) and Chrome
  • macOS (Apple Silicon)

Context

We're building a "PrestaShop Playground", running PrestaShop 8.2 entirely in the browser via WebAssembly, inspired by WordPress Playground. The project uses your @php-wasm/web and @php-wasm/universal packages as its foundation.

We extract ~25,000 PHP files into the WASM virtual filesystem via php.writeFile(). The PrestaShop framework boots successfully (autoloader, database via SQLite, sessions all work), but Smarty template compilation fails because the compiled .php template files cannot be include()'d or read via file_get_contents().

Files written by PHP itself (via file_put_contents() inside php.run()) seem to have the same issue in the browser runtime. Everything works perfectly in the Node.js runtime (@php-wasm/node).

Workaround attempts

  • Using eval('?>' . file_get_contents($path)) instead of include → same Permission denied
  • Changing file permissions with chmod() → no effect
  • Writing to /tmp/ instead of the document root → same issue
  • Using PharData::extractTo() instead of php.writeFile() → same issue
  • Extracting via JavaScript (fflate unzip) + php.writeFile() → same issue

This appears to be a fundamental difference in how MEMFS handles file permissions between the Node.js and browser WASM runtimes.

Request for help

We'd really appreciate any pointers on:

  • Is this a known limitation of the browser WASM runtime?
  • Is there a specific API or configuration we should use to make files writable/readable?
  • How does WordPress Playground handle Smarty-like template compilation (writing + including PHP files at runtime)?

Thank you for building such an amazing project, it's the foundation that makes our PrestaShop Playground possible! 🙏

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions