Distribute Nette as single PHAR file

6 years ago

Milo
Nette Core | 1148
+
0
-

Hasn't been there a discussion on this topic earlier? I didn't find any threads…

I just tried to compile Nette 2.0.13 to phar and it works nice. Comparisions to minified version:
Pros:

  • phar loading is 5× faster
  • phar.gz loading is 2× faster
  • phar.gz is 2× smaller
  • classes are loaded on demand

Cons:

  • phar is 2× bigger

Dirty code to compile it:

if (ini_get('phar.readonly')) {
    echo "Disable 'phar.readonly' in php.ini.\n";
    exit(1);
}


$pharName = 'nette-dev.phar';
$pharDst = __DIR__ . "/$pharName";
$srcDir = realpath(__DIR__ . '/../nette/Nette');


$phar = new Phar(
    $pharDst,
    FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME,
    $pharName
);

$phar->buildFromDirectory($srcDir);
$phar->setStub($phar->createDefaultStub('loader.php'));

@unlink($pharDst . '.gz');
$pharGz = $phar->compress(Phar::GZ);
$pharGz->setStub($pharGz->createDefaultStub('loader.php'));

Dirty code to test it:

$dt = -microtime(TRUE);
#require 'phar://' . __DIR__ . '/nette-dev.phar/loader.php';
#require __DIR__ . '/nette-dev.phar';
require __DIR__ . '/nette-dev.phar.gz'; # 2x slower
#require __DIR__ . '/nette.min.php';
$dt += microtime(TRUE);

Nette\Diagnostics\Debugger::enable(FALSE);
Nette\Diagnostics\Debugger::$strictMode = TRUE;

dump($dt);
dump(get_declared_classes());


# Just autoloading test
$finder = new Nette\Utils\Finder;
dump($finder);

It needs more tests, actually run all Nette tests. I can do that, but I want to ask you for experiences and opinions at first.

6 years ago

Milo
Nette Core | 1148
+
0
-

Heh,ok, just found one old article https://phpfashion.com/…ktnim-baleni but without result…

6 years ago

enumag
Member | 2128
+
0
-

@Milo: How is it compared to non-minified version? I'm thinking about making a phar file out of the vendor directory after deployment. Not sure whether it's a good idea though.

6 years ago

Majkl578
Moderator | 1379
+
0
-

Just a side note, PHAR archives are currently (or was recently) buggy under Zend Optimizer (aka OPcache).

enumag wrote:

How is it compared to non-minified version?

PHAR content is not minified. It's full version, just packed into an archive (think about it like including nette.zip).

6 years ago

Milo
Nette Core | 1148
+
0
-

@enumag

How is it compared to non-minified version?

I dind't compare PHARed and full (non-minified) Nette versions. But PHAR size is almost the same with small overhead. Just view a PHAR content in some text editor and you'll see why. And class loading will be a little bit slower, but I have no measurements.

I'm thinking about making a phar file out of the vendor directory after deployment. Not sure whether it's a good idea though.

I have no experiences.

@Majkl578
Thanks. As I read it, the OPcache is broken when path to PHAR begins by phar:// and the rest is relative path to PHAR file. In that case there can be collisions. But when it is used without phar:// or with phar:///absolute/path/file.phar there's no problem.

I runned Nette tests with PHARed version and all passed. But it needs own (simplier) PHAR stub. I used:

$phar->setStub("<?php
require 'phar://' . __FILE__ . '/loader.php';
__HALT_COMPILER();");

The right stub code is questionable for distribution.

5 years ago

David Grudl
Nette Core | 6848
+
0
-

I tried to benchmark the Sandbox under PHP 5.5.6 and there are “time per request” in ms (concurrency = 10):

  NetteLoader Composer nette.min.php phar phar + gzip
bez Opcache 13 13 13 12 36
s Opcache 13 13 13 13 36

Sandbox is very atypical project, so there is measurements of the real eshop (with opcache)

NetteLoader Composer nette.min.php phar phar + gzip
64 54 62 62 63

NetteLoaderem refers to a combination of Composer & NetteLoader that is since 2.1.0 not used. From the results, it seems that minified version could be replaced with Phar.

5 years ago

Milo
Nette Core | 1148
+
0
-

Wow, that's great, thank you! I just saw it on GitHub before few minutes.

I'm surprised about almost the same times with/without Opcache. And such big decompressing overhead in sandbox and small overhead in eshop. Interesting.

Note to phar stub. As I understood to default stub source code var_dump($phar->createDefaultStub('loader.php')), it is possible to load phar content without phar extension. But phar extension is part of core since PHP 5.3.0, I guess it is not needed.

5 years ago

JakubJarabica
Gold Partner | 184
+
0
-

Any ideas how can I get Nette in phar to work with PHPStorm + Xdebug?

When I create breakpoint e.g. on $form->setDefaults($variable), I cannot get inside FormContainer: https://www.dropbox.com/…08.11.46.png.

When I googled I found on Jetbrains blog info that phar is supported in PHPStorm, Xdebug supports it as well. I already ran action “Include phar into project”, but it didn't help.

Thanks!

5 years ago

Filip Procházka
Moderator | 4693
+
0
-

Just FYI, minified versions (.min.php or .phar) are supposed to be used only on production. You're supposed to use not-minified version of the package on development for exactly theese reasons :)

And FYI 2, if you have APC or any other opcode caching, there is no benefit in using minified version at all.

Just use composer and don't kill your time anymore :)

5 years ago

JakubJarabica
Gold Partner | 184
+
0
-

OK, will do, thanks.

Just a side note. What is the best way to automate switching between Nette versions? Modifying deployment script to not deploy full version and modify bootstrap? Moreover, how can composer help me with this?