Skip to content

Migration Guide ​

Migrating a traditional stateless PHP application to Nexphant's persistent runtime requires shifting from a "run-and-die" mindset to a persistent state model.

1. Eliminate Global State ​

Global variables ($GLOBALS, static fields on classes) persist across requests in Nexphant. If you store request-specific information in a static property, it will leak to subsequent requests.

Before ​

php
class UserContext
{
    public static ?User $currentUser = null;
}

// In routing
UserContext::$currentUser = $auth->user(); // Leaks user details to next requests!

After ​

Use Nexphant's request-context binding to attach state to the current request owner:

php
use Nexphant\Runtime\Context;

// Bind to current context
Context::set('current_user', $auth->user());

// Retrieve safely (context is destroyed when the request completes)
$user = Context::get('current_user');

2. Shift to Connection Pooling ​

In traditional PHP, you open a connection and let it close when the request dies. In Nexphant, connections must be kept alive and recycled.

  • Do not initialize class-level database singletons that keep private connection resources without checking if the socket is alive.
  • Use Nexphant's built-in database adapters that implement dynamic connection pools automatically.

3. Replace exit() and die() ​

Calling exit() or die() in a traditional application terminates the script, which is fine when spawning short processes. In Nexphant, calling exit() shuts down the entire persistent worker process, disrupting other concurrent fibers.

  • Replace exit() or die() with proper returns or exceptions:
php
// Before
if (!$authorized) {
    echo "Unauthorized";
    exit;
}

// After
if (!$authorized) {
    throw new \Nexphant\Exception\HttpException("Unauthorized", 401);
}

4. Adapt File Uploads ​

Ensure temporary files are cleaned up. Since workers don't restart, file paths written to /tmp will remain until the server disk fills up.

  • Register file paths to the current context's release queue so they are deleted automatically:
php
$tempPath = '/tmp/upload_' . uniqid();
file_put_contents($tempPath, $uploadData);

// Automatically delete the file when the current request owner finishes
\Nexphant\Runtime\Owner::current()->onRelease(fn() => @unlink($tempPath));

Released under the MIT License.