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

Opcache is a problem with the FileSystem driver #135

Merged
merged 4 commits into from
Mar 30, 2014
Merged

Opcache is a problem with the FileSystem driver #135

merged 4 commits into from
Mar 30, 2014

Commits on Mar 15, 2014

  1. Switched include() to using eval + file_get_contents instead

    This is a bit of a long story.
    
    I've been working with tedivm/Stash for a while for an Authentication and Authorisation library. I was using the FileSystem driver for file based sessions. It was working for a long time, both from a Windows computer and on hosted Ubuntu system on Digital Ocean.
    
    However I recently started testing it on my Ubuntu VM which runs on the same kind of specs as the Digital Ocean's VM in order to simulate a closer environment to production.
    
    And then the session management broke.
    
    I started logging everything to figure out what was happening. And what was happening was this, but let me describe the context first.
    
    ```
    <?php 
    /* Cachekey: cache/polyauthqkc1z5m33e/ */
    /* Type: array */
    $expiration = 1394941347;
    $data = array();
    
    /* Child Type: array */
    $data['return'] = unserialize(base64_decode('YToxOntzOjc6InVzZXJfaWQiO2I6MDt9'));
    
    /* Child Type: integer */
    $data['createdOn'] = 1394901250;
    ```
    
    Here is the included file (cached file). The returned variable should end up being: `["user_id" => false]`;
    
    I know this is the real file content prior the the include command because I wrote this as a part of my logger:
    
    ```
    //...line 141
    \FB::log(file_get_contents($path), 'FILE CONTENT PRIOR TO INCLUSION');
    
    include($path);
    //...etc
    ```
    
    And it showed the above file content exactly prior to inclusion.
    
    Now the next thing I did was log the `$data` variable.
    
    ```
    //...line 141
    \FB::log(file_get_contents($path), 'FILE CONTENT PRIOR TO INCLUSION');
    
    include($path);
    
    \FB::log($data, 'DATA VARIABLE');
    //...etc
    ```
    
    This is where the discrepancy appeared.
    
    On my Windows (Apache + mod_php) system it showed:
    
    ```
           "data"       => [
               "return"    => [
                   "user_id" => false
               ],
               "createdOn" => 1394901250
           ]
    ```
    
    On my Ubuntu Digital Ocean VM it would show the same since the session management was working.
    
    However on my Ubuntu VirualBox VM it would show:
    
    ```
           "data"       => [
               "return"    => [],
               "createdOn" => 1394901250
           ]
    ```
    
    Exactly the same createdOn timestamp, but an empty return array!?
    
    Needless to say, this made session management impossible, since none of the sessions could ever be remembered.
    
    Now the error goes away, and still works with all environments, if you instead use eval with file_get_contents:
    
    ```
    eval('?>' . file_get_contents($path));
    ```
    
    This technique is exactly equivalent to using include (the `?>` basically allows the file to start with `<?php`). See this: http://stackoverflow.com/questions/1184628/php-equivalent-of-include-using-eval
    
    I don't know why this error occurs. I don't have enough knowledge about the PHP internals why include doesn't work but this does. It might have something to do with opcode or caching.
    
    I also did some benchmarking. Zero microtime difference.
    CMCDragonkai committed Mar 15, 2014
    Configuration menu
    Copy the full SHA
    2c18b33 View commit details
    Browse the repository at this point in the history

Commits on Mar 26, 2014

  1. Configuration menu
    Copy the full SHA
    31da95f View commit details
    Browse the repository at this point in the history

Commits on Mar 28, 2014

  1. Configuration menu
    Copy the full SHA
    88b53c4 View commit details
    Browse the repository at this point in the history

Commits on Mar 30, 2014

  1. Configuration menu
    Copy the full SHA
    5ddea80 View commit details
    Browse the repository at this point in the history