ruiadr/fetcher

Utilitaire permettant de récupérer et de valider des ressources web via des fetchers spécialisés.

3.2.0 2025-06-24 11:43 UTC

README

pipeline status

Quality Gate Status Coverage

Reliability Rating Security Rating Maintainability Rating

Technical Debt Vulnerabilities

Le module Fetcher permet de récupérer le contenu de ressources web avec validation automatique du type de contenu. Il propose une approche orientée objet avec des fetchers spécialisés pour différents types de ressources.

⭐ Utilisation

Le module Fetcher utilise les concepts suivants :

  • FetcherBase : Classe abstraite de base implémentant la logique commune
  • FetcherBaseInterface : Interface définissant le contrat des fetchers
  • Fetchers spécialisés : Classes concrètes pour chaque type de contenu
  • Factory Pattern : Création automatique du bon fetcher selon le type
  • Validation de contenu : Vérification du Content-Type avant retour du contenu

Utilisation rapide

Fetch d'une page HTML

use Ruiadr\Fetcher\HtmlFetcher;

$fetcher = HtmlFetcher::buildFromUrlString('https://www.example.com');

if ($fetcher->getResponseCode() === 200) {
    $content = $fetcher->getContent();
    echo $content; // Contenu HTML de la page
}

Fetch avec la factory

use Ruiadr\Fetcher\Base\FetcherBase;
use Ruiadr\Base\Wrapper\Url;

$url = new Url('https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css');
$fetcher = FetcherBase::buildFetcher('stylesheets', $url);

echo $fetcher->getContentType(); // "text/css"
echo $fetcher->getContent();     // Contenu CSS

Factory Pattern - FetcherBase

La classe FetcherBase propose une factory qui instancie automatiquement le bon fetcher selon le type demandé.

Syntaxe

use Ruiadr\Fetcher\Base\FetcherBase;
use Ruiadr\Base\Wrapper\Url;

$fetcher = FetcherBase::buildFetcher(string $type, UrlInterface $url): ?FetcherBaseInterface

Types supportés

use Ruiadr\Base\Wrapper\Url;

$url = new Url('https://www.example.com');

// Types par nom court
$htmlFetcher = FetcherBase::buildFetcher('html', $url);       // -> HtmlFetcher
$jsFetcher = FetcherBase::buildFetcher('javascript', $url);   // -> JavascriptFetcher
$cssFetcher = FetcherBase::buildFetcher('stylesheets', $url); // -> StylesheetsFetcher
$textFetcher = FetcherBase::buildFetcher('text', $url);       // -> TextFetcher

// Types par nom de classe complet
$htmlFetcher = FetcherBase::buildFetcher(\Ruiadr\Fetcher\HtmlFetcher::class, $url);

Gestion des types invalides

$fetcher = FetcherBase::buildFetcher('invalidType', $url);
// Retourne null si le type n'existe pas

Fetchers disponibles

HtmlFetcher

Fetcher spécialisé pour les pages HTML.

use Ruiadr\Fetcher\HtmlFetcher;
use Ruiadr\Base\Wrapper\Url;

// Construction directe
$fetcher = new HtmlFetcher(new Url('https://www.example.com'));

// Construction via factory statique
$fetcher = HtmlFetcher::buildFromUrlString('https://www.example.com');

// Utilisation
$responseCode = $fetcher->getResponseCode(); // int(200)
$contentType = $fetcher->getContentType();   // string("text/html")
$content = $fetcher->getContent();           // string("<!DOCTYPE html>...")

JavascriptFetcher

Fetcher spécialisé pour les fichiers JavaScript.

use Ruiadr\Fetcher\JavascriptFetcher;

$url = 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js';
$fetcher = JavascriptFetcher::buildFromUrlString($url);

$fetcher->getResponseCode(); // int(200)
$fetcher->getContentType();  // string("application/javascript")
$fetcher->getContent();      // string("!function(e,t){...")

StylesheetsFetcher

Fetcher spécialisé pour les feuilles de style CSS.

use Ruiadr\Fetcher\StylesheetsFetcher;

$url = 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css';
$fetcher = StylesheetsFetcher::buildFromUrlString($url);

$fetcher->getResponseCode(); // int(200)
$fetcher->getContentType();  // string("text/css")
$fetcher->getContent();      // string(":root{--bs-blue:#0d6efd;...")

TextFetcher

Fetcher spécialisé pour les fichiers texte brut.

use Ruiadr\Fetcher\TextFetcher;

$url = 'https://www.cloudflare.com/ips-v4/';
$fetcher = TextFetcher::buildFromUrlString($url);

$fetcher->getResponseCode(); // int(200)
$fetcher->getContentType();  // string("text/plain")
$fetcher->getContent();      // string("173.245.48.0/20\n103.21.244.0/22\n...")

Créer un nouveau Fetcher

Vous pouvez créer vos propres fetchers pour des types de contenu spécifiques.

Étapes de création

  1. Étendre la classe FetcherBase
  2. Implémenter la méthode getContentType()
  3. Optionnellement, surcharger d'autres méthodes si nécessaire

Exemple : Fetcher pour JSON

<?php

namespace Mon\Namespace;

use Ruiadr\Fetcher\Base\FetcherBase;

class JsonFetcher extends FetcherBase
{
    final public function getContentType(): string
    {
        return 'application/json';
    }
    
    /**
     * Méthode utilitaire pour décoder le JSON
     */
    public function getDecodedContent(): ?array
    {
        $content = $this->getContent();
        
        if (empty($content)) {
            return null;
        }
        
        return json_decode($content, true);
    }
}

Utilisation du fetcher personnalisé

use Mon\Namespace\JsonFetcher;
use Ruiadr\Fetcher\Base\FetcherBase;
use Ruiadr\Base\Wrapper\Url;

// Utilisation directe
$fetcher = JsonFetcher::buildFromUrlString('https://api.example.com/data.json');
$data = $fetcher->getDecodedContent();

// Utilisation via factory avec nom de classe complet
$fetcher = FetcherBase::buildFetcher(JsonFetcher::class, new Url('https://api.example.com/data.json'));

⭐ Tests

Lancer les tests unitaires :

php vendor/bin/phpunit

Lancer les tests unitaires avec des statistiques de couverture du code :

La commande aura pour effet de générer un fichier coverage.xml qui pourra ensuite être utilisé par SonarCloud, et un répertoire coverage contenant le HTML permettant de consulter le compte rendu depuis son navigateur.

php vendor/bin/phpunit --log-junit=tests.xml --coverage-clover=coverage.xml --coverage-html coverage

xdebug doit être installé et activé. Exemple avec un conteneur Docker :

# /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

zend_extension=xdebug.so

[xdebug]
xdebug.mode=coverage