Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Passer une valeur quelconque de PHP a JavaScript

37 réponses
Avatar
Olivier Miakinen
[ diapublication entre fcl.php et fcl.javascript, suivi sur fcl.php(¹) ]

Bonjour,

La question que je me pose, je suis étonné de ne pas l'avoir encore vue
passer. Je n'ai rien trouvé non plus dans la FAQ, même si j'ai trouvé
la question inverse (avec une réponse lapidaire assez logique :
<http://faqfclphp.free.fr/#rub2.8>).


Je voudrais transmettre le contenu d'une variable de type chaîne de
caractères de PHP à JavaScript. À priori, rien de plus simple :
var str = '<?php echo $str; ?>';

Mais le problème, c'est que la chaîne en PHP $str peut contenir à peu
près n'importe quoi, par exemple des caractères chinois ou japonais,
mais aussi des apostrophes simples (') ou doubles ("), des sauts de
ligne, des barres obliques dans un sens et dans l'autre (/ et \) et
ainsi de suite.

Je précise que le codage de $str est de l'UTF-8, et celui du fichier
HTML aussi. Il ne peut pas y avoir de caractère invalide (genre une
valeur CP1252 entre 128 et 159 transformée en UTF-8 comme si c'était
du Latin-1) mais à peu près tout point de code valide entre U+0001 et
U+FFFF est susceptible de s'y retrouver.

Comment puis-je faire pour assurer que ça marche dans tous les cas ?

Cordialement,
--
Olivier Miakinen

(¹) Si votre réponse utilise plus de JavaScript que de PHP, n'hésitez
pas à changer de groupe pour la suite de la discussion.

7 réponses

1 2 3 4
Avatar
Olivier Miakinen
Le 09/12/2008 12:31, Cenekemoi répondait à mpg :

Si je peux me permettre, niveau lisibilité du code, je préfère
vachement voir remplacer "r" par "r" que "r" par 'r'.





Pas moi. Moins il y a de à compter et plus je trouve le résultat
lisible ; d'ailleurs c'est aussi pour ça que je corrige toujours les
« echo "<a href="$href">"; » en « echo "<a href='$href'>"; ».

Évidemment, cela oblige à avoir en tête les différentes syntaxes
d'écriture des chaînes, ce qui se complique encore quand on doit
le faire pour PHP, JavaScript, C, shell, et d'autres langages aux
syntaxes incompatibles les unes avec les autres.

Au passage Cenekemoi, et quoi que ce soit hors sujet ici, cela fait
longtemps que je n'ai pas fait de Java et je ne comprends pas pourquoi
tu mets tant de dans :
str = str.replaceAll(""", "\""); (" -> " et pas " ?)
str = str.replaceAll("'", "\'"); (' -> ' et pas ' ?)

Enfin, les goûts et les couleurs...

Manuel.



+1



+1 aussi, sauf que je ne m'appelle pas Manuel.
Avatar
Pierre Goiffon
Olivier Miakinen wrote:
J'avais posé la question avant d'aller relire attentivement la norme,
mais je savais déjà qu'un saut de ligne ne pouvait pas être transmis
tel quel. Après relecture, je sais maintenant que les seuls caractères
à protéger sont l'apostrophe, la barre oblique , LF (U+000A), CR
(U+000D), LS (U+2028) et PS (U+2029).


J'ignore ces contraintes, peux tu détailler ?



Oui.


(...)

Merci Olivier, je garde ce message très précieusement.
Finalement on n'a pas tant de caractères à échapper, surtout si l'on
traite des chaînes sans retours chariot ce qui je suppose correspond à
la majorité des cas.
Avatar
Alex Marandon
Pierre Goiffon wrote:
Alex Marandon wrote:
Il y a aussi les problèmes liés à l'optimisation du temps de
chargement des pages. Générer du JavaScript dynamiquement rends
difficile et/ou inefficace la concaténation et la minification du
code ainsi que l'exploitation des caches.



Ok pour la concaténation




(...)
Mais je ne comprend pas pourquoi vous parlez du cache ?



je veux simplement dire que si le code contient des données, le
navigateur devra télécharger une copie fraîche de ce code à chaque
changement des données (inefficace)



Ok compris.
L'argument ne me parait pas très pertinent : on pourra appeler un
"properties-fr" et un "properties-en" par exemple, ou un "data-200801"
et un "data-200802", avec toutes les solutions d'url rewriting existant
aujourd'hui ça sera un plaisir.
Ca impose de bien "catégoriser" ses données, mais c'est de toute façon
obligatoire non ?



Là par contre c'est moi qui ne comprends pas :) Réponds-tu au passage
que tu cites ? Si tu fais référence à l'utilisation du champ Expires,
effectivement, que le code JavaScript soit statique où dynamique, on va
versionner les URLs pour forcer le rafraîchissement. Dans le cas où la
version est basée sur le contenu d'une base de donnée plutôt que la date
de modification du fichier, le mécanisme est juste un peu plus compliqué
à mettre en place et implique d'interroger la base, mais en effet c'est
faisable.

Reste que l'on a toujours le besoin de fournir à JavaScript des
données et que XHR n'est pas la réponse miracle.



Comme je l'ai dit précédemment, le DOM est AMHA la "base de données"
dans le contexte d'exécution d'un navigateur web.



C'est intéressant mais en pratique ça me parait plutôt acrobatique à
gérer, car ce contenu en l'occurence ne devra pas toujours être présenté
à l'utilisateur !



Pourquoi forcer l'utilisateur à télécharger du contenu qu'il ne verra
pas ?-)

Pour moi c'est déplacer le problème vers l'intégrateur
HTML



L'intégrateur HTML ? Tu fais référence à ce Monsieur ;-)
http://flickr.com/photos//265918244/

qui devra gérer des "zones cachées" servant au JavaScript à aller y
piocher des données. Ca me parait donc source de gros bugs...



Si on part du principe qu'on peut se passer de communication entre
designer et programmeur, on va effectivement au devant de gros bugs,
quelle que soit la technique employée.

sans
parler de la lourdeur du markup potentiellement généré,



C'est vrai que <input type="hidden"> l'utilisateur va le sentir passer ;-)

et évidemment
directement les problématiques de cache !



Les problématiques de cache sont là de toute façon à partir du moment ou
on sert des pages dynamiques, ça ne change rien de ce point de vue là. À
moins bien sûr que tu serves des pages entièrement statiques et que tu
récupères toutes tes données sous forme de JavaScript généré dynamiquement.

Sinon par curiosité, en pratique tu procèdes comment ? Est-ce que tu
crées des templates JavaScript avec des substitutions de variables au
beau milieu de code, ou bien est-ce que tu isoles ce qui varie dans des
modules chargés séparément ?
Avatar
Pierre Goiffon
Alex Marandon wrote:
je veux simplement dire que si le code contient des données, le
navigateur devra télécharger une copie fraîche de ce code à chaque
changement des données (inefficace)



L'argument ne me parait pas très pertinent : on pourra appeler un
"properties-fr" et un "properties-en" par exemple



Si tu fais référence à l'utilisation du champ Expires,
effectivement, que le code JavaScript soit statique où dynamique, on va
versionner les URLs pour forcer le rafraîchissement.



Oui c'est ce que je voulais dire, pardon si je n'ai pas été assez clair.

Comme je l'ai dit précédemment, le DOM est AMHA la "base de données"
dans le contexte d'exécution d'un navigateur web.



C'est intéressant mais en pratique ça me parait plutôt acrobatique à
gérer, car ce contenu en l'occurence ne devra pas toujours être
présenté à l'utilisateur !



Pourquoi forcer l'utilisateur à télécharger du contenu qu'il ne verra
pas ?-)



Pas compris ?
On a besoin de données pour des traitements internes au JS (liste d'id,
meta données sur chaque élément d'une liste, ...) et pour des libellés à
afficher lors des traitements JS. Ce ne sont pas des données "présentées
dans le HTML" : la 2eme catégorie pourra être affichée, mais c'est le
JavaScript qui va "l'injecter"...

On peut se dire que l'on récupérera toutes les chaînes non affichées à
l'utilisateur sur la page en XHR, mais le faire aussi systématiquement
me parait largement "overkill" si je repense aux différents exemples que
j'ai eu à traiter (en particulier, chaînes utilisées sur plusieurs
pages, coût du traitement côté serveur, introduction de latence côté
client...). Et puis ce genre de généralités, il suffit d'un contre
exemple pour tout écrouler, je préfère prévoir plusieurs cas :)

Si on part du principe qu'on peut se passer de communication entre
designer et programmeur, on va effectivement au devant de gros bugs,
quelle que soit la technique employée.



...
Votre remarque me laisse pantois ! Admettez que veiller à bien cacher
des données présentes dans le HTML uniquement pour servir au JavaScript
impose d'être vigilant !
Vous faites comme vous voulez, moi je privilégie ce qui est le plus
simple possible, ET introduit le moins de dépendances. Là ça ne respecte
pas du tout ces critères.

sans parler de la lourdeur du markup potentiellement généré,



C'est vrai que <input type="hidden"> l'utilisateur va le sentir passer ;-)



Il faudra bien structurer ses données d'une manière ou d'une autre...
Savoir où les placer... etc

et évidemment directement les problématiques de cache !



Les problématiques de cache sont là de toute façon à partir du moment ou
on sert des pages dynamiques, ça ne change rien de ce point de vue là.



Ajouter des données dans le dom de chaque page, c'est très différent
d'appeler un fichier JS externe qui fait des var ... = ... : le 2eme
pourra être caché et visible sans distinction de toute l'application.

Le libellé "êtes vous sûr", je peux le cacher pour 1 an sans problème,
la page toto de l'application par contre ça sera plutôt quelques heures.

Sinon par curiosité, en pratique tu procèdes comment ? Est-ce que tu
crées des templates JavaScript avec des substitutions de variables au
beau milieu de code, ou bien est-ce que tu isoles ce qui varie dans des
modules chargés séparément ?



J'ai été confronté aux 2 cas que je citais plus haut :

- une liste de trucs, par exemple membres du personnel. On a un menu qui
permet de lancer des actions après avoir sélectionné des éléments, mais
ces actions (la disponibilité mais éventuellement un pré-traitement
comme une demande de paramètres) sont conditionnées par des critères tel
que l'équipe du salarié sélectionné, son niveau hiérarchique, etc.
Ces informations ne sont pas affichées dans la liste...
=> soit on planque les données dans le tableau, soit on se créée un
objet JS correspondant à la liste, soit on fait du XHR si bcp d'éléments
dans la liste et/ou de données à utiliser dans le js (et de toute façon
on aura toujours besoin de l'id pour pouvoir faire sa requête côté serveur)

- les libellés dépendants de la langue et qui n'ont pas leur place dans
le HTML (message de confirmation, titre d'une lightbox, ...)
=> dans un JS externe généré dynamiquement (avec les bons entêtes pour
que ça reste longtemps en cache, et url contenant no version et langue),
à ce jour ça me semble la moins pire des solutions

Je ne suis pas développeur front-end, et c'est bien pour cela que je
participe à cette discussion, pour apprendre :).
Avatar
Olivier Miakinen
Le 09/12/2008 13:45, Pierre Goiffon a écrit :

Finalement on n'a pas tant de caractères à échapper, surtout si l'on
traite des chaînes sans retours chariot ce qui je suppose correspond à
la majorité des cas.



Oui. Ce qui me surprend le plus, c'est que même le caractère nul ne fait
pas partie des caractères interdits dans une chaîne, alors même qu'il
existe une séquence d'échappement spéciale rien que pour lui ().
Avatar
Alex Marandon
Pierre Goiffon wrote:
Si on part du principe qu'on peut se passer de communication entre
designer et programmeur, on va effectivement au devant de gros bugs,
quelle que soit la technique employée.



...
Votre remarque me laisse pantois ! Admettez que veiller à bien cacher
des données présentes dans le HTML uniquement pour servir au JavaScript
impose d'être vigilant !
Vous faites comme vous voulez, moi je privilégie ce qui est le plus
simple possible, ET introduit le moins de dépendances. Là ça ne respecte
pas du tout ces critères.



Quelque soit la technique employée, une modification inconsidérée du
HTML peut casser le JavaScript. Tout en ne s'affranchissant pas de cette
contrainte, la génération de JavaScript introduit une dépendance
supplémentaire côté serveur. C'est plus compliqué et ça rajoute du
couplage dans le système.

sans parler de la lourdeur du markup potentiellement généré,



C'est vrai que <input type="hidden"> l'utilisateur va le sentir passer
;-)



Il faudra bien structurer ses données d'une manière ou d'une autre...



Un petit coup de JSON peut-être ?

Savoir où les placer... etc



À la fin bien sûr.

et évidemment directement les problématiques de cache !



Les problématiques de cache sont là de toute façon à partir du moment
ou on sert des pages dynamiques, ça ne change rien de ce point de vue là.



Ajouter des données dans le dom de chaque page, c'est très différent
d'appeler un fichier JS externe qui fait des var ... = ... : le 2eme
pourra être caché et visible sans distinction de toute l'application.


> Le libellé "êtes vous sûr", je peux le cacher pour 1 an sans problème,

Oui tout, peut être mis en cache, il n'en reste pas moi que le client
veut des données à jour. Que le "êtes vous sûr" soit dans du JavaScript
ou du HTML, le jour ou il change il faudra récupérer la nouvelle version.

la page toto de l'application par contre ça sera plutôt quelques heures.



Tout à fait, dans la plupart des applications les pages ont déjà une
durée de vie plus courte que le code JavaScript. Y mettre des données
est donc à mon avis moins pénalisant que de les mettre dans le code
JavaScript.

J'ai été confronté aux 2 cas que je citais plus haut :

- une liste de trucs, par exemple membres du personnel. On a un menu qui
permet de lancer des actions après avoir sélectionné des éléments, mais
ces actions (la disponibilité mais éventuellement un pré-traitement
comme une demande de paramètres) sont conditionnées par des critères tel
que l'équipe du salarié sélectionné, son niveau hiérarchique, etc.
Ces informations ne sont pas affichées dans la liste...
=> soit on planque les données dans le tableau, soit on se créée un
objet JS correspondant à la liste, soit on fait du XHR si bcp d'éléments
dans la liste et/ou de données à utiliser dans le js (et de toute façon
on aura toujours besoin de l'id pour pouvoir faire sa requête côté serveur)

- les libellés dépendants de la langue et qui n'ont pas leur place dans
le HTML (message de confirmation, titre d'une lightbox, ...)
=> dans un JS externe généré dynamiquement (avec les bons entêtes pour
que ça reste longtemps en cache, et url contenant no version et langue),
à ce jour ça me semble la moins pire des solutions

Je ne suis pas développeur front-end, et c'est bien pour cela que je
participe à cette discussion, pour apprendre :).



Je dois reconnaitre que ces exemples sont pertinents. Le second exemple
me parle particulièrement. Merci pour ces précisions, moi aussi
j'apprends :)
Avatar
Alex Marandon
Olivier Miakinen wrote:
[...]
En clair, une chaîne délimitée par des quotes simples (respectivement
doubles), en dehors des séquences d'échappement dont je n'ai pas copié
la syntaxe, peut contenir tout caractère Unicode, sauf une quote simple
(respectivement double), un backslash, ou l'un des terminateurs de ligne
que sont LF (10), CR (13), LS (U+2028) et PS (U+2029).

Et donc les syntaxes suivantes sont invalides :
var invalid1 = 'aujourd'hui';
var invalid2 = 'tout de suite';
var invalid3 = 'et
maintenant';

En revanche les suivantes sont valides :
var valid1 = 'aujourd'hui';
var valid2 = 'tout de suite';
var valid3 = 'etrn maintenant';



Très instructif en effet, merci pour cette info.
1 2 3 4