diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 95adc95..1499b6d 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -3516,3 +3516,78 @@ function drupal_check_memory_limit($required, $memory_limit = NULL) {
   //   the operation.
   return ((!$memory_limit) || ($memory_limit == -1) || (parse_size($memory_limit) >= parse_size($required)));
 }
+
+/**
+ * Read a file from Drupal's PHP storage.
+ *
+ * @param string $filename
+ *   The name of the file to read. Can be a relative path.
+ * @param string $type
+ *   A string that describes the contents of the file. e.g. Twig, DIC
+ *
+ * @return
+ *   No return but requested code is included and executable.
+ */
+function drupal_php_read($filename, $type = 'default') {
+  include_once _drupal_php_helper($filename, $type);
+}
+
+/**
+ * Write a file to Drupal's PHP storage.
+ *
+ * @param string $filename
+ *   The name of the file to write. Can be a relative path.
+ * @param string $data
+ *   The contents of the file.
+ * @param string $type
+ *   A string that describes the contents of the file. e.g. Twig, DIC
+ */
+function drupal_php_write($filename, $data, $type = 'default') {
+  file_put_contents(_drupal_php_helper($filename, $type), $data);
+}
+
+/**
+ * Gets the path to the requested file in Drupal's PHP storage.
+ *
+ * @param string $filename
+ *   The name of the file. Can be a relative path.
+ * @param string $type
+ *   A string that describes the contents of the file. e.g. Twig, DIC
+ */
+function _drupal_php_helper($filename, $type) {
+  static $drupal_static_fast;
+  if (!isset($drupal_static_fast)) {
+    $drupal_static_fast['initalized'] = &drupal_static(__FUNCTION__);
+  }
+  $initalized = &$drupal_static_fast['initalized'];
+
+  $php_loader = variable_get('php_loader', array());
+  // Shortcut the loading process if there's no loader specified.
+  if (!$php_loader) {
+    return DRUPAL_ROOT . '/' . $filename;
+  }
+
+  $index = isset($php_loader[$type]) ? $type : 'default';
+  $loader_conf = $php_loader[$index];
+  $GLOBALS['conf']['php_loader_current'] = $loader_conf;
+  if (!isset($initalized[$index])) {
+    if (isset($loader_conf['init_callback'])) {
+      $arguments = isset($loader_conf['init_arguments']) ? $loader_conf['init_arguments'] : array();
+      call_user_func_array($loader_conf['init_callback'], $arguments);
+    }
+    $initalized[$index] = TRUE;
+  }
+  if (isset($loader_conf['path_prefix'])) {
+    $filename = $loader_conf['path_prefix'] . $filename;
+  }
+  if (isset($loader_conf['path_prefix_callback'])) {
+    call_user_func_array($loader_conf['path_prefix_callback'], array(&$filename));
+  }
+  return $filename;
+}
+
+function drupal_stream_wrapper_register($protocol, $wrapper) {
+  if (array_search($protocol, stream_get_wrappers()) === FALSE) {
+    stream_wrapper_register($protocol, $wrapper);
+  }
+}
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 32ce838..79dfce2 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1070,6 +1070,20 @@ function install_settings_form_submit($form, &$form_state) {
     'value'     => $config_directory_name ? $config_directory_name : 'config_' . drupal_hash_base64(drupal_random_bytes(55)),
     'required'  => TRUE,
   );
+  // This is our basic php loader.
+  $loader_dir = variable_get('file_public_path', conf_path() . '/files') . '/codegen';
+  $settings['conf']['php_loader'] = array(
+    'value'     => array(
+      'default' => array(
+        'init_callback' => 'stream_filter_register',
+        'init_arguments' => array('drupal.*', 'Drupal\\Core\\PhpLoader\\DrupalStreamFilter'),
+        'path_prefix' => $loader_dir . '/',
+        'path_prefix_callback' => array('Drupal\\Core\\PhpLoader\\DrupalStreamFilter', 'pathPrepare'),
+        'header' => drupal_hash_base64(drupal_random_bytes(55)),
+      ),
+    ),
+    'required'  => TRUE,
+  );
 
   drupal_rewrite_settings($settings);
 
@@ -1083,6 +1097,9 @@ function install_settings_form_submit($form, &$form_state) {
     // Bail out using a similar error message as in system_requirements().
     throw new Exception(st('The directory %directory could not be created or could not be made writable. To proceed with the installation, either create the directory and modify its permissions manually or ensure that the installer has the permissions to create it automatically. For more information, see the <a href="@handbook_url">online handbook</a>.', array('%directory' => config_get_config_directory(), '@handbook_url' => 'http://drupal.org/server-permissions')));
   }
