Files
Virtnet.bond/preload.php

298 lines
9.6 KiB
PHP

<?php
/**
* OPcache Preload Script for PHP 8.3-FPM
*
* Configure in php.ini:
* opcache.preload=/path/to/preload.php
* opcache.preload_user=www-data
*
* Run after deployment: php artisan optimize && php artisan filament:optimize
*/
declare(strict_types=1);
$basePath = __DIR__;
$preloadedCount = 0;
$skippedCount = 0;
/**
* Compile a file into OPcache without executing it
*/
function preloadFile(string $path): bool
{
global $preloadedCount, $skippedCount;
if (!is_file($path) || !is_readable($path)) {
return false;
}
try {
if (opcache_compile_file($path)) {
$preloadedCount++;
return true;
}
} catch (Throwable $e) {
// Silently skip files that can't be preloaded (syntax errors, etc.)
}
$skippedCount++;
return false;
}
/**
* Recursively preload all PHP files in a directory
*/
function preloadDirectory(string $dir, array $excludePatterns = []): void
{
if (!is_dir($dir)) {
return;
}
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
if (!$file->isFile() || $file->getExtension() !== 'php') {
continue;
}
$path = $file->getRealPath();
// Skip excluded patterns
foreach ($excludePatterns as $pattern) {
if (preg_match($pattern, $path)) {
continue 2;
}
}
preloadFile($path);
}
}
/**
* Preload specific files from a list
*/
function preloadFiles(array $files): void
{
foreach ($files as $file) {
if (is_file($file)) {
preloadFile($file);
}
}
}
// =============================================================================
// 1. LARAVEL CACHED/COMPILED FILES (Most Critical)
// =============================================================================
$cachedFiles = [
$basePath . '/bootstrap/cache/packages.php',
$basePath . '/bootstrap/cache/services.php',
$basePath . '/bootstrap/cache/config.php',
$basePath . '/bootstrap/cache/routes-v7.php',
$basePath . '/bootstrap/cache/events.php',
$basePath . '/bootstrap/cache/filament.php',
$basePath . '/bootstrap/cache/livewire-components.php',
];
preloadFiles($cachedFiles);
// =============================================================================
// 2. COMPOSER AUTOLOADER (Essential for class resolution)
// =============================================================================
preloadFiles([
$basePath . '/vendor/autoload.php',
$basePath . '/vendor/composer/autoload_real.php',
$basePath . '/vendor/composer/ClassLoader.php',
$basePath . '/vendor/composer/autoload_static.php',
]);
// =============================================================================
// 3. LARAVEL CORE FRAMEWORK
// =============================================================================
$laravelCoreDirs = [
// Foundation & Core
$basePath . '/vendor/laravel/framework/src/Illuminate/Foundation',
$basePath . '/vendor/laravel/framework/src/Illuminate/Container',
$basePath . '/vendor/laravel/framework/src/Illuminate/Contracts',
// HTTP Layer
$basePath . '/vendor/laravel/framework/src/Illuminate/Http',
$basePath . '/vendor/laravel/framework/src/Illuminate/Routing',
$basePath . '/vendor/laravel/framework/src/Illuminate/Pipeline',
// Database & Eloquent
$basePath . '/vendor/laravel/framework/src/Illuminate/Database',
// Support utilities
$basePath . '/vendor/laravel/framework/src/Illuminate/Support',
$basePath . '/vendor/laravel/framework/src/Illuminate/Collections',
// Session & Auth
$basePath . '/vendor/laravel/framework/src/Illuminate/Auth',
$basePath . '/vendor/laravel/framework/src/Illuminate/Session',
$basePath . '/vendor/laravel/framework/src/Illuminate/Cookie',
// Views & Blade
$basePath . '/vendor/laravel/framework/src/Illuminate/View',
// Events & Queue
$basePath . '/vendor/laravel/framework/src/Illuminate/Events',
$basePath . '/vendor/laravel/framework/src/Illuminate/Queue',
// Validation & Cache
$basePath . '/vendor/laravel/framework/src/Illuminate/Validation',
$basePath . '/vendor/laravel/framework/src/Illuminate/Cache',
// Encryption & Hashing
$basePath . '/vendor/laravel/framework/src/Illuminate/Encryption',
$basePath . '/vendor/laravel/framework/src/Illuminate/Hashing',
];
// Exclude test files and stubs
$excludePatterns = [
'/[Tt]est[s]?\.php$/',
'/[Ss]tub[s]?\.php$/',
'/[Ff]ixture[s]?/',
];
foreach ($laravelCoreDirs as $dir) {
preloadDirectory($dir, $excludePatterns);
}
// =============================================================================
// 4. LIVEWIRE (Critical for your app)
// =============================================================================
preloadDirectory($basePath . '/vendor/livewire/livewire/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/livewire/volt/src', $excludePatterns);
// =============================================================================
// 5. FILAMENT (Admin Panel - Critical for your app)
// =============================================================================
$filamentDirs = [
$basePath . '/vendor/filament/filament/src',
$basePath . '/vendor/filament/support/src',
$basePath . '/vendor/filament/forms/src',
$basePath . '/vendor/filament/tables/src',
$basePath . '/vendor/filament/actions/src',
$basePath . '/vendor/filament/infolists/src',
$basePath . '/vendor/filament/notifications/src',
$basePath . '/vendor/filament/widgets/src',
];
foreach ($filamentDirs as $dir) {
preloadDirectory($dir, $excludePatterns);
}
// =============================================================================
// 6. COMMON DEPENDENCIES
// =============================================================================
$commonDeps = [
// Symfony HTTP Foundation
$basePath . '/vendor/symfony/http-foundation/Request.php',
$basePath . '/vendor/symfony/http-foundation/Response.php',
$basePath . '/vendor/symfony/http-foundation/HeaderBag.php',
$basePath . '/vendor/symfony/http-foundation/ParameterBag.php',
$basePath . '/vendor/symfony/http-foundation/InputBag.php',
$basePath . '/vendor/symfony/http-foundation/FileBag.php',
$basePath . '/vendor/symfony/http-foundation/ServerBag.php',
$basePath . '/vendor/symfony/http-foundation/Cookie.php',
$basePath . '/vendor/symfony/http-foundation/Session/Session.php',
// Symfony HTTP Kernel
$basePath . '/vendor/symfony/http-kernel/HttpKernel.php',
// PSR Interfaces
$basePath . '/vendor/psr/container/src/ContainerInterface.php',
$basePath . '/vendor/psr/http-message/src/MessageInterface.php',
$basePath . '/vendor/psr/http-message/src/RequestInterface.php',
$basePath . '/vendor/psr/http-message/src/ResponseInterface.php',
$basePath . '/vendor/psr/log/src/LoggerInterface.php',
// Carbon (Date handling)
$basePath . '/vendor/nesbot/carbon/src/Carbon/Carbon.php',
$basePath . '/vendor/nesbot/carbon/src/Carbon/CarbonInterface.php',
$basePath . '/vendor/nesbot/carbon/src/Carbon/CarbonImmutable.php',
];
preloadFiles($commonDeps);
// =============================================================================
// 7. APPLICATION CODE (Your code)
// =============================================================================
$appDirs = [
// Models (Most frequently accessed)
$basePath . '/app/Models',
// HTTP Layer
$basePath . '/app/Http/Controllers',
$basePath . '/app/Http/Middleware',
$basePath . '/app/Http/Requests',
// Livewire Components
$basePath . '/app/Livewire',
// Filament Admin
$basePath . '/app/Admin/Resources',
$basePath . '/app/Admin/Pages',
$basePath . '/app/Admin/Widgets',
// Service Providers
$basePath . '/app/Providers',
// Jobs & Events
$basePath . '/app/Jobs',
$basePath . '/app/Events',
$basePath . '/app/Listeners',
// Helpers & Classes
$basePath . '/app/Classes',
$basePath . '/app/Helpers',
$basePath . '/app/Traits',
// Policies & Rules
$basePath . '/app/Policies',
$basePath . '/app/Rules',
];
foreach ($appDirs as $dir) {
preloadDirectory($dir);
}
// =============================================================================
// 8. BLADE COMPILED VIEWS (if using view caching)
// =============================================================================
// Only preload if compiled views exist and are recent
$compiledViewsPath = $basePath . '/storage/framework/views';
if (is_dir($compiledViewsPath)) {
// Limit to most recently modified compiled views (top 200)
$viewFiles = glob($compiledViewsPath . '/*.php');
if ($viewFiles) {
// Sort by modification time, newest first
usort($viewFiles, fn($a, $b) => filemtime($b) - filemtime($a));
$viewFiles = array_slice($viewFiles, 0, 200);
preloadFiles($viewFiles);
}
}
// =============================================================================
// SUMMARY (logged to error_log for debugging)
// =============================================================================
if (php_sapi_name() === 'cli') {
echo "OPcache Preload Complete: {$preloadedCount} files preloaded, {$skippedCount} skipped\n";
echo "Memory usage: " . round(memory_get_usage(true) / 1024 / 1024, 2) . " MB\n";
} else {
error_log("OPcache Preload: {$preloadedCount} files preloaded, {$skippedCount} skipped");
}