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

  • 2
    kateskye888

    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.

    Répondre à ce message

  • 5

    Bonjour,
    L’article semble un peu ancien, je suis sur la version 1.92, mais je n’arrive pas à trouver la réponse à mon problème sur le web.

    J’insère 1 fichier .php avec le code suivant (entre chevrons) : INCLUDE(scripts/nuage.php)

    Cela fonctionne très bien pour tout mes scripts, hors la requête de ce fichier php est très lourde (env.13000 résultats pour 4000 à l’affichage sur le site), ce qui, évidemment ne plaît pas au serveur...

    Je cherche donc à utiliser le cache de SPIP ou au moins celui de la page (si je ne peux pas le définir pour le fichier).
    Différentes formulations sont évoquées : #INCLURE ou <INCLURE suivies de #CACHE.... mais je n’ai aucune syntaxe qui passe.

    Voilà, si une âme charitable pouvait me donner la bonne formulation...à charge de revanche !

    Merci par avance.

    • L’article date en effet mais son contenu est toujours pleinement valable.

      Spip gère bien les caches des fichiers inclus.

      Essaie avec #INCLURE plutôt ...

      Regarde aussi éventuellement http://spipistrelle.clinamen.org/spip.php?article17

    • Merci pour ta réponse rapide.
      Je reste un peu sur ma faim avec l’histoire des noisettes....

      [(#INCLURE{fond=ma_noisette}{mes_paramètres…}|les_filtres)]

      Dois-je comprendre que je remplace simplement ma_noisette par le nom de mon fichier php ? ou dois-je le déplacer dans un répertoire particulier ?

      J’ai vu certains tutos qui donnaient une procédure assez complexe en créant d’autres fichiers, en insérant du code propre à SPIP. S’agit-il de cette démarche ?

      Pardon pour mes questions de néophyte mais je débute avec SPIP et j’ai du mal avec les filtres et les paramètres propres au CMS.

      Par avance, merci.

    • Apparament tu inclus un fichier de code php.

      Tu devrais relire le tuto de cette page en détail.

      Le code php n’est pas exécuté par spip avant les balises spip : il est inclu tel quel dans le fichier de cache, et exécuté à chaque fois.

      Une base de la programmation spip pour bénéficier du cache, c’est de ne pas utiliser de php, mais uniquement du spip ! C’est toujours possible (et souhaitable dans 99% des cas on dira).

      Donc si tu veux du cache, abandonne php, fait tout en spip !

    • “Donc si tu veux du cache, abandonne php, fait tout en spip (...)”

      J’avais bien relu et c’est ce que j’avais peur de comprendre...

      C’est quand même étonnant pour un outil aussi complet et performant que SPIP, il n’y ait pas de solution simple pour de l’inclusion de code, de surcroit si les balises SPIP sont exécutées avant le code php ^^

      Je vais donc me pencher sur l’injection de noisettes ! (t’as un Nuts ?)

      En tout cas merci de ton aide.

    • J’ai l’impression que tu imagines trop vite des limites qui en fait me donnent l’impression d’être surtout celles de ta compréhension. Tu verras en approfondissant concrètement le sujet. Bons squelettes !

    Répondre à ce message

  • 1
    dymencharles

    salut,
    mon probleme est que je n’arrive pas a manipuler du php dans le script

    <script langage="javascript"> </script>
    • Dans l’ordre on a : PHP (interprété par le serveur) puis javascript (dont les instructions sont exécutées par le navigateur web de l’internaute). Quand on affiche le code source d’une page html, on voit bien que seul le code javascript est visible, php est déjà interprété. Si tu veux pouvoir manipuler php dans javascript, il faut que tu mettes tes instructions javascript dans des print.
      ex :

      <?php <br>
      print"<script language=\"JavaScript\"> \n";<br>
      print"alert("hello");";<br>
      $m="bonjour";<br>
      print"<\script>";<br>
      ?>


      lis cet article, il te permettra de mieux comprendre

    Répondre à ce message

  • 1

    J’ai besoin de mettre un peu de javascript dans un modele et je me retrouve toujours avec

      &lt;script language
    ................
      &lt;/script>
    dans le code source de la page et donc impossible d'exécuter le javascript.

    Par contre dans un squelette pas de probléme.
    Quelqu’un saurait-il pourquoi ?

    • Salut jojo, en fait tu dois regarder le numero de ton article dans lequel tu veut inserrer du javascript : ex : ton article à pour numero : 8 ;
      donc tu va dans le dossier squelette, tu ouvre le fichier : article.html, tu le renomme : article8.html, puis tu inserre ton javascript la où tu veut et tu le met sur le serveur !

      PS : si tu à un problème encore vient sur mon site car je ne passe pas souvent ici !

    Répondre à ce message

  • Voir aussi sur la réponse de Arno* sur le forum :

    Je cite :
    —  Le PHP est interprété après les boucles

    C’est une erreur très classique (je le commets moi-même régulièrement).

    Lors de la construction d’une page de ton site, cela fonctionne en gros ainsi :

    -  étape 1 : SPIP récupère le fichier de ton squelette, et va interpréter le langage de boucles : en fonction du paramètre passé en variable (id_article, id_rubrique...), les boucles sont transformées en requêtes vers la base de données, et les balises (#TITRE, #TEXTE...) sont remplacées par les éléments tirés de la base de données ;

    Dans cette première étape, tout ce que qui n’est pas du ressort des boucles et des balises SPIP est laissé tel quel ; de cette façon, tu peux mettre absolument ce que tu veux dans ton squelette (PHP, XML...).

    Le résultat est un fichier « texte » qui est le résultat de l’interprétation de ton squelette d’origine en y insérant les résultats tirés de la base de données. Ce fichier est sauvegardé (en cache).

    -  étape 2 : ce fichier est appelé sur le serveur et envoyé vers ton butineur. Ainsi, s’il y a du PHP dans ce fichier, alors il est interprété par Apache et le résultat t’es communiqué.

    Tu vois donc que le PHP est interprété par Apache après que SPIP ait interprété les boucles et les balises SPIP. Du coup, il n’est pas possible d’utiliser du PHP à l’intérieur des définitions de boucles.

    Répondre à ce message

  • 5

    j’ai un problème avec php dans un article.

    j’encadre bien mon code par pour pas que spip fasse des manip sur mon code mais il en fait !

    le « <« est codé en »&lit;« comment faire donc pour exécuter convenablement du code php séparé par »

    <?" et "?>

     » ?

    nb : le problème n’existe pas pour « > » qui reste bien « > »

    merci

    • là aussi ya problème dans les forum :-(

      je disais j’encadre mon code php dans l’article par < H T M L > et < / H T M L > mais le « < » se trouve changé

    • Georges Cubas

      spip est fait pour publier un journal à l’origine et je ne crois pas qu’il soit prévu d’insérer du php ou du javascript dans les articles pour qu’il soit interprété. Il y a les squelettes pour ca.

      Dans un article il n’y a que du texte à afficher, les balises < HTML > indiquant à spip de ne pas faire de mise en forme.

      Donc pour ton problème il faut créer un squelette spécifique à l’article. Si tu dois inserer du php différent dans chaque article spip n’est peut être pas le bon systeme pour ton site.

      — 
      SourisVerte.net

    • PhilippeD

      on est bien d’accord sur le principe de base... mais .. on a parfois besoin d’un petit coup de PHP !

      Pour moi le pb est deglisser des adresses mail transformées en image à l’exécution. Exemple :

      adresse :
       <?php admail2img("toto@mac.com") ?> incopiable... 
    • Je me pose la même type de question...

      Effectivement, aujourd’hui, il ne semble pas y avoir de solution pour mettre un peu de PHP dans les articles.

      Et pourtant, il y a des cas où cela se justifie :

      Personnellement, je cherche à mettre en ligne des synthèses de chants pour aider des choristes à répéter.

      -  Première approche : je fais un bon HTML bien bourrin, avec usage intensif de copier-coller (les morceaux sont interprétés via un plug-in), et j’insère le tout dans un article SPIP.

      -  Deuxième approche : je fais un PHP une bonne fois pour toute, et il me suffit d’uploader le fichier de musique et de renseigner une table dans MySQL.

      De mon point de vue, cela reste de la publication d’informations.

      Je peux y arriver, bien sûr, en faisant un article et un squelette spécifiques. Mais je trouve ça « sale ».

      J’ai tout faux ?

    • SAlut désolé pour le retard de la réponse. Donc si c’est toujours valable tu peux faire un filtre qui récupère les adresses email dans tes articles et les remplace par une fonction php qui crée ton image

      par exemple :

      function apres_propre($texte) {
      	// remplace les mailto par des images
      	return ereg_replace("/<a href=\"mailto://(.*)\">(.*)<\/a>/i", "<?php email2img('\\1', '\\2'); ?".">", $texte);
      }

      je ne l’ai pas testé, c’est juste pour l’idée. Il y a plus d’informations sur la fonction ’apres_propre’ dans d’autres articles.

      A+

      souriverte.net

    Répondre à ce message

  • 1

    Bonjour,

    Voila j’ai un petit problème avec un menu. En fait il est en javascript, dans une page en .js.
    Est-ce qu’il est possible de faire des boucles directement dans mon ficher js ?

    Merci !

    Celine

    • tu peux faire des boucles dans tous types de fichier, même les javascripts, il faut juste le traiter comme des squelettes.

      C’est un peu bizarre, mais il faut écrire un squelette : monjavascript.php3/monjavascript.html et mettre le contenu du javascript (Avec boucle) dans le .html, il ne faut pas se fier à l’extension.

      Ensuite, on peut insérer le javascript en appelant le .php :
      <sript src="monjavascript.php3">

    Répondre à ce message

  • Bonjour et merci aux créateurs de ce site dans lequel j’ai bcp appris sur SPIP.

    Je cherche à mettre un accès privé sur mon site et je me sers des sessions PHP.
    J’ai une page login1.php qui inerroge une table et qui ouvre une session :

    if ($num == 1) //$num1 compte le nb d’enregistrement avec nom+pass corrects

    header(« Location : page2.php3 ») ;

    @session_start() ;

    $_SESSION[’auth’] = « yes » ;

    exit ;

    Ensuite chaque page controle la présence de cette variable :

    <?php 
    
    @session_start(); 
    
    if (@$_SESSION['auth'] != "yes") 
    
    {header("location: login1.php"); 
    
    exit;} 
    
    ?>

    (PS : le code de mes pages ne compoerte pas tous ces sauts de ligne que j’ajoite ici pour la lisibilité du message)

    Cette procédure marche parfaitement EN LOCAL : lorsque je demande page2.php3 en tapant son URL, sans passer par le formulaire de login1.php, je suis renvoyé vers login1.php.

    Cette procédure marche aussi chez mon hébergeur sur un dossier de test.

    Mais quand je la teste sur mes pages SPIP, il y a invariablement le même message d’erreur « headers already sent ».

    Ces pages sont actuellement protégées par .htaccess/.htpasswd. ESt-ce que ça vient de là ou de la présence des boucles SPIP (sui ne posent pas pb en local) ?

    Merci.

    Répondre à ce message

  • 2

    et comment passer une variable spip à php ?

    boucle(articles)critere

    <?php
    _ $var=#TITRE;
    ?>


    /boucle

    n’a pas l’air de fonctionner.

    • Essaye $var=’#TITRE’ ;
      (avec guillemets)

      Paolo

    • Bonjour,
      j’aurai aimé savoir s’il est possible d’intégrer des boucles SPIP dans une page javascript.
      En fait, je voudrai placer un menu dynamique dans mon squelette SPIP en appelant une page javascript qui elle-même contiendrai une boucle SPIP. Est-ce possible ?
      Merci !

    Répondre à ce message

  • 2

    Salut !

    Je voudrais créer une liste de titre de brève à sélectionner dans un formulaire, puis afficher le texte de la brève en dessous à chaque sélection.
    Voilà mon code :

    le javascript :
    [script]
    function afficherFondateur(monchoix)

    var leTexte = « divfond » ;
    [BOUCLE_trouverbreve (BREVES) id_breve=monchoix]

    document.getElementById(leTexte).innerHTML = #TEXTE ;

    [/BOUCLE_trouverbreve]

    [/script]

    le formulaire :
    [FORM NAME=« myForm » ACTION=« » METHOD=« get »]
    [SELECT NAME=« mySel » CLASS=« input » onchange=« afficherBreve(fmyForm.mySel.options[this.selectedIndex].value) »]

    [BOUCLE_liste (BREVES) par id_breve]
    [OPTION VALUE=« #ID_BREVE »]#TITRE[/OPTION]
    [BOUCLE_liste]
    [/SELECT]
    [INPUT TYPE=« button » NAME=« valider » VALUE=« Aller » CLASS=« bouton »]
    [/FORM]

    le div où j’affiche le texte de la brève :
    [div id=« divfond » style=« position:relative ; width:100% ; height:300px ; z-index:1 ; overflow : auto »]
    [/div]

    JE N’ARRIVE PAS A RECUPERER LE TEXTE ! Quelqu’un a-t-il une solution ?

    • Errata : il s’agit de afficherBreve et non afficherFondateur !
      J’arrive à récupérer l’ID_BREVE mais pas le #TEXTE dans le script Javascript

    • As tu eu des réponses ou des solujtions ?

      Je suis dans le meme cas que toi présentement...

      Thierry

    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