SPIP, PHP et Javascript sont dans un bateau

Dans quel ordre ça passe ? et le cache ?...

Comment se passe la cohabitation entre le source SPIP, PHP et javascript dans un squelette ? C’est possible pour plus de puissance et de souplesse dans le développement d’extensions spécifiques, de combiner spip à php. Toutefois tout n’est pas possible n’importe comment ! Attention donc aux bonnes manières !
Pour ne pas perdre des jours à débugger une boucle qui ne donne rien, la question à examiner est : dans quel ordre ça se passe ? à partir de quel fichier (cache ou pas cache) ? et à quel moment ?

Au début il y a le squelette

Supposons donc un squelette dans lequel se mêlent avec allégresse les instructions de diverses natures : HTML bien sûr, SPIP aussi, mais aussi PHP et Javascript.

Bien sûr, dans un coin du site, il y a aussi la base de données MySQL qui contient les infos « contenu » des articles.

Puis souffle le vent dans le cache

Ensuite il faut savoir qu’il y a un cache avec SPIP : chaque page est précalculée lors de son premier affichage. Ce résultat est stocké dans le cache, et c’est ce cache qui est ensuite appelé pour affichage.

La moulinette SPIP ne fait QUE traiter le code SPIP. Pour chaque boucle, SPIP interroge la base de données et génère en ligne le résultat (développé) correspondant aux réponses de la requête générée par la boucle et appliquée à la base de données.

A bord du cache

Dans le cache, il n’y a plus aucune instruction SPIP, car elles ont toutes été calculées. Par contre, il y a encore tout le code PHP résultant de l’interprétation du langage SPIP, et tout le source PHP ou Javascript présent en tant que tel dans les squelettes, qui est traité par SPIP exactement comme si c’était du simple texte, au même titre que du HTML.

Il y a 3 conséquences à cela :

  • si du code PHP ou javascript est contenu dans les critères d’une boucle, il ne sera PAS exécuté et ne pourra PAS être pris en compte dans le calcul de la boucle. Ce sera uniquement le code "source" qui sera pris en compte et le résultat sera donc erroné.
  • si du code PHP ou javascript est contenu à l’intérieur du corps d’une boucle, il sera dupliqué en autant d’exemplaires que la boucle fera d’itérations, exactement comme tout le reste du contenu. Et il s’exécutera à chaque fois. Parfois ce sera approprié, parfois ça ne le sera pas.
  • si votre squelette contient du code php, ce code se retrouvera tel quel dans le fichier de cache, et l’exécution se refera à chaque appel de la page : ces parties ne bénéficieront PAS du cache.

En conséquence de ce qui précède, l’utilisation de php est à proscrire dans les squelettes SPIP, car ce code n’est pas « caché » : pour bénéficier pleinement du cache, on utilisera uniquement SPIP, pas PHP. Pour cela, on réécrira le code php en SPIP en utilisant des éléments évolués du langage SPIP depuis la version 1.9 :
-  filtres conditionnels : ?, oui, non, ...
-  balises #SET, #GET, #EVAL, ...

Il est également toujours possible d’utiliser des filtres créés sur mesure : fonctions écrites en PHP, mais dont l’utilisation par spip, en tant que filtres appliqués à des balises, bénéficie toujours du cache. C’est cette solution qu’on utilisera quand on ne pourra pas se passer de traitements PHP complexes : pour bénéficier du cache, on les déportera dans des filtres.

Pour l’affichage

C’est le contenu du cache qui est appelé.

  • Le contenu PHP s’exécute sur le serveur et génère la page que reçoit le navigateur de l’utilisateur (c’est pour lui qu’on fait tout ça, faut pas l’oublier !).
  • Le contenu Javascript s’exécute dans le navigateur.

En conclusion : SPIP d’abord !

  1. Eviter le php en dur dans les squelettes, et plutôt mettre ce php dans des fonctions qui seront appelées en tant que filtres dans les squelettes.
  1. Pour bien mélanger PHP, Javascript et SPIP, se souvenir de l’ordre de préséance entre eux :
    • SPIP d’abord développe les boucles
    • le cache mémorise ce résultat intermédiaire
    • PHP exécute le cache et sert la page au navigateur
    • Javascript s’exécute dans le navigateur

Rq : quelques approfondissements sur le fonctionnement du cache

1) Les explications ci dessus sont en fait simplifiées, puisque SPIP gère en réalité 2 niveaux de cache : un niveau de php, pour le résultat de la compilation du code ; et un niveau de html, résultat de l’exécution du php compilé, appliqué sur la base de donnée.

C’est ainsi que dans SPIP3 :

  1. le répertoire ’tmp/cache/skel’ contient le fichier php compilé à partir des squelettes lors de l’étape de ’recalcul’. Ce cache est indépendant des variables d’url.
  2. les répertoires tmp/cache/a/... contiennent les fichiers résultants de l’exécution par php de tmp/cache/skel/, créés à chaque calcul. Il y a un fichier différent pour chaque jeu de variable d’url.

2) Il y a aussi des caches sur le disque pour les images (vignettes et versions réduites), un cache en mémoire pour les chemins des fichiers (surchargés ou non), un cache mémoire pour les pipelines, et pour divers paramètres régissant le fonctionnement interne de SPIP...

