En vous promenant sur Beamreactor, nous stockons votre IP 48h pour des raisons de sécurité.

Lecteur Markdown

checklinks Documentation › CHECKLINKS_DOCUMENTATION

Checklinks Documentation

Checklinks #

Vérificateur automatique de liens morts dans BeamReactor.

Namespace: ChecklinksScanner

Version: 1.2.0

Niveau requis: Administrateur

Depuis: 2002

Vue d'ensemble #

Scanner multi-source qui détecte les liens HTTP morts (4xx, 5xx, timeout) en analysant automatiquement les tables de base de données configurées via des fichiers de configuration JSON par plugin.

Fonctionnalités #

  • Scan automatique multi-plugins via configuration JSON
  • Détection parallèle avec curl_multi
  • Export CSV et JSON des liens morts
  • Interface de lancement avec rapport détaillé
  • Support de patterns d'URL complexes avec paramètres multiples

Architecture #

Interface utilisateur :

  • Bouton de lancement du scan
  • Affichage des résultats en textarea
  • Export CSV/JSON via formulaires POST

Classe ChecklinksScanner :

  • getAllUrls() — Collecte des URLs depuis les configurations
  • scan(array $urls) — Vérification HTTP parallèle

Configuration par plugin #

Chaque plugin peut définir ses sources d'URLs via :

Emplacement : plugins/{plugin}/conf/{plugin}.sitemap.json

Structure :

json
{
  "enabled": true,
  "sources": [
    {
      "type": "database",
      "table": "nom_table",
      "url_pattern": "index.php?obj=plugin.php&id=%s&lang=%s",
      "url_params": ["id", "lang"],
      "column_id": "id",
      "column_lang": "language"
    }
  ]
}

Champs de configuration #

| Champ | Type | Description |

|-------|------|-------------|

| enabled | bool | Active/désactive ce plugin |

| type | string | Toujours "database" |

| table | string | Nom de la table SQL |

| url_pattern | string | Pattern avec placeholders %s (compatible vsprintf) |

| url_params | array | Liste ordonnée des paramètres (ex: ["id", "lang"]) |

| column_{param} | string | Nom de colonne SQL pour chaque paramètre |

Exemple multi-paramètres #

json
{
  "url_pattern": "index.php?obj=docs.php&cat=%s&doc=%s&lang=%s",
  "url_params": ["cat", "doc", "lang"],
  "column_cat": "category_id",
  "column_doc": "document_id", 
  "column_lang": "language"
}

Classe ChecklinksScanner #

Constructeur #

php
public function __construct()

Initialise $baseUrl depuis $cfg[0] en nettoyant les /index.php en fin de chaîne.

getAllUrls #

php
public function getAllUrls(): array

Retourne : Tableau d'items :

php
[
  [
    'url' => 'https://example.com/index.php?obj=blog.php&id=42&lang=fr',
    'source' => 'blog',
    'document' => '42',
    'lang' => 'fr'
  ],
  ...
]

Comportement :

1. Parcourt plugins//conf/.sitemap.json

2. Vérifie enabled: true

3. Construit requêtes SQL dynamiques selon url_params

4. Génère URLs via vsprintf($url_pattern, $values)

5. Normalise les slashes et évite index.php/index.php

Gestion d'erreurs :

  • Ignore plugins sans configuration
  • Log les erreurs SQL via error_log()
  • Continue en cas d'échec sur un plugin

scan #

php
public function scan(array $urls): array

Paramètres :

  • $urls — Tableau retourné par getAllUrls()

Retourne : Liens morts uniquement :

php
[
  [
    'url' => 'https://...',
    'code' => 404,
    'source' => 'blog',
    'document' => '42',
    'lang' => 'fr'
  ],
  ...
]

Comportement :

  • Utilise curl_multi pour parallélisation
  • Options cURL :

- CURLOPT_FOLLOWLOCATION — Suit les redirections

- CURLOPT_NOBODY — HEAD request (pas de body)

- CURLOPT_TIMEOUT — 20 secondes

  • Considère comme mort : code >= 400 ou code == 0 (timeout/DNS)

Interface utilisateur #

Lancement du scan #

html
<form method="post">
  <button type="submit" name="launch">Lancer le scan</button>
</form>

Affichage des résultats #

Format textarea avec :

  • Code HTTP
  • URL complète
  • Source (plugin)
  • Document ID
  • Langue

Export #

Deux boutons POST avec base64_encode() du contenu :

| Bouton | Paramètre | Format | Nom fichier |

|--------|-----------|--------|-------------|

| Export CSV | export_csv | CSV RFC 4180 | liens-morts-{date}.csv |

| Export JSON | export_json | JSON pretty-print | liens-morts-{date}.json |

Headers :

php
// CSV
Content-Type: text/csv; charset=utf-8
Content-Disposition: attachment; filename="liens-morts-2026-01-15_143022.csv"

// JSON
Content-Type: application/json; charset=utf-8
Content-Disposition: attachment; filename="liens-morts-2026-01-15_143022.json"

Locale #

Fichier : getlocale('checklinks')

Variable : $dialchecklinks[]

| Index | Usage |

|-------|-------|

| 1 | Message début de scan |

| 2 | Template durée (sprintf) |

| 5 | Label "liens morts" |

| 15 | Bouton export CSV |

| 16 | Bouton export JSON |

| 17 | Message "aucun lien mort" |

| 18 | Label bouton lancement |

Dépendances #

  • Beamreactor\Database\SQL — Requêtes préparées
  • curl_multi_*() — Extension cURL avec support multi
  • frameheader() / framefooter() — Système de frame BeamReactor

Cas particuliers #

vsprintf vs sprintf #

vsprintf() est utilisé pour supporter N paramètres dynamiques sans connaître leur nombre à l'avance.

Exemple :

php
$url_pattern = "?obj=x.php&a=%s&b=%s&c=%s";
$url_params = ["a", "b", "c"];
$values = [1, 2, 3];
vsprintf($url_pattern, $values); // "?obj=x.php&a=1&b=2&c=3"

Limitations connues #

  • Pas de support HTTPS avec certificats auto-signés (cURL strict)
  • Timeout fixe à 20 secondes (non configurable)
  • Pas de retry automatique
  • CURLOPT_NOBODY peut échouer sur certains serveurs (préférer GET si problèmes)

Exemple de flux complet #

1. Admin clique "Lancer le scan"

2. getAllUrls() collecte 1500 URLs depuis 12 plugins

3. scan() lance 1500 requêtes HEAD parallèles

4. Détecte 23 liens morts (404, 500, timeout)

5. Affiche résultats en textarea

6. Admin exporte CSV pour traitement

7. Fichier téléchargé : liens-morts-2026-01-15_143022.csv

Performance #

Scan de 5000 URLs : ~45 secondes

Parallélisation : curl_multi limite hardware (~100 connexions simultanées)

Mémoire : Proportionnelle au nombre d'URLs (env. 200 bytes/URL)

Sécurité #

  • Pas de validation externe des URLs (confiance totale dans la config JSON)
  • Base64 pour transport POST (pas de chiffrement, juste encodage)
  • Aucune sanitisation des données exportées (CSV échappé via str_replace('"', '""'))
  • User-Agent personnalisé : BeamReactor-DeadLinkScanner/2026
de en fr