Discussion:
[LONG] Syntaxe HEREDOC et inclusion de javascript, je nage...
(trop ancien pour répondre)
Eric Demeester
2011-02-24 20:45:32 UTC
Permalink
Bonjour,

Dans le but d'externaliser le code javascript inclus dans un script php
dont je ne suis pas l'auteur [*], j'essaye de comprendre comment il a
été construit, et ça commence à me faire mal à la tête...

Voici une fonction mélangeant php et javascript, il y en a plusieurs
comme ça dans le script en question.

Ce que fait la fonction a peu d'importance, ni le nom des variables, ce
qui m'intéresse, c'est la logique (?) de l'imbrication PHP/javascript et
comment réécrire ça proprement...

Mes commentaires concernant ce que je crois comprendre sont entre
crochets.

......................................................................
function rotator_fade_orig( $mod, $fileList, $_params, $speed,
$speed_fade, $number, $url, $url_class, $url_target )
{
$stamp1 = <<<EOT
<script type="text/javascript" language="javascript">
<!--
var j{$mod}=0;
var rotImg{$mod}=new Array();
if (document.images){

EOT;

[ j'en déduis que $stamp1 contient la chaîne littérale contenue entre
<<<EOT et EOT;, et que la valeur de la variable $mod passée en
paramètre à la fonction est affectée à deux variables du javascript,
et ci-dessous on revient au PHP, j'ai bon jusque là ? ]

foreach($fileList as $i=>$imh)
{
$stamp1 .= "rotImg{$mod}[$i]=new Image();\n";
$stamp1 .= "rotImg{$mod}[$i].src=\"". $imh ."\";\n";
}
$_out = "<img src=\"". $fileList[0] ."\" $_params />";
if($url) $_out = "<a href=\"$url\" $url_class $url_target>". $_out
."</a>";

[ Le foreach ci-dessus et le $_out, c'est bien du PHP qui continue à
construire la chaîne $stamp1, mais on est toujours dans le javascript,
puisqu'on a pas encore rencontré de </script>. Donc le bidule est en
train de construire dynamiquement du javascript à la volée, j'ai
toujours bon ? Ci-dessous, on repasse en syntaxe HEREDOC : ]

$stamp2 = <<<EOT
}
function rotator$mod() {
if (document.all){

document.images.rot_img{$mod}.style.filter="blendTrans(duration={$speed_fade})";
document.images.rot_img{$mod}.filters.blendTrans.Apply();
}
document.images.rot_img{$mod}.src=rotImg{$mod}[j{$mod}].src;
if (document.all)
document.images.rot_img{$mod}.filters.blendTrans.Play();

if (j{$mod}<({$number}-1))
j{$mod}=j{$mod}+1;
else
j{$mod}=0;

rotTimer{$mod} = setTimeout('rotator{$mod}()',{$speed});
}
//-->
</script>{$_out}<script type="text/javascript"
language="javascript">rotator{$mod}();</script>
EOT;

[ On s'intéresse maintenant à la chaîne littérale $stamp2, qui comme
$stamp1 est en fait du javascript assaisonné de variables passées par
le PHP. Puis vient la fin du script. {$_out} entre accolades juste
avant la réouverture d'un script appelant la fonction rotator, je ne
comprends pas sa syntaxe... ]

return $stamp1.$stamp2;
}

[ ici, fin de la fonction PHP, qui renvoie la concaténation des deux
chaînes à la fonction appelante, laquelle insérera le javascript
dans la page appelante ($_out je suppose) ]
......................................................................

En résumé, si j'ai compris la philosophie de la chose, je pourrais
résoudre mon problème de séparation des genres en écrivant le javascript
dans un fichier texte puis appeler ce fichier dans les en-têtes de la
page, plutôt que d'insérer directement le javascript dans le corps de la
page html générée ?

Tout ça parce qu'un spécialiste du référencement (sic) n'aime pas le
javascript dans les pages « parce que ça perturbe les robots » :(

Si vous avez des idées, des commentaires, des suggestions, cela me sera
d'un grand secours.

Merci aux personnes qui auront eu la patience de me lire.

[*] Il s'agit de function.image_rotator.php, qui est un plugin de
cms made simple :
http://dev.cmsmadesimple.org/project/files/172#package-220
C'est ce qui fait défiler les portraits en haut à droite sur :
http://www.opusinfide.com/
--
Eric
Olivier Miakinen
2011-02-24 21:16:34 UTC
Permalink
Post by Eric Demeester
[...]
[ j'en déduis que $stamp1 contient la chaîne littérale contenue entre
<<<EOT et EOT;, et que la valeur de la variable $mod passée en
paramètre à la fonction est affectée à deux variables du javascript,
et ci-dessous on revient au PHP, j'ai bon jusque là ? ]
Presque... Ce n'est pas tout à fait une chaîne littérale car la variable
$mod est interprétée.
Post by Eric Demeester
[...]
En résumé, si j'ai compris la philosophie de la chose, je pourrais
résoudre mon problème de séparation des genres en écrivant le javascript
dans un fichier texte puis appeler ce fichier dans les en-têtes de la
page, plutôt que d'insérer directement le javascript dans le corps de la
page html générée ?
Presque aussi. Après avoir lu le javascript depuis un fichier texte, il
faudrait soit remplacer les variables par leurs valeurs via un truc du
style preg_replace('/\$mod/', $mod), soit en faire des paramètres de la
fonction javascript. J'essaierai de détailler un peu plus tard, là je
dois partir.
--
Olivier Miakinen
Olivier Miakinen
2011-02-24 23:02:25 UTC
Permalink
Salut !

Comme promis voici une réponse un peu plus complète.

Il faut savoir que les chaînes de caractères en syntaxe Heredoc se
comportent exactement comme celles entourées de doubles guillemets,
avec donc l'interprétation des variables, la seule différence étant
qu'on n'a pas besoin d'échapper les « " » eux-mêmes. Cela étant posé,
l'essentiel pour comprendre ce que fait ce code se trouve ici :
http://fr.php.net/manual/fr/language.types.string.php#language.types.string.parsing.complex

De temps en temps il est écrit simplement $mod et parfois c'est {$mod}.
Le plus souvent c'est la même chose, mais parfois la syntaxe {$mod} est
obligatoire. Voyons cela plus en détail.
Post by Eric Demeester
......................................................................
function rotator_fade_orig( $mod, $fileList, $_params, $speed,
$speed_fade, $number, $url, $url_class, $url_target )
{
$stamp1 = <<<EOT
<script type="text/javascript" language="javascript">
<!--
var j{$mod}=0;
var rotImg{$mod}=new Array();
Ici, on aurait pu avoir tout aussi bien j$mod et rotImg$mod, ça
reviendrait strictement au même. Par exemple, si $mod vaut 15, le
code JavaScript résultant sera :
var j15=0;
var rotImg15=new Array();
Post by Eric Demeester
foreach($fileList as $i=>$imh)
{
$stamp1 .= "rotImg{$mod}[$i]=new Image();\n";
$stamp1 .= "rotImg{$mod}[$i].src=\"". $imh ."\";\n";
Ici, en revanche, les accolades sont indispensables. Supposons que $mod
vaut 15 et $i vaut 2, alors ce code est équivalent à :
$stamp1 .= "rotImg15[2]=new Image();\n";
$stamp1 .= "rotImg15[2].src=\"". $imh ."\";\n";

Sans les accolades, PHP essaierait d'accéder à l'indice 2 d'un tableau
PHP nommé $mod, puis de coller le contenu de $mod[2] dans la chaîne,
laquelle ne serait pas du tout une syntaxe de tableau JavaScript !
Post by Eric Demeester
function rotator$mod() {
Là il n'y a pas d'accolades, mais on aurait pu les mettre :
function rotator{$mod}() {
c'est-à-dire si $mod = 15 :
function rotator15() {
Post by Eric Demeester
if (document.all){
document.images.rot_img{$mod}.style.filter="blendTrans(duration={$speed_fade})";
document.images.rot_img{$mod}.filters.blendTrans.Apply();
}
document.images.rot_img{$mod}.src=rotImg{$mod}[j{$mod}].src;
if (document.all)
document.images.rot_img{$mod}.filters.blendTrans.Play();
if (j{$mod}<({$number}-1))
j{$mod}=j{$mod}+1;
else
j{$mod}=0;
rotTimer{$mod} = setTimeout('rotator{$mod}()',{$speed});
Bon, là il y a des accolades partout, mais ça ne devrait plus te poser
de problème de compréhension. La plupart pourraient être supprimées,
plus précisément toutes sauf une seule paire d'accolades. Je te laisse
trouver laquelle.


Cordialement,
--
Olivier Miakinen
Eric Demeester
2011-02-25 14:11:16 UTC
Permalink
dans (in) fr.comp.lang.php, Olivier Miakinen <om+***@miakinen.net>
ecrivait (wrote) :

Bonjour Olivier,
Post by Olivier Miakinen
Il faut savoir que les chaînes de caractères en syntaxe Heredoc se
comportent exactement comme celles entourées de doubles guillemets,
[...]
Post by Olivier Miakinen
http://fr.php.net/manual/fr/language.types.string.php#language.types.string.parsing.complex
Honte à moi, j'avais consulté cette page du manuel, mais je m'étais
limité à la lecture du paragraphe concernant Heredoc, et j'avais raté
les explications concernant la syntaxe « complète ». C'est beaucoup plus
clair, maintenant.
Post by Olivier Miakinen
De temps en temps il est écrit simplement $mod et parfois c'est {$mod}.
Le plus souvent c'est la même chose, mais parfois la syntaxe {$mod} est
obligatoire. Voyons cela plus en détail.
Bon, là il y a des accolades partout, mais ça ne devrait plus te poser
de problème de compréhension. La plupart pourraient être supprimées,
plus précisément toutes sauf une seule paire d'accolades. Je te laisse
trouver laquelle.
Post by Eric Demeester
document.images.rot_img{$mod}.src=rotImg{$mod}[j{$mod}].src;
^^^^^^
C'est là qu'il faut les laisser. J'ai bon ? :)
Post by Olivier Miakinen
Après avoir lu le javascript depuis un fichier texte, il
faudrait soit remplacer les variables par leurs valeurs via un truc du
style preg_replace('/\$mod/', $mod), soit en faire des paramètres de la
fonction javascript.
En fait, étant une feignasse notoire, je pensais m'orienter vers la
solution suivante :

Je laisse le script PHP original construire $stamp1 et $stamp2 (ainsi
j'ai un javascript dans lequel les variables sont affectées), mais je le
modifie de façon à supprimer au début :

<script type="text/javascript" language="javascript">

et </script> à la fin.

Une fois que j'ai construit $stamp1 et $stamp2, je les écris dans un
fichier texte intitulé disons, rotator.js, puis, au lien de renvoyer ces
deux variables à la fonction appelante, je lui retourne cette chaîne :

<script type="text/javascript" language="javascript1.2"
src="rotator.js"></script>

Ça implique de générer dynamiquement le javascript à chaque appel de la
fonction php, mais après tout c'est déja ce qui se passe, la seule
différence étant que je fais plaisir au référenceur fou en
l'externalisant afin qu'il ne soit plus présent dans le source de la
page html. Je m'en vais tester tout ça.

Merci de ta réponse !

Amicalement,
--
Eric
Olivier Miakinen
2011-02-25 16:43:42 UTC
Permalink
Post by Eric Demeester
Post by Olivier Miakinen
http://fr.php.net/manual/fr/language.types.string.php#language.types.string.parsing.complex
Honte à moi, j'avais consulté cette page du manuel, mais je m'étais
limité à la lecture du paragraphe concernant Heredoc, et j'avais raté
les explications concernant la syntaxe « complète ». C'est beaucoup plus
clair, maintenant.
Il faut dire que la syntaxe des chaînes est beaucoup plus complexe
qu'on ne pourrait le croire au premier abord. Il n'y a qu'à voir
comment on peut écrire aussi bien "${foo}" que "$foo" ou "{$foo}".
Et c'est encore pire avec les variables statiques de classes et les
constantes de classes (cf. plus loin sur la page) !
Post by Eric Demeester
Post by Olivier Miakinen
Bon, là il y a des accolades partout, mais ça ne devrait plus te poser
de problème de compréhension. La plupart pourraient être supprimées,
plus précisément toutes sauf une seule paire d'accolades. Je te laisse
trouver laquelle.
Post by Eric Demeester
document.images.rot_img{$mod}.src=rotImg{$mod}[j{$mod}].src;
^^^^^^
C'est là qu'il faut les laisser. J'ai bon ? :)
20/20 !
Post by Eric Demeester
[...]
En fait, étant une feignasse notoire, je pensais m'orienter vers la
Je laisse le script PHP original construire $stamp1 et $stamp2 (ainsi
j'ai un javascript dans lequel les variables sont affectées), mais je le
<script type="text/javascript" language="javascript">
et </script> à la fin.
Une fois que j'ai construit $stamp1 et $stamp2, je les écris dans un
fichier texte intitulé disons, rotator.js, puis, au lien de renvoyer ces
<script type="text/javascript" language="javascript1.2"
src="rotator.js"></script>
Ça implique de générer dynamiquement le javascript à chaque appel de la
fonction php, mais après tout c'est déja ce qui se passe, la seule
différence étant que je fais plaisir au référenceur fou en
l'externalisant afin qu'il ne soit plus présent dans le source de la
page html. Je m'en vais tester tout ça.
Attention, si tu fais cela, à ce que la fonction ne soit appelée qu'une
seule fois. En effet, si elle est appelée plusieurs fois avec des
paramètres différents ($mod, $url, $speed, $speed_fade, etc.), c'est
le dernier appel qui gagnera en remplissant le rotator.js avec *ses*
paramètres particuliers.

P.-S. : je ne suis pas sûr que le paramètre language de la balise script
serve à quelque chose... mais sur ce point tu dois être plus au courant
que moi alors je te laisse juge.

Cordialement,
--
Olivier Miakinen
Olivier Masson
2011-02-25 12:27:34 UTC
Permalink
Post by Eric Demeester
Tout ça parce qu'un spécialiste du référencement (sic) n'aime pas le
javascript dans les pages « parce que ça perturbe les robots » :(
Eh bé ! Quel spécialiste ! Ce qui peut perturber certains crawlers, ce
sont les liens JS (à la "onclick") même si Google en tient compte, par
opposition aux liens dits "en dur" que recherchent les référenceurs.
Ce n'est pas le cas ici, donc c'est du gros pipeau et je n'ai d'ailleurs
jamais vu d'article sur une telle connerie.
Eric Demeester
2011-02-25 16:27:26 UTC
Permalink
[ Attention, suivi positionné sur fr.comp.infosystemes.www.auteurs et
sujet changé parce que ça n'a plus rien à voir avec PHP ]

Salut Olivier,
Post by Olivier Masson
Post by Eric Demeester
Tout ça parce qu'un spécialiste du référencement (sic) n'aime pas le
javascript dans les pages « parce que ça perturbe les robots » :(
Eh bé ! Quel spécialiste ! Ce qui peut perturber certains crawlers, ce
sont les liens JS (à la "onclick") même si Google en tient compte, par
opposition aux liens dits "en dur" que recherchent les référenceurs.
Oui, mais ça, il n'y a pas sur mes sites. Je n'utilise le javascript
qu'à la demande expresse de clients qui veulent des Mickeys qui bougent,
dans le genre des portraits défilants sur la page que je citais. Le
bidule est cliquable, mais il y a au moins 3 liens en dur dans des menus
menant à la même page, parfaitement accessibles aux robots d'indexation.
Post by Olivier Masson
Ce n'est pas le cas ici, donc c'est du gros pipeau et je n'ai d'ailleurs
jamais vu d'article sur une telle connerie.
Je viens de regarder un peu, et les seuls articles parlant de ça sont
sur des sites de... marchands de référencement.

J'y ai quand même trouvé un bon conseil, mais pas spécialement lié aux
robots d'indexation, c'est l'utilisation systématique d'une balise
<noscript> proposant un résumé de ce que fait le javascript, utile pour
améliorer l'accessibilité et proposer une informations aux personnes
ayant javascript désactivé.

Autre préconisation du même spécialiste pour, je cite, « passer en
tendance verte sur mes outils de monitoring » : gziper le site
entièrement en paramétrant un php.ini.

Je suis loin d'être un spécialiste en référencement, mais je trouve tout
ça un peu tiré par les cheveux, comparé à la proposition de contenus
pertinents, sémantiquement corrects et organisés selon une arborescence
claire, le tout présenté dans des pages valides w3c.

Mais bon.
--
Eric
Continuer la lecture sur narkive:
Loading...