Comment générer un texte autour d’un mot précis en PHP ?

Mathieu Chartier Programmation 10 commentaires

Encore un billet technique sur ce blog. Comme j'en ai pris l'habitude, j'aime varier entre mes différentes passions telles que le référencement web, les réseaux sociaux, les CMS ou encore les astuces techniques (notamment en PHP). Ne pensez pas que je n'aime rien d'autre, mais rien qu'avec ces sujets, nous avons de quoi discuter un moment... :-)

Aujourd'hui, je vous présente une même fonction PHP transcrite en PHP procédural et objet (POO) qui permet de générer un extrait de texte à partir d'un mot précis. Le cas d'école pour ce type de fonction est la génération de description dans un moteur de recherche. Si vous souhaitez créer un snippet (extrait de texte) autour d'un mot recherché, ces fonctions et méthodes sont faites pour vous !

Fonctionnalités générales

La fonction est assez modulaire, même si elle peut être encore améliorée. Au-delà de générer un texte, elle permet plusieurs adaptations :

  • Accepter un mot précis ou un tableau de mot (dans ce cas, l'extrait est généré autour d'un des mots tirés au hasard). Dans la version en POO, il est possible de définir l'indice du mot que nous souhaiterions prioriser.
  • Modifier le nombre de mots à afficher avant et après le mot recherché. Par conséquent, vous pouvez gérer la taille du texte créé dynamiquement.
  • Choisir autour de quelle occurrence du mot générer l'extrait. En effet, il peut arriver qu'un mot soit répété dans un texte, il convient alors de choisir quelle occurrence privilégier pour générer le snippet.
  • Afficher une chaîne au choix avant et après l'extrait (souvent des points de suspension...).

Tous les paramètres sont détaillés dans les fichiers ou les codes présentés ci-dessous, n'hésitez pas à me contacter si vous avez un problème...

N.B. : si cette fonction vous aide, vous pourrez dire merci à Olivier Andrieu, le "Pape" du référencement, car c'est pour lui que j'ai développé cet outil à l'origine. Comme je n'aime pas jeter mes créations par les fenêtres, je préférais vous en faire profiter... :-)

Génération de texte autour d'un mot : la fonction PHP !

Voici la fonction generateWrapText() en PHP procédural. Elle est relativement complète mais peut encore être améliorée comme nous le verrons à la fin de cet article. Si elle vous convient, vous pouvez la recopier ou la télécharger ci-dessous.

Télécharger “GenerateWrapText 1.1 (PHP procédural)”generateWrapText-1.zip – Téléchargé 557 fois – 2 KB


Version plus complète en PHP Objet (POO)

Juste pour le plaisir, j'ai développé une version en PHP Objet de ce générateur de texte autour d'un mot précis. Au fond, rien de bien neuf, la Class PHP peut encore être améliorée mais elle profite désormais de getters (accesseurs) et setters (mutateurs) pour effectuer plus facilement des opérations sur les extraits à générer.

Les méthodes principales de la Class GenerateWrapText sont les suivantes :

  • retournerTexte("texte général", "mot recherché") qui retourne le résultat (return).
  • afficherTexte("texte général", "mot recherché") qui affiche le résultat (echo).

Vous pouvez la télécharger ci-dessous ou la recopier dans le cadre qui suit.

Télécharger “GenerateWrapText 1.1 (PHP objet)”generateWrapText-POO.zip – Téléchargé 455 fois – 2 KB


Variante de création d'extrait de texte à la volée

