web-dev-qa-db-fra.com

Moyen efficace de passer des variables de PHP à JavaScript

De temps en temps, je dois passer certaines variables de PHP à JS script .

var js-variable = "<?php echo $php-variable; ?>";

Mais c'est très moche et je ne peux pas cacher mon script JS dans un fichier .js car il doit être analysé par PHP. Quelle est la meilleure solution pour gérer cela? 

23
user606521

Si vous ne souhaitez pas utiliser PHP pour générer votre javascript (et que l'appel supplémentaire à votre serveur Web ne vous gêne pas), utilisez AJAX pour récupérer les données.

Si vous voulez utiliser PHP, encodez toujours avec json_encode avant de générer.

<script>
    var myvar = <?php echo json_encode($myVarValue); ?>;
</script>
35
ilanco

S'il vous plaît utiliser une api rest/rpc et passez json à votre js. Cela peut être fait de la manière suivante si vous utilisez jquery:

rest.php 

<?php echo "{name:biplav}" ?>

Ensuite, depuis votre js, faites un appel comme ceci:

var js_var;
$.get("rest.php", function(data) {
         js_var=data;
});

C’est l’exemple le plus simple auquel je puisse penser.

8
biplav
<?php
// filename: output-json.php
header('content-type:application/json;charset=utf-8');
printf('var foo = %s;', json_encode($foo, JSON_PRETTY_PRINT));

json_encode est une fonction robuste qui garantit que la sortie est codée et formatée en javascript/json valide. L'en-tête de type de contenu indique au navigateur comment interpréter la réponse.

Si votre réponse est vraiment JSON, telle que:

{"foo": 5}

Puis déclarez-le en tant que content-type:application/json;charset=utf-8. JSON est plus rapide à analyser et a beaucoup moins de chances d'être exploité par xss que javascript. Cependant, si vous devez utiliser du vrai javascript dans la réponse, par exemple:

var obj = {foo: 5};

Puis déclarez-le en tant que content-type:text/javascript;charset=utf-8 

Vous pouvez le lier comme un fichier:

<script src="output-json.php"></script>

Alternativement, il peut être pratique d’incorporer la valeur directement dans votre code HTML au lieu de faire une requête http séparée. Faites-le comme ça:

<script>
    <?php printf('var foo = %s;', json_encode($foo, JSON_HEX_TAG | JSON_PRETTY_PRINT)) ?>
</script>

Assurez-vous d'utiliser JSON_HEX_TAG si l'intégration dans votre code HTML via la balise <script> , sinon vous risquez des attaques par injection xss. Vous devrez peut-être également utiliser d'autres indicateurs pour plus de sécurité, en fonction du contexte dans lequel vous l'utilisez: JSON_HEX_AMP, JSON_HEX_QUOT, JSON_HEX_APOS. Ces indicateurs rendent la réponse moins lisible par l'homme, mais sont généralement bons pour la sécurité et la compatibilité, vous devriez donc probablement les utiliser.

Je tiens vraiment à souligner l’importance de la déclaration du type de contenu et de l’utilisation éventuelle de l’indicateur JSON_HEX_TAG, car ils peuvent contribuer à atténuer l’injection xss.

Faites pas faites ceci sauf si vous souhaitez tenter une attaque xss:

<script>
    var myvar = <?php echo json_encode($myVarValue); ?>;
</script>
7
goat

À mon avis, si vous devez transmettre une variable directement dans votre JS, votre application Web n'est probablement pas bien conçue.

J'ai donc deux astuces: * Utilisez les fichiers JSON pour les configurations générales, comme /js/conf/userprefs.json

{
    "avatar": "/img/users/123/avatar.jpg",
    "preferred_color": "blue"
    // ...
}
  • ou (meilleur moyen) vous pouvez récupérer vos confs json avec un appel AJAX.

Avec PHP frameworks tels que Symfony2, vous pouvez choisir un format dans votre configuration de routage, en laissant la sortie d'une variable au moteur de template (comme Twig).

Je fais un exemple pour les utilisateurs Symfony2 mais cela peut être utilisé par n’importe quel programmeur:

routage.yml

userprefs:
    pattern: /js/confs/userprefs.{_format}
    defaults: { _controller: CoreBundle:JsonPrefs:User, _format: json }
    requirements:
        _format: json
        _method: GET

Dans le contrôleur, vous pouvez effectuer toutes les requêtes nécessaires pour récupérer vos variables en les plaçant dans la vue:

Ressources/Vues/JsonPrefs/User.json

{
    "avatar": "{{ user.avatar }}",
    "preferred_color": "{{ user.preferred_color }}"
    // ...
}

Dans votre JS, vous pourrez maintenant récupérer le JSON avec un simple AJAX call . Pour des raisons de performances, vous pouvez mettre en cache les JSON (par exemple) avec Varnish. De cette façon, votre serveur n'a pas besoin de faire une requête à chaque fois que vous lisez les préférences de l'utilisateur.

3
Francesco Casula

Si vous modifiez votre fichier .htaccess pour inclure

 AddType application/x-httpd-php .js

vous pouvez utiliser un fichier .js et il sera géré par PHP, ce qui correspond à la moitié de ce dont vous avez besoin.

En ce qui concerne la gravité de cette solution, je dirais qu’il s’agit du mécanisme le moins laid. Vous pouvez essayer de transmettre votre script JS entier via un script PHP sous forme de chaîne, puis de rechercher et de remplacer les variables à insérer, mais je pense que vous conviendrez que cela est plus laid que la solution que vous êtes. utilise actuellement.

2
Eliot Ball

Placez tous vos fichiers .js dans un dossier et configurez votre serveur HTTP pour qu'il redirige toutes les demandes vers ces fichiers vers un fichier PHP qui charge les fichiers et les génère.

Supposons que vous avez Apache et que vos fichiers .js sont dans/js:

RewriteRule /js   /getjs.php

getjs.php:

<?php
header('Content-Type: text/javascript');
include_once($_SERVER['SCRIPT_NAME']);
?>
2
MaxArt

Pour éviter d’exécuter des fichiers .js avec l’analyseur PHP, vous ne pouvez pratiquement rien faire, sauf peut-être récupérer la valeur de js-variable via un appel AJAX.

Aussi, vous pouvez envisager de sortir la valeur comme ceci:

var js_variable = <?php echo json_encode ($php_variable); ?>

pour échapper à toutes les choses qui casseraient votre javascript.

1
wroniasty

À tout le moins, vous pouvez utiliser un shortcode PHP pour rendre votre solution "laide" un peu plus propre:

var js-variable = "<?= $php-variable ?>";
0
Kevin