#!/usr/bin/env php ou "KEY" => preg_match_all('/[\'"]([A-Z0-9_]+)[\'"]\s*=>/i', $content, $matches); $keys = $matches[1] ?? []; sort($keys); return array_unique($keys); } /** * Logique de logging */ function log_audit($level, $event, $msg) { echo sprintf("[%s] %s: %s\n", strtoupper($level), $event, $msg); } function check_config_drift() { $found_issue = false; $reviewed_files = 0; $files_requiring_action = 0; log_audit('info', 'audit_start', "Début de l'audit des configurations PHP"); // On cherche les fichiers .php qui ne sont pas des .local.php $base_files = glob(CONF_DIR . '/*.php'); $base_files = array_filter($base_files, function($f) { return !str_ends_with($f, '.local.php'); }); foreach ($base_files as $base_conf) { $reviewed_files++; $base_name = basename($base_conf); $local_conf = str_replace('.php', '.local.php', $base_conf); $local_name = basename($local_conf); // 1. Si le fichier local n'existe pas if (!file_exists($local_conf)) { if (copy($base_conf, $local_conf)) { chmod($local_conf, 0600); log_audit('notice', 'audit_missing_local', "Le fichier $local_name a été créé par copie de $base_name"); } else { log_audit('error', 'audit_create_local_failed', "Impossible de créer $local_name"); $found_issue = true; $files_requiring_action++; } continue; } // 2. Comparaison des clés $keys_base = extract_keys($base_conf); $keys_local = extract_keys($local_conf); $missing = array_diff($keys_base, $keys_local); // Présent dans base mais pas local $obsolete = array_diff($keys_local, $keys_base); // Présent dans local mais plus dans base if (!empty($missing) || !empty($obsolete)) { $found_issue = true; $files_requiring_action++; log_audit('warning', 'audit_file_requires_action', "Vérification requise pour $local_name"); if (!empty($missing)) { log_audit('warning', 'audit_keys_missing', "Options absentes de $local_name : " . implode(', ', $missing)); } if (!empty($obsolete)) { log_audit('info', 'audit_keys_obsolete', "Options obsolètes ou personnalisées dans $local_name : " . implode(', ', $obsolete)); } } else { log_audit('info', 'audit_file_ok', "Le fichier $local_name est synchronisé avec $base_name"); } } // Résumé final if (!$found_issue) { log_audit('info', 'audit_success', "Toutes les configurations sont à jour ($reviewed_files fichiers vérifiés)"); } else { log_audit('warning', 'audit_requires_action', "Action requise sur $files_requiring_action fichier(s) sur $reviewed_files"); } } // --- Main --- check_config_drift();