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 :

{
  "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 #

{
  "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 #

public function __construct()

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

getAllUrls #

public function getAllUrls(): array

Retourne : Tableau d'items :

[
  [
    '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 #

public function scan(array $urls): array

Paramètres :

  • `$urls` — Tableau retourné par `getAllUrls()`

Retourne : Liens morts uniquement :

[
  [
    '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 #

<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 :

// 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 :

$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