php-wasm

repository·master·Indexed 23 days ago

https://github.com/seanmorris/php-wasm

Provides PHP runtimes compiled to WebAssembly, enabling PHP to run in web environments without a traditional server-side setup. It supports various entry points such as CGI and CLI, and offers extensions including php-wasm-dom and php-wasm-libxml. The project includes php-wasm-builder (v0.1.0) for building php-wasm, php-cgi-wasm, and their dependencies.

Tokens
43.9K
Snippets
128
Records
285
Agent score
79%

What's inside php-wasm

  1. Overview of php-wasm packages

    master

    The php-wasm project provides PHP runtimes compiled to WebAssembly. The core packages are:

    • php-wasm: The base package.
    • php-cgi-wasm: PHP via the CGI interface.
    • php-cli-wasm: PHP via the Command Line Interface.
    • php-dbg-wasm: PHP with debugging support.
    • php-wasm-builder: A package for building PHP WASM assets.

    Supported runtime-loadable libraries include:

    • gd, iconv, intl, libxml, xml, dom, simplexml, yaml, zip, mbstring, openssl, phar, sqlite, and zlib.

    Additionally, specialized PDO drivers are maintained as separate packages:

    • pdo_cfd1
    • pdo_pglite
    • vrzno
  2. What is the waitline extension?

    master
    waitline is a line-reader extension used by php-wasm to enable interactive CLI and debugger input in WASM-hosted environments. It replaces standard blocking STDIN reads with an asynchronous, JavaScript-backed line source. This mechanism is what allows php -a (interactive shell) sessions and phpdbg prompts to function correctly within a browser or other WASM runtimes.
  3. Use the vrzno PHP-to-JavaScript bridge

    master

    The vrzno extension is a bridge that allows PHP code running in WebAssembly to interact with the JavaScript environment (globalThis). It enables PHP to access JavaScript objects, classes, promises, callbacks, and values.

    Note: The standard php-wasm runtime includes vrzno by default, so you typically do not need to import this package directly unless you are performing custom builds.

    import { PhpNode } from 'php-wasm/PhpNode.mjs';
    
    const php = new PhpNode({
      version: '8.4',
      answer: 42,
    });
    
    await php.run(`<?php
      $global = new Vrzno;
    
      var_dump(vrzno_env('answer'));
      var_dump($global->Date->now() > 0);
    `);
  4. Manually manage PHP extension assets

    master

    Runtime-loadable extension helper JS packages are ESM-only. If you need to manage extension assets manually, you can pass the following options to the constructor:

    • sharedLibs: Shared library assets.
    • dynamicLibs: Dynamic library assets.
    • files: Additional files.
    • locateFile: A function to locate assets.
  5. Manage filesystem transactions and mirroring

    master

    In the web and worker builds, filesystem operations are protected by a lock named php-wasm-fs-lock using navigator.locks.request. This prevents data corruption when multiple tabs or service workers access the filesystem.

    Automatic Transactions

    By default, the entire filesystem is loaded from IDBFS before an operation and saved back to IDBFS when the lock is released. Operations are enqueued asynchronously and batched automatically. You generally do not need to manage mirroring manually.

    Manual Transactions

    To take explicit control of filesystem mirroring, you can disable automatic transactions by passing {autoTransaction: false} to the constructor.

    WARNING: If you disable automatic transactions, you must manually manage the transaction lifecycle. Failure to do so correctly may result in a corrupted filesystem.

    1. Call php.startTransaction() before operations.
    2. Call php.commitTransaction() when finished.
  6. How the PharStreamWrapper works with Interceptors

    master

    The PharStreamWrapper intercepts phar:// stream invocations to prevent insecure deserialization attacks (e.g., hiding Phar files inside images).

    To use it, you must:

    1. Create a Behavior object.
    2. Attach one or more Assertable interceptors to that behavior.
    3. Initialize the Manager with that behavior.
    4. Unregister the native phar stream wrapper and register TYPO3\PharStreamWrapper\PharStreamWrapper in its place.

    Interceptors can act on specific commands, including:

    • COMMAND_DIR_OPENDIR
    • COMMAND_MKDIR
    • COMMAND_RENAME
    • COMMAND_RMDIR
    • COMMAND_STEAM_METADATA
    • COMMAND_STREAM_OPEN
    • COMMAND_UNLINK
    • COMMAND_URL_STAT
    $behavior = new \TYPO3\PharStreamWrapper\Behavior();
    \TYPO3\PharStreamWrapper\Manager::initialize(
        $behavior->withAssertion(new PharExtensionInterceptor())
    );
    
    if (in_array('phar', stream_get_wrappers())) {
        stream_wrapper_unregister('phar');
        stream_wrapper_register('phar', 'TYPO3\\PharStreamWrapper\\PharStreamWrapper');
    }
  7. Access JavaScript from PHP using Vrzno

    master

    The environment provides a Vrzno object (often accessible via $window = new Vrzno;) that acts as a bridge between PHP and the JavaScript runtime. This allows you to:

    • Call JS functions: Use vrzno_eval() to execute arbitrary JavaScript strings.
    • Execute JS functions with arguments: Use vrzno_run('functionName', [args]) to call a specific JavaScript function with a list of arguments.
    • Handle Promises: Use vrzno_new($Promise, callback) to wrap a JavaScript Promise so it can be handled within PHP logic.
    • Import JS Libraries: Use vrzno_import('url') to load external JavaScript modules into the PHP context.
  8. Run PHP code snippets with various configurations

    master

    The php-wasm environment supports running PHP code with specific execution parameters via URL queries. Common patterns include:

    • Hello World: Basic execution.
    • phpinfo(): Inspecting the PHP configuration.
    • Persistent Memory: Using the persist flag to maintain state across executions.
    • Single Expression: Using the single-expression flag to return strings directly.
    • DOM Access: Interacting with the browser DOM from within PHP.
    • Sqlite/PDO: Running database queries using SQLite.
    • JSON: Working with JSON encoding/decoding.
    • Closures: Testing PHP closures and scope.
    • File Access: Iterating through the filesystem.
    • Fetch/Promises: Handling asynchronous operations and JavaScript promises from PHP.