I am including a PHP file that in stored in the public:// directory.

(Yes, I know that's generally a bad thing, but there are reasons, and this is done on a local development server.)

I get this warning.

User warning: stream_set_option() not supported for local file based stream wrappers in Drupal\Core\StreamWrapper\LocalStream->stream_set_option() (line 356 of core/lib/Drupal/Core/StreamWrapper/LocalStream.php).

I don't understand what's going on.

Why is include() calling PublicStream::stream_set_option()?


It happens with PHP 7.4, where one of the backward incompatible changes is the following one.

When using include/require on a stream, streamWrapper::stream_set_option() will be invoked with the STREAM_OPTION_READ_BUFFER option. Custom stream wrapper implementations may need to implement the streamWrapper::stream_set_option() method to avoid a warning (always returning FALSE is a sufficient implementation).

Even with the latest code committed in Drupal 9, LocalStream::stream_set_option() triggers the user error you are seeing.

public function stream_set_option($option, $arg1, $arg2) {
  trigger_error('stream_set_option() not supported for local file based stream wrappers', E_USER_WARNING);
  return FALSE;
  • Thanks for the explanation!
    – joachim
    Jul 8 '20 at 6:38
  • So in my case, I need to get from settings the path that public:// represents, and then use include on that.
    – joachim
    Jul 8 '20 at 6:38
  • Directly using the path of the file to include would avoid that user error. I would rather do so, especially because the public:// directory doesn't usually change very often.
    – apaderno
    Jul 8 '20 at 7:35
  • I understand that using public:// would make the code work for every site, without editing the code to correct the file path. I also doubt Drupal core maintainers will remove the code triggering the user error to allow users to use include() with public://.
    – apaderno
    Jul 13 '20 at 10:17
  • I've fixed it by doing: $directory = str_replace("public://", \Drupal::service('file_system')->realpath("public://") . '/', $directory); and so it still works on every site.
    – joachim
    Jul 14 '20 at 12:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.