Il existe une variante pour faire le même type de création d'extrait de texte à la volée autour d'un mot précis. Souvent, les développeurs conseillent de chercher la position exacte du mot (avec strpos ou l'inverse strrpos), d'en récupérer la longueur (avec strlen), puis de boucler autour de cette position pour afficher "n" lettres avant ou après.

J'aime moins cette méthode qui me semble plus lourde et plus complexe pour couper précisément des mots, bien qu'il y ait des moyens d'arriver à nos fins. Il faudrait notamment remonter de "n" caractères avant le mot recherché pour trouver un espace ou idem après ce mot. Toutefois, nous n'aurions jamais la précision et le contrôle sur le nombre de mots réels à afficher (sans parler des calculs parfois lourds pour trouver les positions, etc.)

Conclusion sur la génération de snippets en PHP autour d'un mot précis

Voilà, j'espère que cette fonction pourra rendre service à certains d'entre vous, voire donner des idées d'améliorations.

Je vous glisse une piste par exemple. La fonction découpe les mots à chaque espace, mais il arrive que des "mots" n'en soit pas réellement, il faudrait donc filtrer ces "faux mots" tant que possible. Certes, cela pourrait être un travail de titan mais voici quelques exemples simples d'améliorations possibles :

  • Si on écrit une phrase avec un trait d'union encadré d'espace, ce tiret est considéré comme un mot, il faudrait donc supprimer les "mots" de ce type lors du découpage du texte en tableau de termes. Beaucoup d'exemples sont similaires comme l'esperluette, le signe euro, le pourcentage (...) qui sont souvent espacés des textes. Il faut également supprimer la ponctuation espacée comme les points d'exclamation, d'interrogation, etc. Tout cela permettrait d'avoir un nombre de mots plus réaliste et précis autour du terme ciblé.
  • Si on utilise des encodages variés (fortement déconseillé mais ça arrive...), il pourrait être intéressant de faire un test de détection d'encodage (avec mb_detect_encoding ou mieux) pour adapter l'affichage final.

10 commentaires

  • Zorinho dit :

    Bonjour,

    N'étant pas du tout un technicien, j'ai tenté de mettre le fichier dans mon espace FTP pour y accéder par URL mais la page reste en blanc.

    Comment faut-il faire pour pouvoir tester ce fichier qui à l'ar très intéressant ?

    Cordialement

    • Bonjour,
      C'est normal que ça vous fasse ça, le fichier n'étant que la fonction générique. Il faut donc l'inclure dans le fichier sur lequel vous souhaitez générer votre extrait de texte (avec < ?php include_once('chemin-eventuel/generateWrapText.php'); ?>). Une fois le fichier "chargé", vous pouvez utiliser la fonction en respectant les paramètres, par exemple en écrivant ceci (n'importe où après l'inclusion) :
      < ?php echo generateWrapText("Mon super texte cible avec le mot à encadrer à l'intérieur", "mot"); ?>
      Voilà ! :D

  • Zorinho dit :

    Merci beaucoup pour les infos complémentaires, j'ai fait des tests et ça fonctionne bien, manque plus que le plugin wordpress !

    En revanche, c'est dommage lorsque le texte contient plusieurs occurence de ne pas avoir des extraits correspondants à chaque occurence pour voir quel extrait serait le plus pertinent.

    +1

  • Xavier dit :

    Bonjour,
    D'abord merci pour les ressources que vous dispensez sur votre site (notamment le moteur de recherche !), mais j'ai une question concernant cette fonction. Il me semble qu'il y a un souci si il n'y a pas "n" mots suivants ou précédents. Par exemple si l'occurrence recherchée est en début ou fin de texte. Comment pourrais-je modifier la fonction pour vérifier qu'elle s'arrête si elle arrive en début ou fin de texte ? Merci pour vos conseils.

    • Bonjour,
      Merci pour votre remarque, je n'avais pas pensé à ça quand j'ai codé ça à la va-vite. Téléchargez la nouvelle version (1.1), c'est corrigé et j'ai ajouté une option pour mettre le mot recherché en gras. De même, si c'est le découpage arrive en début ou fin de texte, les chaînes complémentaires de s'affichent pas (par exemple, inutile d'afficher "..." à la fin si c'était bien la fin du texte normal). :D

      • Xavier dit :

        Merci pour cette réactivité ! Toutefois, je dois m'y prendre comme un manche, j'ai toujours des erreurs.
        Exemple :
        $contenu = 'un test de chaine assez court mais pas trop quand même un test de chaine court mais pas trop quand même un test de chaine court mais pas trop quand même un test de chaine court mais pas trop quand même';
        nb : une fois "assez", au début.
        $extrait->afficherTexte($contenu, 'assez');
        résultat : Notice: Undefined offset: 1
        Un avis ?

  • Xavier dit :

    Désolé pour le spam, mais après quelques tests, je m'excuse, votre script ne semble pas être en cause. Mon souci vient probablement du fait que je soumets à votre script une chaine qui ne contient pas systématiquement le mot recherché (ce script est utilisé dans un système de recherche, le mot cherché peut être dans le titre ou dans le contenu). Il va falloir que je me penche plus sérieusement dessus.

    • J'ai résolu ce souci. En effet, je n'avais pas d'erreur, sauf si le mot n'existait pas. Désormais, ça retourne un texte "vide" si le mot recherché n'est pas dans le texte. Vous pouvez donc téléchargez à nouveau la version 1.1, c'est corrigé. :D

  • Alice dit :

    Bonjour,

    Honte à moi, l'article date de 2015 et je ne le vois que maintenant.

    Merci de partager cela, je pense que ça va bien m'aider pour un projet de génération semi automatique de texte.

    Je commence à peine à apprendre le PHP et je me demandais si cette fonction peut s'adapter à une utilisation plus "poussée". Admettons que je souhaite générer un texte autour de cinq variables (ma requête principale, mes deux requêtes secondaires et mes deux ancres), et qu'en fonction de mes requêtes je puisse choisir un type de texte (= secteur d'activité), ai-je besoin de créer une base de données (regroupant mes textes en fonction de différents secteurs d'activité) ?

    Merci d'avance,
    Alice

    • Bonjour,
      Vous serez obligée d'avoir une base de données ici sinon vous aurez trop de calculs à gérer à chaque recherche. Ce n'est pas tant que vous ne pourriez pas faire sans, mais déjà, le programme que je donne ici impose quelques calculs qui prennent du temps quand plusieurs résultats sont générés. Si dans votre cas vous voulez l'appliquer selon 5 variables (une seule pouvant être prise en compte par extrait en revanche), ce sera donc encore pire, donc l'idéal serait d'enregistrer les infos dans une base de données pour chaque requête, afin de ne plus avoir à les reproduire à chaque recherche.
      Après, pour gagner du temps, quand une requête sera effectuée, il suffira de vérifier dans la base si les "cases" sont déjà remplies (donc il y a déjà eu une génération d'extrait) ou non, afin d'éviter d'écraser ce qui est déjà fait.

  • Déposer un commentaire

    L'adresse de messagerie ne sera pas publiée.* Champs obligatoires