+  // Now that config has ensured that the files directory is writeable,
+  // just create the codegen dir.
+  file_prepare_directory($loader_dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
 
   // Indicate that the settings file has been verified, and check the database
   // for the last completed task, now that we have a valid connection. This
diff --git a/core/lib/Drupal/Core/PhpLoader/DatabaseStreamWrapper.php b/core/lib/Drupal/Core/PhpLoader/DatabaseStreamWrapper.php
new file mode 100644
index 0000000..02ac967
--- /dev/null
+++ b/core/lib/Drupal/Core/PhpLoader/DatabaseStreamWrapper.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\Core\PhpLoader;
+
+class DatabaseStreamWrapper {
+  public $context;
+  protected $contents;
+  protected $eof = TRUE;
+  protected $path = '';
+
+  public function rename($path_from, $path_to) {
+    db_update('php')
+      ->fields(array('path' => $path_to))
+      ->condition('path', $path_from)
+      ->execute();
+    return TRUE;
+  }
+  public function stream_eof() {
+    return $this->eof;
+  }
+  public function stream_open($path, $mode, $options, &$opened_path) {
+    $this->path = $path;
+    $this->read($path);
+    $opened_path = $path;
+    $this->pos = 0;
+    $this->eof = empty($this->contents);
+    return TRUE;
+  }
+  public function stream_read($count) {
+    $return = substr($this->contents, $this->pos, $count);
+    $this->pos += $count;
+    $this->eof = empty($return);
+    return $return;
+  }
+  public function stream_tell() {
+    return $this->pos;
+  }
+  public function stream_write($data) {
+    $fields = array(
+      'contents' => $data,
+      'updated' => REQUEST_TIME,
+    );
+    db_merge('php')
+      ->key(array('path' => $this->path))
+      ->fields($fields)
+      ->execute();
+    return strlen($data);
+  }
+  public function unlink($path) {
+    db_delete('php')
+      ->condition('path', $path)
+      ->execute();
+  }
+  public function stream_stat() {
+    return $this->stat();
+  }
+  public function url_stat($path, $flags) {
+    $this->read($path);
+    return $this->stat();
+  }
+
+  protected function read($path) {
+    if (!$contents = db_query('SELECT contents, updated FROM {php} WHERE path = :path', array(':path' => $path))->fetchAssoc()) {
+      $contents = array('contents' => '', 'updated' => 0);
+    }
+    $this->contents = $contents['contents'];
+    $this->updated = $contents['updated'];
+  }
+
+  protected function stat() {
+    $stat = array(
+      'dev' => 0,
+      'ino' => 0,
+      'mode' => 0,
+      'nlink' => 1,
+      'uid' => 0,
+      'gid' => 0,
+      'rdev' => 0,
+      'size' => strlen($this->contents),
+      'atime' => REQUEST_TIME,
+      'mtime' => $this->updated,
+      'ctime' => $this->updated,
+      'blksize' => -1,
+      'blocks' => -1,
+    );
+    return array_values($stat) + $stat;
+  }
+}
diff --git a/core/lib/Drupal/Core/PhpLoader/DrupalStreamFilter.php b/core/lib/Drupal/Core/PhpLoader/DrupalStreamFilter.php
new file mode 100644
index 0000000..fe381d8
--- /dev/null
+++ b/core/lib/Drupal/Core/PhpLoader/DrupalStreamFilter.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\Core\PhpLoader;
+
+use \php_user_filter;
+
+class DrupalStreamFilter extends php_user_filter {
+  protected $contents;
+
+  public function filter($in, $out, &$consumed, $closing) {
+    // Read all the stream data and store it in the $data property.
+    while ($bucket = stream_bucket_make_writeable($in)) {
+      $this->contents .= $bucket->data;
+      $consumed += $bucket->datalen;
+    }
+    $data = '';
+    if ($closing && preg_match("|^<\?php(?: //(?'hash'[A-Za-z0-9_-]{43})\n)?(?'code'.*)|s", $this->contents, $matches)) {
+      $hash = drupal_hash_base64($GLOBALS['conf']['php_loader_current']['header'] . $matches['code']);
+      switch ($this->filtername) {
+        case 'drupal.read':
+          if ($hash == $matches['hash']) {
+            $data = $this->contents;
+          }
+          break;
+        case 'drupal.write':
+          $data = '<?php //' . $hash . "\n" . $matches['code'];
+          break;
+      }
+    }
+    if ($data) {
+      stream_bucket_append($out, stream_bucket_new($this->stream, $data));
+      return PSFS_PASS_ON;
+    }
+    return PSFS_FEED_ME;
+  }
+  public static function pathPrepare(&$filename) {
+    @mkdir(dirname($filename), 0700, TRUE);
+    $filename = 'php://filter/read=drupal.read/write=drupal.write/resource=' . $filename;
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/PhpLoader/DatabaseStreamWrapperTest.php b/core/modules/system/lib/Drupal/system/Tests/PhpLoader/DatabaseStreamWrapperTest.php
new file mode 100644
index 0000000..7a651c2
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/PhpLoader/DatabaseStreamWrapperTest.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\PhpLoader\DatabaseStreamWrapperTest.
+ */
+
+namespace Drupal\system\Tests\PhpLoader;
+
+class DatabaseStreamWrapperTest extends PhpLoaderTest {
+  public static function getInfo() {
+    return array(
+      'name' => 'Database stream wrapper',
+      'description' => 'Reads and writes a php file in the database.',
+      'group' => 'PHP Loader',
+    );
+  }
+  protected function conf() {
+    return array(
+      'default' => array(
+        'init_callback' => 'drupal_stream_wrapper_register',
+        'init_arguments' => array('dbphp', 'Drupal\\Core\\PhpLoader\\DatabaseStreamWrapper'),
+        'path_prefix' => 'dbphp://',
+      ),
+    );
+  }
+  function testDatabaseStreamWrapper() {
+    $this->assertIdentical($this->contents, db_query('SELECT contents FROM {php} WHERE path = :path', array(':path' => "dbphp://$this->filename"))->fetchfield());
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/PhpLoader/DrupalStreamFilterTest.php b/core/modules/system/lib/Drupal/system/Tests/PhpLoader/DrupalStreamFilterTest.php
new file mode 100644
index 0000000..70f755d
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/PhpLoader/DrupalStreamFilterTest.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\PhpLoader\DatabaseStreamWrapperTest.
+ */
+
+namespace Drupal\system\Tests\PhpLoader;
+
+class DrupalStreamFilterTest extends PhpLoaderTest {
+  protected $loaderDir;
+  public static function getInfo() {
+    return array(
+      'name' => 'Stream filter',
+      'description' => 'Reads and writes a signed php file on the disk.',
+      'group' => 'PHP Loader',
+    );
+  }
+  public function conf() {
+    $this->loaderDir = variable_get('file_public_path', conf_path() . '/files') . '/codegen/';
+    return array(
+      'default' => array(
+        'init_callback' => 'stream_filter_register',
+        'init_arguments' => array('drupal.*', 'Drupal\\Core\\PhpLoader\\DrupalStreamFilter'),
+        'path_prefix' => $this->loaderDir,
+        'path_prefix_callback' => array('Drupal\\Core\\PhpLoader\\DrupalStreamFilter', 'pathPrepare'),
+        'header' => drupal_hash_base64(drupal_random_bytes(55)),
+      ),
+    );
+  }
+
+  public function testDrupalStreamFilter() {
+    $contents = file_get_contents($this->loaderDir . $this->filename);
+    $this->assertIdentical($this->contents, preg_replace('|^<\?php.*\n|', '<?php', $contents));
+    // Change the file and try a second read. This is a fatal if the file is
+    // read again because the same function would be defined the second time
+    // but this does not happen because the file has been changed and the
+    // filter does not let it through.
+    file_put_contents($this->loaderDir . $this->filename, ' ', FILE_APPEND);
+    drupal_php_read($this->filename);
+    $this->pass('The filter works');
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/PhpLoader/PhpLoaderTest.php b/core/modules/system/lib/Drupal/system/Tests/PhpLoader/PhpLoaderTest.php
new file mode 100644
index 0000000..edf3632
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/PhpLoader/PhpLoaderTest.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\PhpLoader\PhpLoaderTest.
+ */
+
+namespace Drupal\system\Tests\PhpLoader;
+
+use Drupal\simpletest\WebTestBase;
+
+abstract class PhpLoaderTest extends WebTestBase {
+  protected $filename;
+  protected $contents;
+  function setUp() {
+    global $conf;
+    parent::setUp();
+    $conf['php_loader'] = $this->conf();
+    $this->filename = $this->randomName() . '.php';
+    do {
+      $random = mt_rand(10000, 100000);
+      $function = 'test' . $random;
+    } while (function_exists($function));
+    $this->contents = "<?php\nfunction $function() { return $random;}";
+    drupal_php_write($this->filename, $this->contents);
+    drupal_php_read($this->filename);
+    $this->assertIdentical($function(), $random);
+  }
+  abstract protected function conf();
+}
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 0605a1d..c2c6052 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1374,6 +1374,31 @@ function system_schema() {
     'primary key' => array('mlid'),
   );
 
+  $schema['php'] = array(
+    'description' => 'Stores PHP code',
+    'fields' => array(
+      'path' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => 'The path to the file.',
+      ),
+      'contents' => array(
+        'description' => 'The contents of the file.',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'updated' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => 'Timestamp when this file was last updated.',
+      ),
+    ),
+    'primary key' => array('path'),
+  );
+
   $schema['queue'] = array(
     'description' => 'Stores items in queues.',
     'fields' => array(
