Skip to content

Commit

Permalink
Merge pull request #44 from DarkGhostHunter/master
Browse files Browse the repository at this point in the history
Added ignoring unreadable files
  • Loading branch information
DarkGhostHunter authored Jul 7, 2020
2 parents c86cb1e + 8ddec1f commit 19829a8
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
/.scrutinizer.yml export-ignore
/tests export-ignore
/.editorconfig export-ignore
/.github export-ignore
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ This package generates a [PHP 7.4 preloading](https://www.php.net/manual/en/opca
* [Generation](#generation)
+ [`memoryLimit()`](#memorylimit)
+ [`useRequire()`](#userequire)
+ [`ignoreNotFound()`](#ignorenotfound)
* [Compilation](#compilation)
+ [`writeTo()`](#writeto)
+ [`getList()`](#getlist)
Expand Down Expand Up @@ -244,6 +245,22 @@ Preloader::make()->useRequire(__DIR__ . '/../vendor/autoload.php');

> You may get some warnings when compiling a file with unresolved links. These are not critical, since these files usually are the least requested in your application.
#### `ignoreNotFound()`

Some applications may create files at runtime that are genuinely cached by Opcache, but doesn't exist when the application is firstly deployed.

To avoid this problem, you can use the `ignoreNotFound()`, which will compile a script that ignore files not found or are unreadable.

```php
<?php

use DarkGhostHunter\Preloader\Preloader;

Preloader::make()->ignoreNotFound();
```

> If the file is readable but its preloading returns an error, it will throw an exception nonetheless.
### Compilation

#### `writeTo()`
Expand Down
20 changes: 20 additions & 0 deletions src/GeneratesScript.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ trait GeneratesScript
*/
protected ?string $autoloader = null;

/**
* If the script should ignore files not found.
*
* @var bool
*/
protected bool $ignoreNotFound = false;

/**
* Memory limit (in MB) to constrain the file list.
*
Expand Down Expand Up @@ -54,6 +61,19 @@ public function useRequire(string $autoloader) : self
return $this;
}

/**
* If it should NOT throw an exception when a file to preload doesn't exists.
*
* @param bool $ignore
* @return $this
*/
public function ignoreNotFound($ignore = true)
{
$this->ignoreNotFound = $ignore;

return $this;
}

/**
* Returns a digestible Opcache configuration
*
Expand Down
1 change: 1 addition & 0 deletions src/Preloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ protected function prepareCompiler(string $path)
$this->compiler->opcacheConfig = $this->getOpcacheConfig();
$this->compiler->preloaderConfig = $this->getPreloaderConfig();
$this->compiler->useRequire = $this->useRequire;
$this->compiler->ignoreNotFound = $this->ignoreNotFound;
$this->compiler->autoloader = $this->autoloader;
$this->compiler->writeTo = $path;

Expand Down
8 changes: 8 additions & 0 deletions src/PreloaderCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ class PreloaderCompiler
*/
public string $writeTo;

/**
* If it should add exception for not-found files.
*
* @var bool
*/
public bool $ignoreNotFound;

/**
* Returns a compiled string
*
Expand All @@ -68,6 +75,7 @@ public function compile() : string
'@autoload' => isset($this->autoloader)
? 'require_once \'' . realpath($this->autoloader) . '\';': null,
'@list' => $this->parseList(),
'@failure' => $this->ignoreNotFound ? 'continue;' : 'throw new \Exception("{$file} does not exist or is unreadable.");',
'@mechanism' => $this->useRequire
? 'require_once $file' : 'opcache_compile_file($file)',
]);
Expand Down
2 changes: 1 addition & 1 deletion src/preload.php.stub
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ $files = [@list];
foreach ($files as $file) {
try {
if (!(is_file($file) && is_readable($file))) {
throw new \Exception("{$file} does not exist or is unreadable.");
@failure
}
@mechanism;
} catch (\Throwable $e) {
Expand Down
32 changes: 32 additions & 0 deletions tests/PreloaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,38 @@ public function test_excludes_phantom_preload_variable()
$this->assertStringNotContainsString('$PRELOAD$', $contents);
}

public function test_includes_error_when_files_dont_exists()
{
$this->mockOpcache();

$preloader = new Preloader(new PreloaderCompiler, new PreloaderLister, $this->opcache);

$preloader->writeTo($this->preloaderPath);

$contents = file_get_contents($this->preloaderPath);

$this->assertStringContainsString('throw new \Exception("{$file} does not exist or is unreadable.");', $contents);
$this->assertStringNotContainsString('if (!(is_file($file) && is_readable($file))) {
continue;
}', $contents);
}

public function test_excludes_exception_if_file_doesnt_exists_by_default()
{
$this->mockOpcache();

$preloader = new Preloader(new PreloaderCompiler, new PreloaderLister, $this->opcache);

$preloader->ignoreNotFound()->writeTo($this->preloaderPath);

$contents = file_get_contents($this->preloaderPath);

$this->assertStringNotContainsString('throw new \Exception("{$file} does not exist or is unreadable.");', $contents);
$this->assertStringContainsString('if (!(is_file($file) && is_readable($file))) {
continue;
}', $contents);
}

public function test_exception_when_autoload_doesnt_exists()
{
$this->expectException(LogicException::class);
Expand Down

0 comments on commit 19829a8

Please sign in to comment.