OVH Cloud OVH Cloud

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.

10 réponses

1 2 3 4
Avatar
SAM
Le 12/8/08 7:43 PM, Olivier Miakinen a écrit :

il faut savoir que
je suis en train de découvrir les bases de données (j'ai commencé jeudi
dernier à lire une doc de référence) et que je fais juste des petites
pages de test pour voir ce que ça donne. Pour l'une d'elles, j'ai fait
un formulaire dans lequel on est invité à saisir un texte, et mon
programme PHP vérifie que le texte saisi est le même que celui qu'on
avait déjà saisi précédemment. L'endroit où j'ai généré du JavaScript
directement à partir de PHP, c'est la fonction optionnelle qui vérifie
la même chose en JavaScript avant de faire la requête au serveur.



Je ne sais pas si je n'aurais pas demandé au php d'écrire le texte
(qu'il vient de recevoir) dans un champs ou fenêtre de texte caché,
le JS n'ayant plus alors qu'à comparer le contenu des 2 champs (celui
caché et celui où on doit réciter).

à mon avis, vu de ma chaise, le php aura su remplir, avec un simple
echo, le champ caché comme il le doit
(sans se casser la tête avec des échanges de par \ )

Cela dit, je n'ai pas su trouver (mais j'ai sans doute mal cherché) des
tutoriels donnant quelques méthodes standard du style « page de login »,
« changement de mot de passe », etc.



Bon, je viens d'essayer,
- J'ai un seul champ de texte nommé 'texte'
- J'y entre : bnr? é trans puis /
- ça envoie bien urlisé : bnr? é trans puis /
- mais au retour dans un string JS nourri par php $_GET['texte']
le t de trans est vu comme une tabulation

Mékilébête ce JS !

Le truc du champs caché comparé par JS semble bien fonctionner.
(textarea à remplir + input type=hidden)
(password à confirmer + input password disabled)

Bon ... ce fut un essai simple
et sans moulinage en BdD qui saura réserver ses surprises.

--
sm
Avatar
Olivier Miakinen
Le 08/12/2008 23:55, SAM a écrit :

Je ne sais pas si je n'aurais pas demandé au php d'écrire le texte
(qu'il vient de recevoir) dans un champs ou fenêtre de texte caché,
le JS n'ayant plus alors qu'à comparer le contenu des 2 champs (celui
caché et celui où on doit réciter).



C'est exactement ce que proposait Alex. Je viens d'essayer, et ça marche
parfaitement. Il me suffit de comparer le « value » de l'élément input
avec le « firstChild.nodeValue » de ce nouveau div ou span.

[...]

Bon, je viens d'essayer,
- J'ai un seul champ de texte nommé 'texte'
- J'y entre : bnr? é trans puis /
- ça envoie bien urlisé : bnr? é trans puis /



C'est parfait.

- mais au retour dans un string JS nourri par php $_GET['texte']



Gniii ?
Avatar
mpg
Le (on) lundi 08 décembre 2008 17:06, Olivier Miakinen a écrit (wrote) :

$from >>> array("", "'", '"', "r", "n", "xE2x80xA8", "xE2x80xA9");
$to >>> array('\', ''', '"', 'r', 'n', 'u2028', 'u2029');
return str_replace($from, $to, $str);



Désolé, mais je connais mal PHP (je suis plutôt Java), mais je comprend
mal ce que va donner les changement de "r" et "n" en 'r' et 'n'.
Peux-tu m'éclairer, STP ?



Oui, bien sûr. "n" représente l'unique caractère dont le code ASCII ou
Unicode est 10, tandis que 'n' est une chaîne de deux caractères, de
codes respectifs 92 () et 110 (n). Pour info, 'n' signifie la même
chose que "n". Idem avec "r" (code 13) et 'r' (égal à "r").



Si je peux me permettre, niveau lisibilité du code, je préfère vachement
voir remplacer "r" par "r" que "r" par 'r'. Enfin, les goûts et les
couleurs...

Manuel.
Avatar
SAM
Le 12/9/08 12:55 AM, Olivier Miakinen a écrit :
Le 08/12/2008 23:55, SAM a écrit :
Je ne sais pas si je n'aurais pas demandé au php d'écrire le texte
(qu'il vient de recevoir) dans un champs ou fenêtre de texte caché,
le JS n'ayant plus alors qu'à comparer le contenu des 2 champs (celui
caché et celui où on doit réciter).



C'est exactement ce que proposait Alex. Je viens d'essayer, et ça marche
parfaitement. Il me suffit de comparer le « value » de l'élément input
avec le « firstChild.nodeValue » de ce nouveau div ou span.



sauf que je proposais de rester en DOM.0 ;-)

- mais au retour dans un string JS nourri par php $_GET['texte']



Gniii ?



get ou post ça marche pareil.


PHP:
=== $txt = (isset($_GET['texte'])? $_GET['texte'] : '';

JS en KKbouilla :
================ var txt = '<?php echo $txt ?>';

Mieux avec

html :
===== <form onsubmit="return verif()" method="get" action="test.php">
<?php if($txt != '') { ?>
<input type="hidden" name="texte2" value="<?php echo $txt ?>">
Récitez
<?php
} else {
echo 'Entrez';
}
?>
votre texte :
<textarea name="texte"></textarea>
<input type="submit">
</form>

et

JS :
=== function verif() {
var f = document.forms[0];
if(f.texte2 && f.texte2.value != '') {
if(f.texte.value != f.texte2.value) {
alert('erreur de récitation');
f.texte.focus();
return false;
}
}
return true;
}
Avatar
Pierre Goiffon
Olivier Miakinen wrote:
A première vue du moment que la chaine ne contient pas de ' et vu ce qui
a été dis (page en UTF-8 et tous les caractères sont corrects) alors
qu'est-ce qui ne pourrait pas aller ?



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 ?
Avatar
Pierre Goiffon
Alex Marandon wrote:
on évite en
général de génerer du JavaScript dynamiquement.







Mais on n'a pas toujours le choix...

Et c'est la plupart du temps pour définir des chaines qui seront
utilisées par le JS qu'on le fait ! Ne serait-ce que pour
l'internationalisation...

Pour le reste, XHR permet beaucoup plus de souplesse et évite de
beaucoup la génération de code dynamique dont on avait besoin avant (par
exemple 2 menus déroulant, chaque valeur sélectionnée dans le 1er va
peupler avec les options correspondantes le 2eme).

Il y a d'abord le problème inhérent à la génération de code en général,
on se retrouve avec deux niveaux de code à débugguer, écrits dans deux
langages différents.



Indéniable.

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 : pour le prb évoqué plus haut, on va avoir
tendance à laisser ce qui est généré dynamiquement "tout seul".

Mais je ne comprend pas pourquoi vous parlez du cache ? Ce n'est aps
parce que l'on génère du JavaScript dynamiquement côté serveur que l'on
ne pourra pas renvoyer les bons entêtes, au contraire !

Après, si tu es de ceux qui pensent que mélanger HTML, CSS,
SQL, JavaScript et PHP dans un même fichier ne pose pas de problèmes
particuliers, ce dernier argument ne te parles probablement pas :)



Moteurs de templates, architectures n tiers, tous les outils sont
disponibles pour éviter de "tout mélanger", séparer en couches et faire
en sorte que la présentation reste de la présentation uniquement.

Reste que l'on a toujours le besoin de fournir à JavaScript des données
et que XHR n'est pas la réponse miracle.
Avatar
Alex Marandon
Pierre Goiffon 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 : pour le prb évoqué plus haut, on va avoir
tendance à laisser ce qui est généré dynamiquement "tout seul".

Mais je ne comprend pas pourquoi vous parlez du cache ? Ce n'est aps
parce que l'on génère du JavaScript dynamiquement côté serveur que l'on
ne pourra pas renvoyer les bons entêtes, au contraire !



Tout à fait, 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). Pour envoyer les bons
entêtes, il faudra détecter les changement de données (difficile) alors
que si le fichier ne contient que du code, le serveur web peut se
charger d'envoyer les Last-Modified/ETag qui conviennent en se basant
sur la date de modification du fichier. Mélanger code et données exclut
également l'utilisation d'un champ Expires avec une date dans un futur
lointain (à moins de changer le nom du fichier quand les données
changent, ce qui serait un peu tordu).

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. Pense à une
application bureautique, un traitement de texte par exemple. Il ne
viendrait pas à l'esprit de générer un nouvel exécutable de
l'application à chaque modification du document. On conserve les données
bien séparées du code exécutable. Pour une application bureautique on
voit tout de suite que ce serait aberrant à cause du mode de
construction (compilation) et de déploiement (installation dans le
PATH). Dans le cas de JavaScript, c'est moins évident à cause du mode de
déploiement : il est trés (trop?) facile de construire et réinstaller
l'application à chaque changement des données (moyennant les problèmes à
l'origine de ce fil). Il y a pourtant au sein des navigateurs web un
mécanisme pour représenter les données de façon indépendante du code et
c'est le DOM.

