Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

PHP: Stream stdout and stderr #2261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
adamziel wants to merge 1 commit into trunk from push-oznxvtpzqmzr
Closed

PHP: Stream stdout and stderr #2261

adamziel wants to merge 1 commit into trunk from push-oznxvtpzqmzr

Conversation

@adamziel
Copy link
Collaborator

@adamziel adamziel commented Jun 11, 2025

Implements a php.runStream() method that returns a StreamedPHPResponse instance.
It exposes stdout and stderr as ReadableStreams, allowing the caller to interact
with partial output data. Before this PR, we only had php.run() that buffered
stdout and stderr data and returned it all at once after the PHP code was fully
executed.

Implementation

We register three FS devices at:

  • /internal/stdout
  • /internal/stderr
  • /internal/headers

They are private to every PHP instance and are never shared with other runtimes.

Then, in JavaScript, whenever a chunk of data is written to either of these devices, we propagate
it to consumer via a callback, e.g. PHPWASM.onStdout(chunk).

Users of the PHP class never have to interact with these devices or callbacks directly.
The PHP class creates the relevant ReadableStreams and pushes the data through them
– see php.#executeWithErrorHandling() for details.

Why not use Emscripten's stdout and stderr?

Emscripten's native stdout and stderr devices stop processing data when they encounter
the first null byte. However, null bytes are common when dealing with binary data.

Backwards Compatibility

php.run() continues to work. It creates a streamed response under the hood and buffers
the streamed output before returning a buffered PHPResponse object.

Remaining work

  • Add streaming-specific tests

Follow-up work

  • Stream the response bytes in the web/service worker

// @TODO: Why are we logging things so eagerly? Shouldn't
// the caller handle that? There's so much noise in
// the console.
// logger.error(rethrown);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I found the original PR and it looks like I just replaced all console.error calls with logger.error, so this might be a good time to rethink if we really need these log entries.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Aha, good spot! Thank you

@adamziel adamziel force-pushed the push-szvonsvruzmv branch 7 times, most recently from f3bca7e to 4c5aa92 Compare June 12, 2025 15:09
Base automatically changed from push-szvonsvruzmv to trunk June 12, 2025 15:57
@adamziel adamziel force-pushed the push-oznxvtpzqmzr branch 7 times, most recently from 7f310d7 to 58956fc Compare June 12, 2025 18:29
Implements a php.runStream() method that returns a StreamedPHPResponse instance.
It exposes stdout and stderr as ReadableStreams, allowing the caller to interact
with partial output data. Before this PR, we only had php.run() that buffered 
stdout and stderr data and returned it all at once after the PHP code was fully
executed.
## Implementation
We register three FS devices at:
* /internal/stdout
* /internal/stderr
* /internal/headers
They are private to every PHP instance and are never shared with other runtimes.
Then, in JavaScript, whenever a chunk of data is written to either of these devices, we propagate
it to consumer via a callback, e.g. `PHPWASM.onStdout(chunk)`.
Users of the `PHP` class never have to interact with these devices or callbacks directly.
The PHP class creates the relevant ReadableStreams and pushes the data through them
– see php.#executeWithErrorHandling() for details.
#### Why not use Emscripten's stdout and stderr?
Emscripten's native stdout and stderr devices stop processing data when they encounter
the first null byte. However, null bytes are common when dealing with binary data.
### Backwards Compatibility
php.run() continues to work. It creates a streamed response under the hood and buffers
the streamed output before returning a buffered `PHPResponse` object.
## Remaining work
* Add streaming-specific tests
## Follow-up work
* Stream the response bytes in the web/service worker
Remove old PHP CLI bindings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@bgrgicak bgrgicak bgrgicak left review comments

Assignees

No one assigned

Projects

No open projects
Status: Done

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /