From 104355a35ee46a1305df2dd8f4d7b1dec4434fff Mon Sep 17 00:00:00 2001 From: Dimitri Sitchet Tomkeu Date: Wed, 19 Mar 2025 18:11:11 +0100 Subject: [PATCH 1/3] =?UTF-8?q?feat=20:=20param=C3=A8tres=20opcache=20supp?= =?UTF-8?q?l=C3=A9mentaires=20dans=20la=20v=C3=A9rification=20de=20php.ini?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Cli/Commands/Utilities/PhpIniCheck.php | 25 +++++++++++++- src/Cli/Console/Command.php | 12 +++++++ src/Security/CheckPhpIni.php | 39 ++++++++++++++++------ 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/Cli/Commands/Utilities/PhpIniCheck.php b/src/Cli/Commands/Utilities/PhpIniCheck.php index ae128229..f37dbf47 100644 --- a/src/Cli/Commands/Utilities/PhpIniCheck.php +++ b/src/Cli/Commands/Utilities/PhpIniCheck.php @@ -36,13 +36,36 @@ final class PhpIniCheck extends Command protected $service = 'Service de configuration'; + protected $arguments = [ + 'opcache' => 'Vérifier les valeurs détaillées de l\'opcache dans l\'environnement de production.', + ]; + /** * {@inheritDoc} */ public function execute(array $params) { + unset($params['help'], $params['version'], $params['verbosity']); + $params = array_values($params); + + if (isset($params[0]) && ! in_array($params[0], array_keys($this->arguments), true)) { + $this->fail('Vous devez indiquer un argument correct.')->eol(); + $this->fail(' Example: phpini:check opcache')->eol(); + $this->fail('Arguments:')->eol(); + + $length = max(array_map(strlen(...), array_keys($this->arguments))); + + foreach ($this->arguments as $argument => $description) { + $this->write($this->color->ok($this->pad($argument, $length, 2, 2)) . $description)->eol(); + } + + return EXIT_ERROR; + } + + $argument = $params[0] ?? null; + /** @var array $data */ - $data = CheckPhpIni::run(); + $data = CheckPhpIni::run(argument: $argument); $this->table($data); diff --git a/src/Cli/Console/Command.php b/src/Cli/Console/Command.php index 2fcf849a..861b9dc6 100644 --- a/src/Cli/Console/Command.php +++ b/src/Cli/Console/Command.php @@ -629,6 +629,18 @@ final public function center(string $text, array $options = []): self return $this->write($repeater . ' ' . $text . ' ' . $repeater)->eol(); } + /** + * La chaîne de caractères est remplacée par des titres de la même longueur pour que les descriptions soient bien alignées. + * + * @param int $extra Nombre d'espaces supplémentaires à ajouter à la fin + */ + public function pad(string $item, int $max, int $extra = 2, int $indent = 0): string + { + $max += $extra + $indent; + + return str_pad(str_repeat(' ', $indent) . $item, $max); + } + /** * Facilite l'accès à nos propriétés protégées. * diff --git a/src/Security/CheckPhpIni.php b/src/Security/CheckPhpIni.php index 71afd596..d2fdd8be 100644 --- a/src/Security/CheckPhpIni.php +++ b/src/Security/CheckPhpIni.php @@ -21,13 +21,13 @@ class CheckPhpIni { /** - * @param bool $isCli Set false if you run via Web + * @param bool $isCli Defini a `false` s'il est exécuté via le Web * - * @return array|string HTML string or array in CLI + * @return array|string chaine HTML sur le web ou tableau en CLI */ - public static function run(bool $isCli = true) + public static function run(bool $isCli = true, ?string $argument = null) { - $output = static::checkIni(); + $output = static::checkIni($argument); $thead = ['Directive', 'Globale', 'Actuelle', 'Recommandation', 'Remarque']; $tbody = []; @@ -116,9 +116,9 @@ private static function outputForWeb(array $output, array $thead, array $tbody): } /** - * @internal Used for testing purposes only. + * @internal Utilisé uniquement à des fins de test. */ - public static function checkIni(): array + public static function checkIni(?string $argument = null): array { $items = [ 'error_reporting' => ['recommended' => '5111'], @@ -131,18 +131,37 @@ public static function checkIni(): array 'memory_limit' => ['remark' => '> post_max_size'], 'post_max_size' => ['remark' => '> upload_max_filesize'], 'upload_max_filesize' => ['remark' => '< post_max_size'], - 'max_input_vars' => ['remark' => 'The default is 1000.'], + 'max_input_vars' => ['remark' => 'La valeur par défaut est 1000.'], 'request_order' => ['recommended' => 'GP'], 'variables_order' => ['recommended' => 'GPCS'], 'date.timezone' => ['recommended' => 'UTC'], 'mbstring.language' => ['recommended' => 'neutral'], 'opcache.enable' => ['recommended' => '1'], - 'opcache.enable_cli' => [], - 'opcache.jit' => [], - 'opcache.jit_buffer_size' => [], + 'opcache.enable_cli' => ['recommended' => '0', 'remark' => 'Activer lorsque vous utilisez des files d\'attente ou que vous exécutez des tâches CLI répétitives'], + 'opcache.jit' => ['recommended' => 'tracing'], + 'opcache.jit_buffer_size' => ['recommended' => '128', 'remark' => 'Ajustez avec votre espace mémoire libre'], 'zend.assertions' => ['recommended' => '-1'], ]; + if ($argument === 'opcache') { + $items = [ + 'opcache.enable' => ['recommended' => '1'], + 'opcache.enable_cli' => ['recommended' => '0', 'remark' => 'Activer lorsque vous utilisez des files d\'attente ou que vous exécutez des tâches CLI répétitives'], + 'opcache.jit' => ['recommended' => 'tracing', 'remark' => 'Désactiver lorsque vous utilisez des extensions tierces'], + 'opcache.jit_buffer_size' => ['recommended' => '128', 'remark' => 'Ajustez avec votre espace mémoire libre'], + 'opcache.memory_consumption' => ['recommended' => '128', 'remark' => 'Ajustez avec votre espace mémoire libre'], + 'opcache.interned_strings_buffer' => ['recommended' => '16'], + 'opcache.max_accelerated_files' => ['remark' => 'Ajuster en fonction du nombre de fichiers PHP dans votre projet (par exemple : find your_project/ -iname \'*.php\'|wc -l)'], + 'opcache.max_wasted_percentage' => ['recommended' => '10'], + 'opcache.validate_timestamps' => ['recommended' => '0', 'remark' => 'Lorsque vous le désactivez, opcache conserve votre code dans la mémoire partagée. Le redémarrage du serveur web est nécessaire'], + 'opcache.revalidate_freq' => [], + 'opcache.file_cache' => ['remark' => 'Mise en cache du fichier de localisation, ce qui devrait améliorer les performances lorsque la mémoire du SHM est pleine.'], + 'opcache.file_cache_only' => ['remark' => 'Mise en cache du code optique dans la mémoire partagée, désactivée lorsque vous utilisez Windows'], + 'opcache.file_cache_fallback' => ['remark' => 'Activer lorsque vous utilisez Windows'], + 'opcache.save_comments' => ['recommended' => '0', 'remark' => 'Activé lorsque vous utilisez l\'annotation docblock `package require`'], + ]; + } + $output = []; $ini = ini_get_all(); From d8e84089f53cf9f20f381a28a6ec5d0fb845ce41 Mon Sep 17 00:00:00 2001 From: Dimitri Sitchet Tomkeu Date: Wed, 19 Mar 2025 18:11:52 +0100 Subject: [PATCH 2/3] test: ajout de test pour PhpIniCheck --- .../Cli/Commands/PhpIniCheck.spec.php | 56 ++++++++++++++++++ .../framework/Security/CheckPhpIni.spec.php | 59 +++++++++++++++++++ src/Cli/Commands/Utilities/PhpIniCheck.php | 2 +- 3 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 spec/system/framework/Cli/Commands/PhpIniCheck.spec.php create mode 100644 spec/system/framework/Security/CheckPhpIni.spec.php diff --git a/spec/system/framework/Cli/Commands/PhpIniCheck.spec.php b/spec/system/framework/Cli/Commands/PhpIniCheck.spec.php new file mode 100644 index 00000000..1d611e2d --- /dev/null +++ b/spec/system/framework/Cli/Commands/PhpIniCheck.spec.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +use BlitzPHP\Spec\CliOutputHelper as COH; + +use function Kahlan\expect; + +describe('Commandes / PhpIniCheck', function (): void { + beforeEach(function (): void { + COH::setUp(); + }); + + afterEach(function (): void { + COH::tearDown(); + }); + + beforeAll(function (): void { + COH::setUpBeforeClass(); + }); + + afterAll(function (): void { + COH::tearDownAfterClass(); + }); + + it('phpini:check', function (): void { + command('phpini:check'); + + $result = COH::buffer(); + + expect($result)->toMatch(static fn ($actual) => str_contains($actual, 'Directive')); + expect($result)->toMatch(static fn ($actual) => str_contains($actual, 'Globale')); + expect($result)->toMatch(static fn ($actual) => str_contains($actual, 'Actuelle')); + expect($result)->toMatch(static fn ($actual) => str_contains($actual, 'Recommandation')); + expect($result)->toMatch(static fn ($actual) => str_contains($actual, 'Remarque')); + }); + + it('phpini:check opcache', function (): void { + command('phpini:check opcache'); + + expect(COH::buffer())->toMatch(static fn ($actual) => str_contains($actual, 'opcache.save_comments')); + }); + + it('phpini:check avec un argument non valide', function (): void { + command('phpini:check unknown'); + + expect(COH::buffer())->toMatch(static fn ($actual) => str_contains($actual, 'Vous devez indiquer un argument correct.')); + }); +}); diff --git a/spec/system/framework/Security/CheckPhpIni.spec.php b/spec/system/framework/Security/CheckPhpIni.spec.php new file mode 100644 index 00000000..e5b89d4f --- /dev/null +++ b/spec/system/framework/Security/CheckPhpIni.spec.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +use BlitzPHP\Security\CheckPhpIni; + +use function Kahlan\expect; + +describe('Security / CheckPhpIni', function (): void { + beforeAll(function(): void { + $ini = ini_get_all(); + + $this->display_errors = $ini['display_errors'] ?? ['global_value' => 'disabled', 'local_value' => 'disabled']; + $this->opcache = $ini['opcache'] ?? ['global_value' => 'disabled', 'local_value' => 'disabled']; + }); + + it('Check ini', function (): void { + $output = CheckPhpIni::checkIni(); + + expect($output['display_errors'])->toBe([ + 'global' => $this->display_errors['global_value'], + 'current' => $this->display_errors['local_value'], + 'recommended' => '0', + 'remark' => '', + ]); + }); + + it('Check opcache', function (): void { + $output = CheckPhpIni::checkIni('opcache'); + + expect($output['opcache.save_comments'])->toBe([ + 'global' => $this->opcache['global_value'], + 'current' => $this->opcache['local_value'], + 'recommended' => '0', + 'remark' => 'Activé lorsque vous utilisez l\'annotation docblock `package require`', + ]); + }); + + it('Run web', function (): void { + $output = CheckPhpIni::run(false); + + $expected = [ + 'global' => '1', + 'current' => '1', + 'recommended' => '0', + 'remark' => 'Enable when you using package require docblock annotation', + ]; + + expect($output)->toBeA('string'); + // expect(str_contains($output, 'display_errors'))->toBeTruthy(); + }); +}); diff --git a/src/Cli/Commands/Utilities/PhpIniCheck.php b/src/Cli/Commands/Utilities/PhpIniCheck.php index f37dbf47..049707dd 100644 --- a/src/Cli/Commands/Utilities/PhpIniCheck.php +++ b/src/Cli/Commands/Utilities/PhpIniCheck.php @@ -46,7 +46,7 @@ final class PhpIniCheck extends Command public function execute(array $params) { unset($params['help'], $params['version'], $params['verbosity']); - $params = array_values($params); + $params = array_values(array_filter($params)); if (isset($params[0]) && ! in_array($params[0], array_keys($this->arguments), true)) { $this->fail('Vous devez indiquer un argument correct.')->eol(); From 430a7472d7b090c53ede080ea22b24e790421b3a Mon Sep 17 00:00:00 2001 From: dimtrovich <37987162+dimtrovich@users.noreply.github.com> Date: Wed, 19 Mar 2025 17:20:47 +0000 Subject: [PATCH 3/3] Fix styling --- src/Cli/Commands/Utilities/PhpIniCheck.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Cli/Commands/Utilities/PhpIniCheck.php b/src/Cli/Commands/Utilities/PhpIniCheck.php index 049707dd..e1e13e16 100644 --- a/src/Cli/Commands/Utilities/PhpIniCheck.php +++ b/src/Cli/Commands/Utilities/PhpIniCheck.php @@ -34,8 +34,7 @@ final class PhpIniCheck extends Command */ protected $description = 'Vérifiez les valeurs de votre php.ini dans l\'environnement de production.'; - protected $service = 'Service de configuration'; - + protected $service = 'Service de configuration'; protected $arguments = [ 'opcache' => 'Vérifier les valeurs détaillées de l\'opcache dans l\'environnement de production.', ];