3) Pour une meilleure performance dans la gestion du cache, il convient, dans le cas de pages personnalisées, d’empêcher la démultiplication des fichiers de cache. Voir "Du php dans le squelette à la place de #SESSION ou #CACHE0.

Discussion

14 discussions

  • 3
    Guillaume

    ok merci tout est plus clair

    • pas tout a fait...c’est peut etre debile ce que je vais dire mais bon...si l’on cree son propre filtre, c’est du PHP ?!
      Alors ma question est de savoir si un filtre personnalisé est considere comme du code SPIP ou PHP...
      je voterais pour SPIP mais je souhaiterais etre sur...
      Du coup on a du code PHP qui s’execute à deux moments differents....

    • Meme question pour moi avec un debut de reponse : quid de mes_fonctions.php ?

      J’y ai mis une petite fonction qui affiche directement du html et la, oh surprise, la page s’affiche bien au premier appel, mais au second : erreur, la fonction n’est pas trouvée !

      J’en conclue donc que mes_fonctions = SPIP => interprété qu’une seule fois.

      Mais alors, on doit la mettre ou la fonction qui fait un echo ?

      D’après ce que je comprends, il faut faire un fichier php a part et utiliser le include de PHP, pas le INCLURE de SPIP.

      J’ai bon ?

    • Luciole

      pour mes_fonctions.php3 j’ai eu le meme problème et en fait il suffit de faire :

      <?php include_local(mes_fonctions.php3");?>

      et le tour est joué. Tout marche ensuite nickel !

    Répondre à ce message

  • 1

    Vous trouverez ci-dessous un script permettant de faire défiler du texte (pour moi ce seront les 5 dernières news).

    Comment définir grâce aux balises #TITRE et #TEXTE, relatives aux brèves, la variable next_message[?] du script qui suit.

    Merci de votre aide.

    Arnaud


    Script :

    <script LANGUAGE="JavaScript">
    <!--
    var message = "Bienvenue"
    var character = 0;
    var to_print = "";
    var ypos = 96;
    var next = 0 ;
    var fade = 100 ;
    var next_message = new Array() ;


    next_message[1]= "brève1"<br>
    next_message[2]= "brève2"<br> next_message[3]= "brève3"<br>
    next_message[4]= "brève4"<br>
    next_message[5]= "brève5"




    function doText(text) {
    if (document.all) {
    if (character <= text.length - 1) {
    to_print += text.charAt(character);
    teletext.innerHTML = to_print;
    character++;
    }
    else
    scrollIt();
    }
    setTimeout("doText(message)", 20);
    }

    function scrollIt() {
    if (ypos >= 0) {
    ypos -= 1;
    fade -= 3;
    if (ypos < 5) {
    teletext.innerHTML = "" ;
    }
    }
    else {
    ypos = 96;
    character = 0;
    to_print = "";
    nextMessage();
    fade = 100;
    }
    teletext.style.top = ypos;
    teletext.filters.alpha.opacity = fade;
    }

    function nextMessage() {
    message = next_message[next]
    if (next == 2) {
    next = 0;
    }
    else
    next++;
    }

    // -->

    </script>
    • Voici quelques indications qui je l’espère t’aideront à barrer entre les récifs :

      -  Met le contenu de chaque brève à la suite dans le TEXTE, chacune entre guillemet, séparées par des virgules.
      ex : « lundi », « mardi », « mercredi »

      -  Affecte le tableau next_message, au bon endroit dans le script :

      < !-- var message = "Bienvenue" var character = 0 ; var to_print = "" ; var ypos = 96 ; var next = 0 ; var fade = 100 ; 
      
      var next_message = new Array(#TEXTE) ;
      
      ...

      Mais est-ce que ce script marche vraiment ? c’est pas sur pas sur à vue de nez ...

      Ensuite, il faut penser à la mise à jour de tes brèves défilantes. Si les brèves sont indépendantes les unes des autres et doivent être mises à jour, ne vaudrait il pas mieux des « objets spip » indépendants plutôt que de bidouiller une compilation dans une seule breve ? c’est à dire faire une brève par annonce, et mettre ce script par exemple dans la rubrique « brève défilantes » englobante, avec :

      <BOUCLE_defil(ARTICLES){id_rubrique}> next_message[]= "#TEXTE"
      </BOUCLE_defil>

      Ceci dit et de toute façon, je te souhaite bonne chance ... et donne nous des nouvelles de ta ballade en bateau, avec spip et javascript.

    Répondre à ce message

  • Que se passe t’il lorsqu’on utilise du php dans un squelette pour proteger une partie d’une page (accessible seulement à quelqu’un qui s’est authentifié par #LOGIN_PUBLIC), et que la personne qui consulte la page est derrière un firewall avec un proxy/cache ?.
    Dans le cache du « client » (et non pas celui de spip), c’est seulement de l’html ? Du coup quelqu’un du même site non autorisé pourra visualiser la partie réservée en tapant la bonne url dans la barre d’adresse ?
    Merci d’avance

    Répondre à ce message

  • Tres intéressant Jean-Luc ....
    Je vais y travailler...

    Amicalement

    Daniel.

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom