box-project / box

📦🚀 Fast, zero config application bundler with PHARs.
https://box-project.github.io/box
MIT License
1.12k stars 101 forks source link

Prebuild opcache into the PHAR #1128

Open dkarlovi opened 10 months ago

dkarlovi commented 10 months ago

Feature Request

It's possible to prebuild the opcache onto the filesystem and skip having the actual source available, see https://github.com/dkarlovi/docker-php-opcache-only

Box could have a mode where this type of effort is done and the opcache files are stored into the PHAR instead of raw source files. Req checker would demand having an opcache module available, which would be easy to do in #331

This would very likely reduce the PHAR size since you only need to ship the actual code and can skip comments, docs, etc etc.

theofidry commented 10 months ago

I'm sorry I'm really into something else at the moment, could you expand on what you're doing? 😅

dkarlovi commented 10 months ago

Check the linked repo.

Basically, you make PHP generate opcode into a file and you ship that file, you no longer need to ship the original file that was used to generate it, only the opcode file is used to run the app.

In short, PHAR would be like a JAR, shipping bytecode, not source code.

theofidry commented 10 months ago

Wouldn't there be limitations regarding the max opcache size or the type of code that can be loaded?

dkarlovi commented 10 months ago

The opcache size is relevant when it's in memory. Here it's on the file system and the same rules don't apply (AFAIK).

javiereguiluz commented 10 months ago

@dkarlovi interesting idea. Thanks for proposing it.

I have two quick questions because I don't know much about low-level OPcache:

dkarlovi commented 10 months ago

@javiereguiluz those are good questions.

In my mind, this should start as a direct extension of #331 where the binary shim you'll use to make your PHAR a "native app" is also used to actually build the opcode-PHAR. This would guarantee the opcode is compatible with the shim since it's the shim which built it. This might be a bit conservative and maybe the opcode built by Linux shim can also be used by MacOS shim (assuming the version is identical), but I'm not sure how that works so it would be an optimization.

theofidry commented 10 months ago

Caveat from @mpociot:

I looked into running op-cache files a lot for NativePHP. In theory, it's possible, but it's almost impossible to do with the current implementation because of how opcache files get cached/looked up. They use the absolute path of the php file as a cache key, which would be different for every user running the binary file. There was a RFC/PR for PHP that would make this possible, but unfortunately it was rejected at the time.

No idea if it's relevant or test, I just want it to be here for context when I look further into this.

dkarlovi commented 10 months ago

Since we'll expect to build the files into the PHAR, we know exactly where they are, their absolute path is not changing from PHARs POV, no? :thinking:

pronskiy commented 10 months ago

There was this RFC, not sure if it's the one @mpociot was referring to. RFC: Direct execution opcode file without php source code file Discussion | PR

As I understood, the problem there is not just file paths, but also system id check. So the precompiled opcache works, but reliably only on the same machine with the same php version.

While this makes distributing pre-compiled op-cache useless, there is, however, an interesting idea here. Let's say we have a PHAR glued with PHP bin. This PHP can have its own php.ini opcache settings. And so it can generate and save opcache to some dir and essentially make opcache.enable_cli useful.

pronskiy commented 10 months ago

Ah, but it should be good for Dockerized apps.

dkarlovi commented 10 months ago

Yes, because the binary would contain the PHP which generated the opcode so it's guaranteed to be compatible (as much as PHP is compatible with itself, I guess 😂)

dkarlovi commented 4 months ago

BTW I've reported https://github.com/php/php-src/issues/13989 to hopefully remove one annoyance from getting this working smoothly, it seems like a small issue which could result in a tiny performance improvement, but a big DX improvement (you don't need to have dummy empty files on the filesystem which are not used for anything but for just existing).