Importing From URLs

Last updated on 14th September 2024

Thing is, I want to write code that resembles Deno, so I need to make a way for this to work elegantly. Figuring out whether you would want to consume code like this is your job. I hope you’re reading the source code of every Composer and NPM dependency you install and update…

$export = require 'https://framework.test/export.php';

I tried running this code, and got an error:

Warning: require(): https:// wrapper is disabled in the server configuration
by allow_url_include=0 in /Users/assertchris/Herd/test/index.php on line 3

Warning: require(https://framework.test/export.php): Failed to open stream:
no suitable wrapper could be found in /Users/assertchris/Herd/test/index.php
on line 3

...

This makes sense. I shouldn’t be able to do this by default. After adding allow_url_include=1 to the configuration file, I stopped getting the error. Something else was happening, though.

When frameworks like Laravel have their configuration in a PHP file, and that PHP file returns something, then that becomes the result of a call to require and include. For example, given the following config file:

<?php

return [
  'debug' => true,
];

This can be pulled into an application:

<?php

$config = require 'config.php';
print $config['debug'];

This is a cool PHP feature, because it allows config of an app in the same language as the app code. You can have closures and other useful PHP data types, and these can be read and interacted with using PHP.

When you include or require from a URL, a different stream wrapper is used (remember the error message). This team wrapper doesn’t return the value returned by the PHP script you’re including. It returns true if the file was successfully included.

You can still do things in that file. print statements still work. You can still make or delete files. You just can’t return anything, because knowing the file was included seems to be more important for that stream wrapper.

If I want to include files by URL, I am going to need to register my own stream wrapper, which not only caches the source code, but also returns the value of it as though this file was just another file in the same application folder.