feat: enhance OPcache preload script with performance optimizations and detailed logging

This commit is contained in:
2025-12-21 07:49:48 -05:00
parent a5f3c904f6
commit 6e681b5c36

View File

@@ -1,297 +1,743 @@
<?php <?php
/** /**
* OPcache Preload Script for PHP 8.3-FPM * High-Performance OPcache Preload Script for PHP 8.3-FPM
* Optimized for Paymenter/VirtNet with Laravel 12, Filament 3, Livewire 3, Octane
* *
* Configure in php.ini: * Configure in php.ini or www.conf:
* opcache.preload=/path/to/preload.php * opcache.preload=/var/www/html/preload.php
* opcache.preload_user=www-data * opcache.preload_user=www-data
* opcache.memory_consumption=512
* opcache.interned_strings_buffer=128
* opcache.max_accelerated_files=50000
* opcache.validate_timestamps=0
* opcache.save_comments=1
* opcache.enable_file_override=1
* opcache.jit=1255
* opcache.jit_buffer_size=256M
* opcache.jit_hot_func=127
* opcache.jit_hot_loop=127
* opcache.jit_hot_return=8
* opcache.jit_hot_side_exit=8
* *
* Run after deployment: php artisan optimize && php artisan filament:optimize * After deployment run:
* php artisan optimize
* php artisan filament:optimize
* php artisan view:cache
* php artisan event:cache
* php artisan icons:cache
* sudo systemctl reload php8.3-fpm
*/ */
declare(strict_types=1); declare(strict_types=1);
// Ensure OPcache is available
if (!function_exists('opcache_compile_file')) {
die('OPcache extension is not loaded');
}
$basePath = __DIR__; $basePath = __DIR__;
$preloadedCount = 0;
$skippedCount = 0; // Performance tracking
$stats = [
'preloaded' => 0,
'skipped' => 0,
'errors' => [],
'start_time' => hrtime(true),
'start_memory' => memory_get_usage(true),
];
// =============================================================================
// PRELOAD FUNCTIONS
// =============================================================================
/** /**
* Compile a file into OPcache without executing it * Compile a single file into OPcache
* Returns true if successfully compiled
*/ */
function preloadFile(string $path): bool function preloadFile(string $path): bool
{ {
global $preloadedCount, $skippedCount; global $stats;
// Fast path checks
if (!is_file($path) || !is_readable($path)) { if (!is_file($path) || !is_readable($path)) {
return false; return false;
} }
// Skip empty files
if (filesize($path) === 0) {
return false;
}
try { try {
if (opcache_compile_file($path)) { if (@opcache_compile_file($path)) {
$preloadedCount++; $stats['preloaded']++;
return true; return true;
} }
} catch (Throwable $e) { } catch (Throwable $e) {
// Silently skip files that can't be preloaded (syntax errors, etc.) $stats['errors'][] = basename($path) . ': ' . $e->getMessage();
} }
$skippedCount++; $stats['skipped']++;
return false; return false;
} }
/** /**
* Recursively preload all PHP files in a directory * Preload files from array with existence check
*/ */
function preloadDirectory(string $dir, array $excludePatterns = []): void function preloadFiles(array $files): void
{ {
if (!is_dir($dir)) { foreach ($files as $file) {
preloadFile($file);
}
}
/**
* Recursively preload directory with filtering
*/
function preloadDirectory(string $dir, array $excludePatterns = [], int $maxDepth = 20): void
{
if (!is_dir($dir) || !is_readable($dir)) {
return; return;
} }
$iterator = new RecursiveIteratorIterator( $iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS), new RecursiveDirectoryIterator(
$dir,
FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS
),
RecursiveIteratorIterator::LEAVES_ONLY RecursiveIteratorIterator::LEAVES_ONLY
); );
$iterator->setMaxDepth($maxDepth);
$files = [];
foreach ($iterator as $file) { foreach ($iterator as $file) {
if (!$file->isFile() || $file->getExtension() !== 'php') { if (!$file->isFile() || $file->getExtension() !== 'php') {
continue; continue;
} }
$path = $file->getRealPath(); $path = $file->getRealPath();
if ($path === false) {
continue;
}
// Skip excluded patterns // Apply exclude patterns
$skip = false;
foreach ($excludePatterns as $pattern) { foreach ($excludePatterns as $pattern) {
if (preg_match($pattern, $path)) { if (preg_match($pattern, $path)) {
continue 2; $skip = true;
break;
} }
} }
if (!$skip) {
$files[] = $path;
}
}
// Sort for consistent ordering (helps with JIT optimization)
sort($files, SORT_STRING);
foreach ($files as $path) {
preloadFile($path); preloadFile($path);
} }
} }
/** /**
* Preload specific files from a list * Preload specific classes from a namespace (using Composer's classmap)
*/ */
function preloadFiles(array $files): void function preloadClassmap(string $classmapFile): void
{ {
foreach ($files as $file) { if (!is_file($classmapFile)) {
if (is_file($file)) { return;
preloadFile($file); }
}
$classmap = require $classmapFile;
if (!is_array($classmap)) {
return;
}
foreach ($classmap as $class => $file) {
preloadFile($file);
} }
} }
// Global exclusion patterns (tests, stubs, dev-only files)
$excludePatterns = [
'#[/\\\\][Tt]ests?[/\\\\]#',
'#[/\\\\][Ss]tubs?[/\\\\]#',
'#[/\\\\][Ff]ixtures?[/\\\\]#',
'#[/\\\\][Mm]ocks?[/\\\\]#',
'#[Tt]est\.php$#',
'#[Ss]tub\.php$#',
'#[Ss]pec\.php$#',
'#phpunit#i',
'#[/\\\\]\.#', // Hidden files/dirs
];
// ============================================================================= // =============================================================================
// 1. LARAVEL CACHED/COMPILED FILES (Most Critical) // PHASE 1: COMPOSER AUTOLOADER (Load First - Critical)
// ============================================================================= // =============================================================================
$cachedFiles = [ // Autoloader must be preloaded first for class resolution
$composerFiles = [
$basePath . '/vendor/composer/ClassLoader.php',
$basePath . '/vendor/composer/InstalledVersions.php',
$basePath . '/vendor/composer/autoload_real.php',
$basePath . '/vendor/composer/autoload_static.php',
$basePath . '/vendor/composer/autoload_classmap.php',
$basePath . '/vendor/composer/autoload_files.php',
$basePath . '/vendor/composer/autoload_namespaces.php',
$basePath . '/vendor/composer/autoload_psr4.php',
$basePath . '/vendor/autoload.php',
];
preloadFiles($composerFiles);
// Preload entire Composer classmap for maximum performance
if (is_file($basePath . '/vendor/composer/autoload_classmap.php')) {
preloadClassmap($basePath . '/vendor/composer/autoload_classmap.php');
}
// =============================================================================
// PHASE 2: LARAVEL CACHED FILES (High Priority)
// =============================================================================
$laravelCacheFiles = [
// Core cached files
$basePath . '/bootstrap/cache/packages.php', $basePath . '/bootstrap/cache/packages.php',
$basePath . '/bootstrap/cache/services.php', $basePath . '/bootstrap/cache/services.php',
$basePath . '/bootstrap/cache/config.php', $basePath . '/bootstrap/cache/config.php',
$basePath . '/bootstrap/cache/routes-v7.php', $basePath . '/bootstrap/cache/routes-v7.php',
$basePath . '/bootstrap/cache/events.php', $basePath . '/bootstrap/cache/events.php',
// Filament cache
$basePath . '/bootstrap/cache/filament.php', $basePath . '/bootstrap/cache/filament.php',
$basePath . '/bootstrap/cache/filament/panels.php',
// Livewire cache
$basePath . '/bootstrap/cache/livewire-components.php', $basePath . '/bootstrap/cache/livewire-components.php',
// Icons cache (Blade Icons)
$basePath . '/bootstrap/cache/blade-icons.php',
]; ];
preloadFiles($cachedFiles); preloadFiles($laravelCacheFiles);
// ============================================================================= // =============================================================================
// 2. COMPOSER AUTOLOADER (Essential for class resolution) // PHASE 3: PSR INTERFACES (Required for type resolution)
// ============================================================================= // =============================================================================
preloadFiles([ $psrDirs = [
$basePath . '/vendor/autoload.php', $basePath . '/vendor/psr/container/src',
$basePath . '/vendor/composer/autoload_real.php', $basePath . '/vendor/psr/http-message/src',
$basePath . '/vendor/composer/ClassLoader.php', $basePath . '/vendor/psr/http-client/src',
$basePath . '/vendor/composer/autoload_static.php', $basePath . '/vendor/psr/http-factory/src',
]); $basePath . '/vendor/psr/log/src',
$basePath . '/vendor/psr/cache/src',
$basePath . '/vendor/psr/simple-cache/src',
$basePath . '/vendor/psr/event-dispatcher/src',
$basePath . '/vendor/psr/clock/src',
];
foreach ($psrDirs as $dir) {
preloadDirectory($dir, $excludePatterns);
}
// ============================================================================= // =============================================================================
// 3. LARAVEL CORE FRAMEWORK // PHASE 4: SYMFONY COMPONENTS (Laravel's HTTP Foundation)
// ============================================================================= // =============================================================================
$laravelCoreDirs = [ $symfonyComponents = [
// Foundation & Core // HTTP Foundation (most critical)
$basePath . '/vendor/laravel/framework/src/Illuminate/Foundation', $basePath . '/vendor/symfony/http-foundation',
$basePath . '/vendor/laravel/framework/src/Illuminate/Container',
// HTTP Kernel
$basePath . '/vendor/symfony/http-kernel',
// Routing
$basePath . '/vendor/symfony/routing',
// Event Dispatcher
$basePath . '/vendor/symfony/event-dispatcher',
$basePath . '/vendor/symfony/event-dispatcher-contracts',
// Console (for Artisan commands)
$basePath . '/vendor/symfony/console',
// Error Handler
$basePath . '/vendor/symfony/error-handler',
// Finder
$basePath . '/vendor/symfony/finder',
// Process
$basePath . '/vendor/symfony/process',
// Service Contracts
$basePath . '/vendor/symfony/service-contracts',
// Translation
$basePath . '/vendor/symfony/translation',
$basePath . '/vendor/symfony/translation-contracts',
// Var Dumper (for debugging)
$basePath . '/vendor/symfony/var-dumper',
// Mime
$basePath . '/vendor/symfony/mime',
// Mailer
$basePath . '/vendor/symfony/mailer',
// String (Slugger, etc.)
$basePath . '/vendor/symfony/string',
// UID
$basePath . '/vendor/symfony/uid',
// Clock
$basePath . '/vendor/symfony/clock',
];
foreach ($symfonyComponents as $dir) {
preloadDirectory($dir, $excludePatterns, 10);
}
// =============================================================================
// PHASE 5: LARAVEL FRAMEWORK CORE
// =============================================================================
$laravelCore = [
// Contracts (interfaces - load first)
$basePath . '/vendor/laravel/framework/src/Illuminate/Contracts', $basePath . '/vendor/laravel/framework/src/Illuminate/Contracts',
// Container (DI)
$basePath . '/vendor/laravel/framework/src/Illuminate/Container',
// Foundation
$basePath . '/vendor/laravel/framework/src/Illuminate/Foundation',
// Support (helpers, traits, collections)
$basePath . '/vendor/laravel/framework/src/Illuminate/Support',
$basePath . '/vendor/laravel/framework/src/Illuminate/Collections',
$basePath . '/vendor/laravel/framework/src/Illuminate/Conditionable',
$basePath . '/vendor/laravel/framework/src/Illuminate/Macroable',
// HTTP Layer // HTTP Layer
$basePath . '/vendor/laravel/framework/src/Illuminate/Http', $basePath . '/vendor/laravel/framework/src/Illuminate/Http',
$basePath . '/vendor/laravel/framework/src/Illuminate/Routing', $basePath . '/vendor/laravel/framework/src/Illuminate/Routing',
$basePath . '/vendor/laravel/framework/src/Illuminate/Pipeline', $basePath . '/vendor/laravel/framework/src/Illuminate/Pipeline',
// Database & Eloquent // Database & Eloquent (critical for your app)
$basePath . '/vendor/laravel/framework/src/Illuminate/Database', $basePath . '/vendor/laravel/framework/src/Illuminate/Database',
// Support utilities // Auth
$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/Auth',
// Session & Cookie
$basePath . '/vendor/laravel/framework/src/Illuminate/Session', $basePath . '/vendor/laravel/framework/src/Illuminate/Session',
$basePath . '/vendor/laravel/framework/src/Illuminate/Cookie', $basePath . '/vendor/laravel/framework/src/Illuminate/Cookie',
// Cache
$basePath . '/vendor/laravel/framework/src/Illuminate/Cache',
// Events
$basePath . '/vendor/laravel/framework/src/Illuminate/Events',
// Queue
$basePath . '/vendor/laravel/framework/src/Illuminate/Queue',
// Validation
$basePath . '/vendor/laravel/framework/src/Illuminate/Validation',
// Views & Blade // Views & Blade
$basePath . '/vendor/laravel/framework/src/Illuminate/View', $basePath . '/vendor/laravel/framework/src/Illuminate/View',
// Events & Queue // Mail
$basePath . '/vendor/laravel/framework/src/Illuminate/Events', $basePath . '/vendor/laravel/framework/src/Illuminate/Mail',
$basePath . '/vendor/laravel/framework/src/Illuminate/Queue', $basePath . '/vendor/laravel/framework/src/Illuminate/Notifications',
// Validation & Cache
$basePath . '/vendor/laravel/framework/src/Illuminate/Validation',
$basePath . '/vendor/laravel/framework/src/Illuminate/Cache',
// Encryption & Hashing // Encryption & Hashing
$basePath . '/vendor/laravel/framework/src/Illuminate/Encryption', $basePath . '/vendor/laravel/framework/src/Illuminate/Encryption',
$basePath . '/vendor/laravel/framework/src/Illuminate/Hashing', $basePath . '/vendor/laravel/framework/src/Illuminate/Hashing',
// Filesystem
$basePath . '/vendor/laravel/framework/src/Illuminate/Filesystem',
// Console
$basePath . '/vendor/laravel/framework/src/Illuminate/Console',
// Log
$basePath . '/vendor/laravel/framework/src/Illuminate/Log',
// Config
$basePath . '/vendor/laravel/framework/src/Illuminate/Config',
// Translation
$basePath . '/vendor/laravel/framework/src/Illuminate/Translation',
// Pagination
$basePath . '/vendor/laravel/framework/src/Illuminate/Pagination',
// Bus (Commands)
$basePath . '/vendor/laravel/framework/src/Illuminate/Bus',
// Process
$basePath . '/vendor/laravel/framework/src/Illuminate/Process',
// Concurrency
$basePath . '/vendor/laravel/framework/src/Illuminate/Concurrency',
]; ];
// Exclude test files and stubs foreach ($laravelCore as $dir) {
$excludePatterns = [
'/[Tt]est[s]?\.php$/',
'/[Ss]tub[s]?\.php$/',
'/[Ff]ixture[s]?/',
];
foreach ($laravelCoreDirs as $dir) {
preloadDirectory($dir, $excludePatterns); preloadDirectory($dir, $excludePatterns);
} }
// ============================================================================= // =============================================================================
// 4. LIVEWIRE (Critical for your app) // PHASE 6: LARAVEL OCTANE (High Performance Server)
// =============================================================================
preloadDirectory($basePath . '/vendor/laravel/octane/src', $excludePatterns);
// =============================================================================
// PHASE 7: LARAVEL PASSPORT (API Authentication)
// =============================================================================
preloadDirectory($basePath . '/vendor/laravel/passport/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/league/oauth2-server/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/lcobucci/jwt/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/lcobucci/clock/src', $excludePatterns);
// =============================================================================
// PHASE 8: LIVEWIRE 3
// ============================================================================= // =============================================================================
preloadDirectory($basePath . '/vendor/livewire/livewire/src', $excludePatterns); preloadDirectory($basePath . '/vendor/livewire/livewire/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/livewire/volt/src', $excludePatterns); preloadDirectory($basePath . '/vendor/livewire/volt/src', $excludePatterns);
// ============================================================================= // =============================================================================
// 5. FILAMENT (Admin Panel - Critical for your app) // PHASE 9: FILAMENT 3 (Admin Panel)
// ============================================================================= // =============================================================================
$filamentDirs = [ $filamentPackages = [
// Core
$basePath . '/vendor/filament/filament/src', $basePath . '/vendor/filament/filament/src',
$basePath . '/vendor/filament/support/src', $basePath . '/vendor/filament/support/src',
// Components
$basePath . '/vendor/filament/forms/src', $basePath . '/vendor/filament/forms/src',
$basePath . '/vendor/filament/tables/src', $basePath . '/vendor/filament/tables/src',
$basePath . '/vendor/filament/actions/src', $basePath . '/vendor/filament/actions/src',
$basePath . '/vendor/filament/infolists/src', $basePath . '/vendor/filament/infolists/src',
$basePath . '/vendor/filament/notifications/src', $basePath . '/vendor/filament/notifications/src',
$basePath . '/vendor/filament/widgets/src', $basePath . '/vendor/filament/widgets/src',
// Spatie integration
$basePath . '/vendor/filament/spatie-laravel-media-library-plugin/src',
$basePath . '/vendor/filament/spatie-laravel-settings-plugin/src',
$basePath . '/vendor/filament/spatie-laravel-tags-plugin/src',
$basePath . '/vendor/filament/spatie-laravel-translatable-plugin/src',
]; ];
foreach ($filamentDirs as $dir) { foreach ($filamentPackages as $dir) {
preloadDirectory($dir, $excludePatterns); preloadDirectory($dir, $excludePatterns);
} }
// ============================================================================= // =============================================================================
// 6. COMMON DEPENDENCIES // PHASE 10: BLADE ICONS (Multiple icon sets you're using)
// ============================================================================= // =============================================================================
$commonDeps = [ $bladeIconPackages = [
// Symfony HTTP Foundation $basePath . '/vendor/blade-ui-kit/blade-icons/src',
$basePath . '/vendor/symfony/http-foundation/Request.php', $basePath . '/vendor/blade-ui-kit/blade-heroicons/src',
$basePath . '/vendor/symfony/http-foundation/Response.php', $basePath . '/vendor/andreiio/blade-remix-icon/src',
$basePath . '/vendor/symfony/http-foundation/HeaderBag.php', $basePath . '/vendor/codeat3/blade-coolicons/src',
$basePath . '/vendor/symfony/http-foundation/ParameterBag.php', $basePath . '/vendor/codeat3/blade-devicons/src',
$basePath . '/vendor/symfony/http-foundation/InputBag.php', $basePath . '/vendor/codeat3/blade-file-icons/src',
$basePath . '/vendor/symfony/http-foundation/FileBag.php', $basePath . '/vendor/codeat3/blade-vaadin-icons/src',
$basePath . '/vendor/symfony/http-foundation/ServerBag.php', $basePath . '/vendor/faisal50x/blade-ionicons/src',
$basePath . '/vendor/symfony/http-foundation/Cookie.php', $basePath . '/vendor/postare/blade-mdi/src',
$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); foreach ($bladeIconPackages as $dir) {
preloadDirectory($dir, $excludePatterns);
}
// ============================================================================= // =============================================================================
// 7. APPLICATION CODE (Your code) // PHASE 11: SPATIE PACKAGES
// ============================================================================= // =============================================================================
$appDirs = [ $spatiePackages = [
// Models (Most frequently accessed) $basePath . '/vendor/spatie/laravel-cookie-consent/src',
$basePath . '/app/Models', $basePath . '/vendor/spatie/laravel-query-builder/src',
$basePath . '/vendor/spatie/laravel-package-tools/src',
];
foreach ($spatiePackages as $dir) {
preloadDirectory($dir, $excludePatterns);
}
// =============================================================================
// PHASE 12: OTHER CRITICAL DEPENDENCIES
// =============================================================================
// Carbon (DateTime handling)
preloadDirectory($basePath . '/vendor/nesbot/carbon/src', $excludePatterns);
// Monolog (Logging)
preloadDirectory($basePath . '/vendor/monolog/monolog/src', $excludePatterns);
// Flysystem (File storage)
preloadDirectory($basePath . '/vendor/league/flysystem/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/league/flysystem-local/src', $excludePatterns);
// Guzzle HTTP (API calls)
preloadDirectory($basePath . '/vendor/guzzlehttp/guzzle/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/guzzlehttp/psr7/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/guzzlehttp/promises/src', $excludePatterns);
// DomPDF (PDF generation)
preloadDirectory($basePath . '/vendor/barryvdh/laravel-dompdf/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/dompdf/dompdf/src', $excludePatterns);
// QR Code
preloadDirectory($basePath . '/vendor/endroid/qr-code/src', $excludePatterns);
// Two Factor Auth
preloadFile($basePath . '/vendor/robthree/twofactorauth/lib/TwoFactorAuth.php');
preloadDirectory($basePath . '/vendor/robthree/twofactorauth/lib', $excludePatterns);
// Laravel Socialite (Social auth)
preloadDirectory($basePath . '/vendor/laravel/socialite/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/socialiteproviders/discord/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/socialiteproviders/manager/src', $excludePatterns);
// ApexCharts
preloadDirectory($basePath . '/vendor/akaunting/laravel-apexcharts/src', $excludePatterns);
// Laravel Trend
preloadDirectory($basePath . '/vendor/flowframe/laravel-trend/src', $excludePatterns);
// Laravel Themer
preloadDirectory($basePath . '/vendor/qirolab/laravel-themer/src', $excludePatterns);
// JSON API
preloadDirectory($basePath . '/vendor/timacdonald/json-api/src', $excludePatterns);
// Cookie Consent
preloadDirectory($basePath . '/vendor/whitecube/laravel-cookie-consent/src', $excludePatterns);
// Ramsey UUID
preloadDirectory($basePath . '/vendor/ramsey/uuid/src', $excludePatterns);
preloadDirectory($basePath . '/vendor/ramsey/collection/src', $excludePatterns);
// Doctrine (DBAL for migrations, Inflector for pluralization)
preloadDirectory($basePath . '/vendor/doctrine/inflector/lib', $excludePatterns);
preloadDirectory($basePath . '/vendor/doctrine/lexer/src', $excludePatterns);
// Vite manifest helper
preloadDirectory($basePath . '/vendor/laravel/framework/src/Illuminate/Foundation/Vite', $excludePatterns);
// =============================================================================
// PHASE 13: APPLICATION CODE (Your Code - Highest Priority)
// =============================================================================
// Models (most frequently accessed)
$modelFiles = [
$basePath . '/app/Models/User.php',
$basePath . '/app/Models/Service.php',
$basePath . '/app/Models/Product.php',
$basePath . '/app/Models/Invoice.php',
$basePath . '/app/Models/InvoiceItem.php',
$basePath . '/app/Models/InvoiceTransaction.php',
$basePath . '/app/Models/Order.php',
$basePath . '/app/Models/Ticket.php',
$basePath . '/app/Models/TicketMessage.php',
$basePath . '/app/Models/Gateway.php',
$basePath . '/app/Models/Server.php',
$basePath . '/app/Models/Category.php',
$basePath . '/app/Models/Price.php',
$basePath . '/app/Models/Plan.php',
$basePath . '/app/Models/ConfigOption.php',
$basePath . '/app/Models/Coupon.php',
$basePath . '/app/Models/Property.php',
$basePath . '/app/Models/Extension.php',
$basePath . '/app/Models/Currency.php',
$basePath . '/app/Models/Setting.php',
$basePath . '/app/Models/Session.php',
$basePath . '/app/Models/Role.php',
$basePath . '/app/Models/ServiceConfig.php',
$basePath . '/app/Models/ServiceCancellation.php',
$basePath . '/app/Models/ServiceUpgrade.php',
$basePath . '/app/Models/TaxRate.php',
$basePath . '/app/Models/EmailTemplate.php',
$basePath . '/app/Models/Credit.php',
$basePath . '/app/Models/ApiKey.php',
$basePath . '/app/Models/AuditLog.php',
];
preloadFiles($modelFiles);
// Preload remaining models
preloadDirectory($basePath . '/app/Models', $excludePatterns);
// Core application directories
$appDirectories = [
// HTTP Layer // HTTP Layer
$basePath . '/app/Http/Controllers', $basePath . '/app/Http/Controllers',
$basePath . '/app/Http/Middleware', $basePath . '/app/Http/Middleware',
$basePath . '/app/Http/Requests', $basePath . '/app/Http/Requests',
// Livewire Components // Livewire Components (critical for UI)
$basePath . '/app/Livewire', $basePath . '/app/Livewire',
// Filament Admin // Filament Admin Panel
$basePath . '/app/Admin/Resources', $basePath . '/app/Admin/Resources',
$basePath . '/app/Admin/Pages', $basePath . '/app/Admin/Pages',
$basePath . '/app/Admin/Widgets', $basePath . '/app/Admin/Widgets',
$basePath . '/app/Admin/Components',
$basePath . '/app/Admin/Actions',
$basePath . '/app/Admin/Clusters',
// Service Providers // Service Providers
$basePath . '/app/Providers', $basePath . '/app/Providers',
// Jobs & Events // Background Jobs
$basePath . '/app/Jobs', $basePath . '/app/Jobs',
// Events & Listeners
$basePath . '/app/Events', $basePath . '/app/Events',
$basePath . '/app/Listeners', $basePath . '/app/Listeners',
// Helpers & Classes // Observers
$basePath . '/app/Observers',
// Policies
$basePath . '/app/Policies',
// Classes & Helpers
$basePath . '/app/Classes', $basePath . '/app/Classes',
$basePath . '/app/Helpers', $basePath . '/app/Helpers',
$basePath . '/app/Support',
$basePath . '/app/Traits', $basePath . '/app/Traits',
// Policies & Rules // Validation Rules
$basePath . '/app/Policies',
$basePath . '/app/Rules', $basePath . '/app/Rules',
// Mail
$basePath . '/app/Mail',
// View Components
$basePath . '/app/View',
// Attributes
$basePath . '/app/Attributes',
// Exceptions
$basePath . '/app/Exceptions',
// Console Commands
$basePath . '/app/Console/Commands',
]; ];
foreach ($appDirs as $dir) { foreach ($appDirectories as $dir) {
preloadDirectory($dir); preloadDirectory($dir, $excludePatterns);
} }
// ============================================================================= // =============================================================================
// 8. BLADE COMPILED VIEWS (if using view caching) // PHASE 14: EXTENSIONS (Payment Gateways, Servers, etc.)
// =============================================================================
$extensionDirs = [
$basePath . '/extensions/Gateways',
$basePath . '/extensions/Servers',
$basePath . '/extensions/Others',
];
foreach ($extensionDirs as $dir) {
preloadDirectory($dir, $excludePatterns);
}
// =============================================================================
// PHASE 15: THEMES
// =============================================================================
preloadDirectory($basePath . '/themes/lucentui', $excludePatterns);
// =============================================================================
// PHASE 16: COMPILED BLADE VIEWS (Most Recent)
// ============================================================================= // =============================================================================
// Only preload if compiled views exist and are recent
$compiledViewsPath = $basePath . '/storage/framework/views'; $compiledViewsPath = $basePath . '/storage/framework/views';
if (is_dir($compiledViewsPath)) { if (is_dir($compiledViewsPath)) {
// Limit to most recently modified compiled views (top 200)
$viewFiles = glob($compiledViewsPath . '/*.php'); $viewFiles = glob($compiledViewsPath . '/*.php');
if ($viewFiles) { if ($viewFiles) {
// Sort by modification time, newest first // Sort by modification time, newest first
usort($viewFiles, fn($a, $b) => filemtime($b) - filemtime($a)); usort($viewFiles, static fn($a, $b) => filemtime($b) <=> filemtime($a));
$viewFiles = array_slice($viewFiles, 0, 200); // Preload top 500 most recently used views
$viewFiles = array_slice($viewFiles, 0, 500);
preloadFiles($viewFiles); preloadFiles($viewFiles);
} }
} }
// ============================================================================= // =============================================================================
// SUMMARY (logged to error_log for debugging) // PHASE 17: CONFIG FILES
// ============================================================================= // =============================================================================
if (php_sapi_name() === 'cli') { preloadDirectory($basePath . '/config', $excludePatterns);
echo "OPcache Preload Complete: {$preloadedCount} files preloaded, {$skippedCount} skipped\n"; preloadFile($basePath . '/bootstrap/app.php');
echo "Memory usage: " . round(memory_get_usage(true) / 1024 / 1024, 2) . " MB\n"; preloadFile($basePath . '/bootstrap/providers.php');
// =============================================================================
// PRELOAD SUMMARY & LOGGING
// =============================================================================
$stats['end_time'] = hrtime(true);
$stats['end_memory'] = memory_get_usage(true);
$duration = round(($stats['end_time'] - $stats['start_time']) / 1e6, 2); // ms
$memoryUsed = round(($stats['end_memory'] - $stats['start_memory']) / 1024 / 1024, 2); // MB
$totalMemory = round($stats['end_memory'] / 1024 / 1024, 2); // MB
$summary = sprintf(
'OPcache Preload: %d files preloaded, %d skipped in %.2fms (Memory: %.2fMB used, %.2fMB total)',
$stats['preloaded'],
$stats['skipped'],
$duration,
$memoryUsed,
$totalMemory
);
// Log summary
if (PHP_SAPI === 'cli') {
echo $summary . PHP_EOL;
if (!empty($stats['errors'])) {
echo "Errors (" . count($stats['errors']) . "):\n";
foreach (array_slice($stats['errors'], 0, 10) as $error) {
echo " - {$error}\n";
}
if (count($stats['errors']) > 10) {
echo " ... and " . (count($stats['errors']) - 10) . " more errors\n";
}
}
// Show OPcache status
if (function_exists('opcache_get_status')) {
$status = opcache_get_status(false);
if ($status) {
echo sprintf(
"OPcache Status: %d cached scripts, %.2fMB memory used, %.2f%% hit rate\n",
$status['opcache_statistics']['num_cached_scripts'] ?? 0,
($status['memory_usage']['used_memory'] ?? 0) / 1024 / 1024,
$status['opcache_statistics']['opcache_hit_rate'] ?? 0
);
}
}
} else { } else {
error_log("OPcache Preload: {$preloadedCount} files preloaded, {$skippedCount} skipped"); error_log($summary);
} }
// Force garbage collection to free memory
gc_collect_cycles();