DarkGhostHunter/Preloader

preloader.php.stub

illnesse opened this issue · 9 comments

Would be cool if you specify the preloader stub location via config, so you can use your own.
My setup seems to have issue with yours but this works, not sure why:

    try
    {
        if (!@include_once($file)) {
            throw new \Exception($file . ' cannot include');
        }
        else if (!file_exists($file)) {
            throw new \Exception($file . ' does not exist');
        }
        require_once $file;
    }

it kept saying file not found

That shouldn't happen. May be there is a permission problems on your side. Can you trace it?

In official docker php:7.4-cli

php > include_once('/var/www/preloader.php');
php > print_r(include_once('/var/www/preloader.php'));
1
php > print_r(!@include_once('/var/www/preloader.php') || !true);
1
php > print_r(!include_once('/var/www/preloader.php') || !true); 

Warning: include_once(1): failed to open stream: No such file or directory in php shell code on line 1

Call Stack:
  174.6262     868416   1. {main}() php shell code:0


Warning: include_once(): Failed opening '1' for inclusion (include_path='.:/usr/local/lib/php') in php shell code on line 1`

Call Stack:
  174.6262     868416   1. {main}() php shell code:0

1
php > print_r(!(include_once('/var/www/preloader.php')) || !true);
php > 

I suggest the following solution for fix:

foreach ($files as $file) {
    try {
        if (!(is_file($file) && is_readable($file))) {
            throw new \Exception("{$file} does not exist or unreadable.");
        }
        require_once $file;
    } catch (\Throwable $e) {
        echo "Exception: {$e->getFile()}:{$e->getLine()}", PHP_EOL,
        "Message: {$e->getMessage()}", PHP_EOL;
    }
}

Why the preloader tries to include a file called 1? Seems the list is putting something that shouldn't be there.

I do not know. I’ll go read the documentation =)
This behavior when using the operator || with include

For example

php > print_r(include_once('/var/www/preloader.php') || 2);

Warning: include_once(1): failed to open stream: No such file or directory in php shell code on line 1

Call Stack:
    4.8744     863256   1. {main}() php shell code:0


Warning: include_once(): Failed opening '1' for inclusion (include_path='.:/usr/local/lib/php') in php shell code on line 1

Call Stack:
    4.8744     863256   1. {main}() php shell code:0

from https://www.php.net/manual/en/function.include.php

Because include is a special language construct, parentheses are not needed around its argument. Take care when comparing return value.

Example #4 Comparing return value of include

// won't work, evaluated as include(('vars.php') == TRUE), i.e. include('')
if (include('vars.php') == TRUE) {
    echo 'OK';
}

// works
if ((include 'vars.php') == TRUE) {
    echo 'OK';
}

Sorry, I tried several of my fixes with include or require ... And in the case of "include", "require" I have a lot of problems. I think running code on a list from opcache is a bad idea. Many files have non-static code that should not be executed randomly, and these files are difficult to manually exclude. But, I think, the first idea was to precompile statics from opcache.

I suggest:

// remove this line. It's exist in $files
// require_once '/var/www/vendor/autoload.php';

$files = [
    ....
];

foreach ($files as $file) {
    opcache_compile_file($file);
}

It seems should work =) if I did not understand for what all this, sorry)

I use require instead of compile because require will pull out (thanks to autoload) the file with all its linked files (traits, abstract classes and what not). If the last file uses links outside the list, this will pull them instead of compiling the file and keep the links dangling.

I could make an option to use compile instead of require. Or even better, allow to use compile exclusively for certain files, instead of all.

I'm aware that the script may not work for 100% of people, but that change could work for vast majority.

Update: I was on mobile.

Solved in #15

You're free now to use whichever method works for your application.

Files will not precompile and will not execute
comment

I wrote about in here
#11 (comment)
#11 (comment)
Sorry, if the messages is non-readable, but by examples you cat understant me.

And include_once cannot be used with opcache_compile_file.