Ce fichier sert de carte rapide pour tout agent qui reprend ce projet. Lis-le avant de modifier le code, puis verifie les fichiers concernes localement : ce guide resume l'etat actuel du depot, il ne remplace pas la lecture du code.
PHP Optimizer est un outil Python qui analyse du code PHP et produit des rapports console, JSON ou HTML. Le paquet principal est phpoptimizer, l'entree CLI est phpoptimizer.cli:main, et l'analyse courante passe par SimpleAnalyzer.
Le flux principal est :
src/phpoptimizer/cli.pycollecte les options Click et les fichiers.php.src/phpoptimizer/config.pyconstruit la configuration, les regles, categories, poids et filtres.src/phpoptimizer/simple_analyzer.pylit le fichier PHP, appelle chaque analyseur specialise, filtre et deduplique les issues.src/phpoptimizer/reporter.pyrend les resultats en console, JSON ou HTML.
Commandes utiles depuis la racine du depot :
python -m venv venv
.\venv\Scripts\Activate.ps1
pip install -r requirements.txt
pip install -e .Dependances principales :
clickpour le CLI.coloramapour les couleurs console Windows.phplypour le parsing PHP historique.dataclassesettyping-extensionspour compatibilite.
Le paquet declare Python >=3.8 dans setup.py.
Tests complets :
python -m pytest tests/Tests cibles :
python -m pytest tests/test_analyzer.py -v
python -m pytest tests/test_dynamic_calls_analyzer.py -v
python -m pytest tests/test_type_hint_analyzer.py -v
python -m pytest tests/test_type_hint_versions.py -vExecution CLI en mode module :
python -m phpoptimizer analyze examples/example.php --verbose
python -m phpoptimizer analyze examples/ --recursive --output-format json --output report.json
python -m phpoptimizer analyze examples/type_hints_example.php --php-version 8.2 --verboseApres pip install -e ., la commande console declaree est :
phpoptimizer analyze examples/example.php --verboseGenerer une configuration par defaut :
python -m phpoptimizer init-config example_config.jsonsrc/phpoptimizer/cli.py: commandes Clickanalyze,version,init-config.src/phpoptimizer/config.py:Config,RuleConfig,RuleCategory,SeverityWeight, regles par defaut.src/phpoptimizer/simple_analyzer.py: orchestrateur des analyseurs specialises.src/phpoptimizer/analyzers/base_analyzer.py: contrat commun et helper_create_issue.src/phpoptimizer/analyzers/*.py: detections specialisees.src/phpoptimizer/reporter.py: generation console, JSON, HTML.src/phpoptimizer/suggestions.py: suggestions detaillees associees auxrule_name.src/phpoptimizer/parser.pyetsrc/phpoptimizer/analyzer.py: ancien systeme/parser, encore expose par__init__.py.src/phpoptimizer/rules/: ancien ou futur systeme de regles modulaires ; ne pas supposer qu'il pilote le flux principal actuel.tests/: tests unitairesunittestexecutes viapytest.examples/: exemples PHP pour essais manuels.README.md,README_FR.md,CATEGORIES_GUIDE.md,CONTRIBUTING.md: documentation utilisateur et contribution.
SimpleAnalyzer instancie ces analyseurs dans cet ordre :
LoopAnalyzerSecurityAnalyzerErrorAnalyzerPerformanceAnalyzerMemoryAnalyzerCodeQualityAnalyzerDeadCodeAnalyzerDynamicCallsAnalyzerTypeHintAnalyzer
Chaque analyseur herite de BaseAnalyzer et implemente :
def analyze(self, content: str, file_path: Path, lines: List[str]) -> List[Dict[str, Any]]:
...Les issues doivent suivre le format cree par _create_issue :
{
"rule_name": "...",
"message": "...",
"file_path": "...",
"line": 1,
"column": 0,
"severity": "info|warning|error",
"issue_type": "security|performance|error|...",
"suggestion": "...",
"code_snippet": "..."
}Important : SimpleAnalyzer appelle ensuite config.should_apply_rule(rule_name). Une issue dont le rule_name n'est pas declare dans Config._init_default_rules() sera filtree par defaut. Quand tu ajoutes une nouvelle detection, ajoute aussi sa configuration.
Les categories connues sont dans RuleCategory :
securityerrorperformance.criticalperformance.generalmemorycode_qualitypsr
Les poids sont dans SeverityWeight :
4: critique, surtout securite.3: eleve, erreurs ou performance majeure.2: moyen, optimisations importantes.1: faible, qualite de code.0: tres faible, formatage et conventions.
Le CLI expose les filtres :
--include-rules
--exclude-rules
--include-categories
--exclude-categories
--min-weight
--php-versionAvant de changer ce systeme, lire CATEGORIES_GUIDE.md et les tests associes.
Procedure recommandee :
- Choisir l'analyseur specialise existant le plus proche, ou creer un fichier dans
src/phpoptimizer/analyzers/si la responsabilite est nouvelle. - Utiliser
_create_issue(...)plutot qu'un dictionnaire ad hoc, sauf si le fichier suit deja un motif local precis. - Ajouter le
rule_namedansConfig._init_default_rules()avec categorie, severite, poids et parametres. - Si l'analyseur est nouveau, l'importer dans
src/phpoptimizer/analyzers/__init__.pyet l'ajouter aSimpleAnalyzer.analyzers. - Ajouter ou ajuster les suggestions detaillees dans
src/phpoptimizer/suggestions.pysi le rapport doit montrer un exemple de correction. - Ajouter des tests dans
tests/test_*.pyavec au moins un cas positif et, si le risque de faux positif existe, un cas negatif. - Ajouter un exemple PHP dans
examples/seulement si cela aide a valider manuellement ou documenter la regle. - Lancer les tests cibles puis, si possible,
python -m pytest tests/.
Convention de nommage des regles : domaine.nom_precis, par exemple security.sql_injection, performance.dynamic_method_call, best_practices.line_length.
Le CLI utilise Click dans src/phpoptimizer/cli.py. Pour une nouvelle option :
- Ajouter un
@click.option. - Passer la valeur a
Configou aSimpleAnalyzer. - Verifier l'effet avec un test CLI si possible, sinon au moins une execution manuelle sur
examples/. - Mettre a jour
README.mdetREADME_FR.mdsi l'option est utilisateur.
Attention : le nom de commande installe par setup.py est phpoptimizer, mais certains documents anciens mentionnent php-optimizer. Privilegier phpoptimizer pour les nouvelles docs.
Les tests sont ecrits avec unittest, mais l'usage projet est de les lancer via pytest.
Bonnes pratiques locales :
- Garder les tests proches du comportement modifie.
- Utiliser des snippets PHP minimaux avec
tempfilequand on testeSimpleAnalyzer.analyze_file. - Filtrer les issues par
issue["rule_name"]. - Verifier les cas de non-detection pour limiter les faux positifs.
- Ne pas introduire de refactor large sans besoin direct.
- Respecter les patterns regex et helpers existants dans chaque analyseur.
Il n'y a pas de configuration black, ruff ou mypy dans le depot. CONTRIBUTING.md recommande Black, mais ne l'applique pas automatiquement.
- Le worktree peut contenir des fichiers non suivis. Au moment de creation de ce guide,
test_categories.pyetait non suivi : ne pas le supprimer ni le modifier sans demande explicite. - Plusieurs fichiers de documentation contiennent des caracteres accentues et symboles. Sous PowerShell, l'affichage peut etre degrade selon l'encodage de la console ; ne conclus pas trop vite que le fichier est corrompu.
reporter.pyimporteAnalysisResultetIssuedepuissrc/phpoptimizer/analyzer.py, mais le flux principal CLI utilise des dictionnaires issus deSimpleAnalyzer.Config.should_apply_rule()filtre strictement les regles inconnues. C'est une source frequente de "ma detection ne sort pas".- Certains noms de regles testes peuvent ne pas etre tous declares dans
Config; verifier avant de modifier le filtrage global. rules/existe, mais le chemin principal actuel estanalyzers/plusSimpleAnalyzer.collect_php_files()danscli.pyne consulte pasConfig.should_process_file(). Si tu veux appliquer exclusions, extensions ou taille max au CLI, il faut modifier ce chemin consciemment.- Eviter les commandes destructrices Git. Le depot peut contenir du travail utilisateur non commite.
- Usage general :
README.mdetREADME_FR.md. - Categories, poids et filtres :
CATEGORIES_GUIDE.md. - Ajout de regles et conventions :
CONTRIBUTING.md. - Appels dynamiques :
DYNAMIC_CALLS_OPTIMIZATION.md. - Historique de changements :
CHANGELOG.md.
Avant de finaliser une modification :
git status --shortpour distinguer tes changements du travail existant.- Tests cibles sur les fichiers touches.
- Tests complets si la modification touche
Config,SimpleAnalyzer, le CLI ou un contrat commun. - Verification manuelle CLI si le comportement utilisateur change.
- Mise a jour de la documentation si une option, categorie ou regle visible change.