EvanDotPro / EdpSuperluminal

This module caches the common Zend\* classes used by your application into a single cache file, reducing reliance on the autoloader. This greatly improves the performance of ZF2.
BSD 2-Clause "Simplified" License
170 stars 47 forks source link

create the cache once and use it for all other distributions #27

Open Exlord opened 10 years ago

Exlord commented 10 years ago

Hi, i have written a CMS with ZF2 and i am using it for a couple of sites (10 at the moment- more later) so i created the cache in my local system and uploaded it to the sites BUT i encountered a problem in Zend\Validator\Hostname(line 557) : $regexChars += include __DIR__ . '/' . $this->validIdns[$this->tld]; the __DIR__ is converted to my local file path and causeing a file not found error in the other systems.

is there a way to fix this ? or do i have to to the process for every site ???

berturion commented 8 years ago

I wanted to create an issue for this and I saw yours.

I really +1.

The cache is not usable on multiple environments as soon as the code uses classes that contains the __DIR__ keyword. If so, the full local path is written in the cache file and causes application crashes once deployed to another location. I don't know how to avoid this, and it is very annoying because it prevents us to use some very important framework classes like Zend\Validator\Hostname. In my case it was with Zend\I18n\Translator in which the method getBasePath returns the directory where are stored framework translations using __DIR__ . '/../languages/'.

Another workaround would be to generate the cache in the target environment, but it forces us to load EdpSuperluminal module in production which is not a good thing.

EDIT: I think the best quick solution would be to ignore classes that contains __DIR__ keyword in the process of caching but I don't know how. All the module code is in Module.php, maybe someone could find how to parse classes and detect __DIR__ in order to not cache these files ?

berturion commented 8 years ago

OK. I've done it. I don't know how to make a pull request, if the maintainer can see this, please update the code.

Here is the first modified sample of Module.php:

        (...)
        // Skip internal classes or classes from extensions
        // (this shouldn't happen, as we're only caching Zend classes)
        if ($class->isInternal()
            || $class->getExtensionName()
        ) {
            continue;
        }

        // BEGIN NEW CODE
        // Skip class containing __DIR__ instructions
        if (static::hasMagicDIR($class->getFileName())) {
            continue;
        }
        // END NEW CODE

        $code .= static::getCacheCode($class);
        (...)

And the new method hasMagicDIR:

protected static function hasMagicDIR($classFilePath) {
    $ret = false;
    $fh = fopen($classFilePath,'r');
    while ($line = fgets($fh)) {
        if(strstr($line, '__DIR__')) {
            $ret = true;
            break;
        }
    }
    fclose($fh);
    return $ret;
}
berturion commented 8 years ago

In case you're interested: https://github.com/berturion/EdpSuperluminal