Pour parler plus concrètememt, si on a besoin des données au chargement
de la page, on peut les mettre dans le HTML. Pour le reste, il y a XHR.
Avatar
Pierre Goiffon
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 ?

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 ! Pour moi c'est déplacer le problème vers l'intégrateur
HTML 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... sans
parler de la lourdeur du markup potentiellement généré, et évidemment
directement les problématiques de cache !
Avatar
Olivier Miakinen
Le 09/12/2008 09:42, Pierre Goiffon a écrit :

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.

J'essaye de donner des informations précises pour pouvoir s'y référer.
Le document de référence que j'ai lu est :
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf

Les syntaxes qui nous intéressent se trouvent dans le paragraphe « 7.8.4
String Literals » :
-----------------------------------------------------------------------
StringLiteral ::
" DoubleStringCharacters(opt) "
' SingleStringCharacters(opt) '

DoubleStringCharacters ::
DoubleStringCharacter DoubleStringCharacters(opt)

SingleStringCharacters ::
SingleStringCharacter SingleStringCharacters(opt)

DoubleStringCharacter ::
SourceCharacter but not double-quote " or backslash or
LineTerminator
EscapeSequence

SingleStringCharacter ::
SourceCharacter but not single-quote ' or backslash or
LineTerminator
EscapeSequence
-----------------------------------------------------------------------

SourceCharacter est défini au paragraphe « 5.1.5 Grammar Notation » :
-----------------------------------------------------------------------
SourceCharacter ::
any Unicode character
-----------------------------------------------------------------------

Quant à LineTerminator, il est défini au paragraphe « 7.3 Line
Terminators » :
-----------------------------------------------------------------------
The following characters are considered to be line terminators:
Code Point Value Name Formal Name
u000A Line Feed <LF>
u000D Carriage Return <CR>
u2028 Line separator <LS>
u2029 Paragraph separator <PS>

LineTerminator ::
<LF>
<CR>
<LS>
<PS>
-----------------------------------------------------------------------


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';


Cordialement,
--
Olivier Miakinen
Avatar
Cenekemoi
Bonjour à mpg qui nous a écrit :
Si je peux me permettre, niveau lisibilité du code, je préfère
vachement voir remplacer "r" par "r" que "r" par 'r'. Enfin, les
goûts et les couleurs...

Manuel.



+1

--
Cordialement, Thierry ;-)
1 2 3 4