IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Callback et manipulation du buffer de sortie


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Callback et manipulation du buffer de sortie
    Bonjour,

    Je suis en train de traiter le problème suivant :

    Un document est généré dans le buffer de sortie et je veux le modifier, en l'occurence transformer les titres <Hn>... </Hn> pour générer un sommaire et associer des ancres.

    Aucun problème particulier, preg_match_all avec captures puis remplacements avec précautions (voir remarques en notes).

    Mais le problème se gâte quand le document est la publication d'un extrait d'un document plus grand (chapitre d'un livre par exemple). Dans ce cas il va falloir rapprocher du document de sortie, la source (HTML en format interne et partiellement encodé de caractères spéciaux) :

    J'ai pour l'instant échoué sur le problème suivant : comment fabriquer à partir des tags Hn source non encodés la chaîne qui pourra être recherchée dans le buffer de sortie ?

    On pourrait penser que une routine (simplifiée) comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function ob_sencode ($input) {
        ob_start();
        echo $input;
        return ob_get_clean();
    }
    pourrait faire l'affaire en ignorant toutes les définitions d'encodage du contexte.

    Mais cela ne marche pas, et je ne vois vraiment pas pourquoi :
    Le titre brut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <h2>L'impact des nouveaux moyens de communication et de traitement de l'information</h2>
    revient tel quel de la fonction ob_sencode()
    alors que dans le buffer il est encodé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <h2>L’impact des nouveaux moyens de communication et de traitement de l’information</h2>
    Note : C'est évidemment l'exemple élémentaire, dans la pratique c'est tout de suite un peu plus compliqué, mais pouvant être traité, avec les apostrophes, différents guillemets etc. et les fonction spéciales de remplacement du type "texturize" de WordPress

    Je n'ai rien trouvé sur la question.

    Il y a plusieurs autres solutions plus ou moins complexes pour faire le rapprochement (ré-associer de manière fiable un titre avec son image dans le buffer pour effectuer le remplacement adapté) mais pouvoir générer le code identique parait la plus simple, mais je sèche.

    Cordialement

    Trebly

    Si vous avez une idée, merci d'avance

    Notes : Je compléterai au fur et à mesure de la discussion ou à la fin.

  2. #2
    Membre confirmé Avatar de 01001111
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 319
    Points : 509
    Points
    509
    Par défaut
    Bonsoir,
    je suis peut-être miro ou abruti, mais j'ai du mal à comprendre la définition de ton problème.
    pourquoi utiliser le buffer si tu as déjà l'input en variable de type chaine de caractères? Mais il y a peut-être un intérêt ici que je ne comprends pas.

    Il semble que tu aies un problème ici avec les chaines contenant des guillemets simples ou doubles.
    es-tu sûr d'avoir appliqué addslashes au bon moment si nécessaire? Un stripslashes en sortie annule les effets du addslashes mais autant que possible il faut avoir les guillemets échappés dans la chaine, ou du moins être sûr que les chaines que tu compares sont dans le même état.

    Enfin, si tu as un problème avec l'encodage de caractères, tu peux essayer mb_detect_encoding pour détecter le charset de la chaine puis iconv pour tout convertir au même format, mais ça ne marche pas toujours comme on veut, j'ai eu des problèmes par le passé suite à des mises à jour de php avec iconv qui semble un peu fragile.

    En tout cas un peu plus de code à se mettre sous la dent ferait avancer la compréhension de ton problème.
    0x4F

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Contexte et éléments de solution au problème de callback "manuel" du buffer, pas si évident que cela
    Bonsoir,

    Désolé de cette réaction tardive à ta réponse à ma question, j'avais loupé l'activation de notification... et je ne suis pas revenu jusqu'à aujourd'hui faire un contrôle systématique des sujets lancés.

    En fait il y avait deux problèmes importants et je les ai confondus en répondant, tardivement

    A- Traiter de texte brut, puis le buffer de sortie comme avec une fonction de type callback mais par soft complexe

    l'explication du traitement est donnée en (B), en résumé, pour un article on a le HTML intégral complété de commandes de traitement les [shortcodes], à ce stade on va analyser le sommaire et pré-traiter des shortcodes spécifiques. Le texte en entrée est intégral alors que des commandes comme "<!--nextpage-->" vont permettre un découpage en sections affichées à la fin (buffer) comme des documents séparés. Par conséquent si l'on veut avoir un sommaire général il faut faire un prétraitement.
    On va ensuite rendre (confier) ce document prétraité au traitement principal de mise en page WordPress.
    Après traitement on va récupérer le buffer de sortie qui ne comprendra, si le texte est découpé, qu'une seule partie du document complet (j'ai pas exemple un ouvrage de 80 pages découpé en 12 sections).
    Par ailleurs comme il s'agit d'un buffer il est encodé triplement (UTF8+full_HTML+altération et compléments de styles et ajout de tags internes générés par Wordpress), la question est donc de retrouver les bons entêtes pour les compléter : en particulier écrire les liens permettent d'y accéder depuis le sommaire.

    La seule solution qui me semble viable, et que je fais fonctionner sans problème depuis cet été, comporte un double traitement sachant que :
    • Je n'ai pas pu trouver de moyen de repasser du texte encodé à l'original source.
    • Je n'ai pas pu trouver de moyen de repasser du texte source à l'output (nombreuses raisons : impossible malgré les outils d'encodage décodage et les traitement wordpress).


    Je vais, en fait, créer un identifiant unique en string ascii des headers (Hn) qui pourra être obtenu à partir des deux formes. Le traitement n'est que deux "simples" (pas si simples) preg_replace après avoir isolé les tags (<Hn>...</Hn>) et filtré.
    Dans les deux cas, après avoir isolé le contenu textuel, on remplace le chaines de caractères spéciaux (qui auront été modifiés par un identifiant unique de même longueur en octets et l'on complète d'infos permettant d'interdire tout doublon (les doublons s'ils existent - i.e. "introduction" sont nécessairement dans le même ordre...).
    Le rapprochement des listes marche à 100%

    Ensuite il ne s'agit plus que de remplacer les blocs pour reconstituer le nouvel élément valide DOM Hn souhaité (ajout de <span> permettant l'identification, les liens, associer les data utiles etc...) remplaçant après un parse partiel les éléments Hn du DOM de sortie.

    J'ai aussi appliqué ce traitement à des documents construits (listes divers avec objets multiples) pour retrouver et modifier des identifiants et libellés d'éléments et introduire notamment des liens et des marques.


    B- Difficultés de récupération du buffer : anomalies -> échec de recherches = buffer tronqué

    Le problème est résolu, mais je laisse ouvert parce je pense intéressant le résultat de l'analyse que j'ai ménée qui m'a d'ailleurs conduit à faire une note sur php.net à propos de ob_start (l'analyse a été faite en utilisant les fonction d'analyse de la pile de bufferisation et les contenus).

    Pourquoi lire le buffer :
    • Dans le cas d'articles parce que Wordpress modifie les "source" html des articles avec les "shortcodes", il est utile d'analyser (recherche d'éléments utiles) et d'effectuer les remplacements dans le buffer d'éléments repérés en première analyse (difficile à cause de l'encodage full html du buffer).
    • Il existe le cas de documents générés (listes d'articles ou autres objets mixtes - articles par auteur) et dans ce cas seul l'analyse du buffer en callback permet les traitements utiles (extension des fonctionalités prévues à l'origine qui j'ai implémentée et qui permet de construire le sommaire (avec lien) de tout document y compris ceux générés par une méthode quelconque : plugins)


    Le traitement principal que j'effectue : encadrement de "span" permettant l'identification d'éléments et la création de liens (avec beaucoup de précautions à cause des mécanismes d'héritage et leur prise en compte dans les css).

    D'où venait le problème de traitement rencontré :

    Le buffer était tronqué dans certains cas (articles suffisamment longs... en fait supérieurs à 4096 c.).

    Lorsque wordpress (le thème utilisé puis mes traitements) utilise ob_start(); pour ouvrir un niveau de buffer à traiter, l'ouverture du nouveau niveau de buffer se fait avec la bufferisation de sortie par défaut (ou le set effectué... quelque part de "chunk_size" qui en l'occurrence était réglé à 4096c. cf. remarque de la doc php :
    Avant la version PHP 5.4.0, la valeur 1 était une valeur spéciale qui définissait la taille du morceau à 4096 octets.
    ce qui était le cas).
    Par conséquent si l'on écrit plus que la taille de buffer, on ne retrouvera avec ob_get*() que au plus la taille max de buffer définie par chunk_size.

    Pour effectuer le traitement que je voulais faire (un callback en utilisant ob_get*() et la réécriture complète par un traitement complexe qui implique tout un document) il faut donc :
    1. Forcer l'écriture de la partie "article" (je crée une div spécifique) sans limite de vidage en exécutant un ob_start(,0); (0 = buffer illimité) qui n'est pas du tout équivalent de ob_start(); pour cette question.
    2. Après la fin d'écriture récupérer ce buffer (en totalité) et le remplacer.


    Ca marche très bien et en encadrant avec une div je peux tester la validité du buffer récupéré (et d'ailleurs le découper proprement).

    Donc le traitement n'est possible qu'en modifiant les sources du (ou des) thème(s) utilisé(s) (ce qui nécessite pour le plugin que je développe un processus d'installation assez lourd impliquant des patch de thèmes).

    Merci.
    Cordialement

    Trebly

Discussions similaires

  1. Réponses: 1
    Dernier message: 08/04/2009, 12h53
  2. désactiver le buffer de sortie
    Par elekaj34 dans le forum Web
    Réponses: 3
    Dernier message: 07/03/2009, 08h27
  3. Réponses: 5
    Dernier message: 07/09/2007, 03h01
  4. Buffer de sortie
    Par mic79 dans le forum Linux
    Réponses: 2
    Dernier message: 28/08/2006, 10h13
  5. [Configuration] nombre de scripts limité avec buffers de sorties
    Par alcor dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 7
    Dernier message: 08/04/2006, 22h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo