Skip to content
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

Preloading has no defined io-stream constants #10673

Open
SCIF opened this issue Feb 23, 2023 · 2 comments
Open

Preloading has no defined io-stream constants #10673

SCIF opened this issue Feb 23, 2023 · 2 comments

Comments

@SCIF
Copy link

SCIF commented Feb 23, 2023

Description

As of https://www.php.net/manual/en/features.commandline.io-streams.php , there should be constants defined in CLI.

Added the following to preload.ini:

opcache.preload_user=www-data
opcache.preload=/path/to/preload.php

The following code wrote to preload.php:

<?php

var_dump(defined('STDIN'));
var_dump(defined('STDOUT'));
var_dump(defined('STDERR'));

Resulted in this output:

/path/to/preload.php:3:
bool(false)
/path/to/preload.php:4:
bool(false)
/path/to/preload.php:5:
bool(false)

But I expected this output instead:

/path/to/preload.php:3:
bool(true)
/path/to/preload.php:4:
bool(true)
/path/to/preload.php:5:
bool(true)

I could imagine this is the expected behavior but docs should be updated then. :) There are no restrictions defined in https://www.php.net/manual/en/opcache.preloading.php BTW, the opcache_enabled shown as false for var_dump(opcache_get_status(false));.

PHP Version

8.1.16

Operating System

Docker image: php:8.1-fpm-bullseye

@iluuu1994
Copy link
Member

Given that echo works in CLI with preloading I think expecting these constants to be there is reasonable.

@nielsdos
Copy link
Member

nielsdos commented Mar 25, 2023

I tried tackling this, but it's more complicated than I thought. The constants (and stdin/stdout/stderr stream configuration) happen in cli_register_file_handles() which is called from do_cli(). But the preloaded script gets executed before that happens, in php_module_startup() which is called from php_cli_startup(). I tried to create a fake module that calls cli_register_file_handles() that runs before opcache's startup, but that crashes because we need zend_activate() to have been called for the open files and resources lists.
So in short this means that only for the lifetime of the main script the cli_register_file_handles() function is called. This also means that the following gives strange results:

preload.php:

<?php
$f = fopen("php://stdout", "w");
fwrite($f, "hello\n");
fclose($f);

index.php:

<?php
echo "hi"; // nothing printed

Put the echo in the preload file and you get a "bad file descriptor" warning, and put the fopen-fwrite-fclose in the index file and you get "hello" and "hi".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants