web-dev-qa-db-fra.com

Est-il considéré comme une mauvaise pratique d'avoir PHP dans votre JavaScript

Tant de fois sur ce site, je vois des gens essayer de faire des choses comme ça:

<script type="text/javascript">
  $(document).ready(function(){

     $('<?php echo $divID ?>').click(funtion(){
       alert('do something');
     });

  });
</script>

Je ne pense pas que ce soit une sorte de schéma dans lequel les gens tombent naturellement. Il doit y avoir une sorte de tutoriel ou de matériel d'apprentissage qui le montre, sinon nous ne le verrions pas autant. Ce que je demande, c'est si je m'en occupe trop ou est-ce vraiment une mauvaise pratique?

EDIT: En parlait à un ami à moi qui met souvent Ruby dans son JavaScript et il a soulevé ce point.

Est-il correct de placer dynamiquement des constantes larges d'application dans votre JavaScript afin que vous n'ayez pas à modifier deux fichiers. par exemple...

MYAPP.constants = <php echo json_encode($constants) ?>;

est-il également possible de coder directement les données que vous prévoyez d'utiliser dans une bibliothèque

ChartLibrary.datapoints = <php echo json_encode($chartData) ?>;   

ou devrions-nous faire un AJAX appel à chaque fois?

55
Greg Guida

En règle générale, il est une mauvaise pratique d'utiliser la langue X pour générer du code dans la langue Y.

Essayez de découpler les deux langues en faisant des données leur seule interface - ne mélangez pas le code .

Dans votre exemple, vous pouvez améliorer le code en utilisant PHP pour remplir une structure cfg disponible pour JavaScript:

<script type="text/javascript">
  var cfg = {
    theId: "<?php echo $divID ?>",
    ...
  };

  $(document).ready(function(){
     $("#" + cfg.theId).click(funtion(){
       alert('do something');
     });
  });
</script>

De cette façon, PHP ne se soucie que de remplir la structure de données et JavaScript ne se soucie que de consommer la structure de données.

Ce découplage ouvre également la voie au chargement asynchrone des données (JSON) à l'avenir.

Mise à jour:

Pour répondre aux questions supplémentaires que vous avez posées avec votre mise à jour, oui, il serait judicieux d'appliquer le principe DRY et de laisser PHP et JavaScript partager la même configuration) objet:

<script type="text/javascript">
  var cfg = <?php echo json_encode($cfg) ?>;

  ...

Il n'y a aucun mal à insérer la représentation JSON de votre configuration directement dans votre page comme ceci. Vous n'avez pas nécessairement à le récupérer via XHR.

83
Ates Goral

JavaScript généré dynamiquement est une horrible et mauvaise pratique.

Ce que vous êtes censé faire, c'est comprendre ce que signifie la séparation des préoccupations et l'amélioration progressive.

Cela signifie essentiellement que vous avez du HTML dynamique et du JavaScript statique (ce qui améliore le HTML).

Dans votre cas, vous voulez probablement une classe sur votre div et sélectionnez-la avec un sélecteur de classe

21
Raynos

Le plus gros problème avec votre extrait de code est que vous manquez le # pour en faire un sélecteur jQuery valide;).

Je dirais que vous devriez essayer d'éviter d'inclure PHP dans votre JavaScript si possible. Qu'est-ce qui ne va pas en changeant le sélecteur dans votre gestionnaire click() en classe et en ajoutant la classe à l'élément en question si vous le souhaitez le gestionnaire à renvoyer, et pas si vous ne le faites pas;

<script type="text/javascript">
  $(document).ready(function(){

     $('.foo').click(funtion(){
       alert('do something');
     });

  });
</script> 

<div id="bar" class="<?php echo ($someCond ? 'foo' : ''); ?>">Hello</div>

Il y a existe circonstances où vous devez inclure PHP dans votre JavaScript; mais je dois admettre que ce sont peu nombreuses et espacées).

Un exemple est quand vous avez différents environnements; tester, mettre en scène et vivre. Chacun d'eux a un emplacement différent de vos actifs (images, principalement). Le moyen le plus simple de définir le chemin afin qu'il puisse être utilisé par JavaScript est quelque chose comme;

var config = { assets: "<?php echo $yourConfig['asset_url']; ?>" };
10
Matt

C'est une mauvaise pratique à mon avis, car vous auriez besoin d'appeler ce fichier quelque chose.php et vous ne pourriez pas le compresser par exemple, sans mentionner qu'il n'est pas correct de mélanger votre serveur avec votre JavaScript. Essayez de limiter autant que possible le mélange entre PHP et JS.

Vous pouvez toujours le faire à la place:

function setOnClick(divid) {
 $(divid).click(funtion(){
   alert('do something');
 });
}

Et puis vous pourriez appeler cette fonction dans un fichier php, pour rendre ces choses de mélange aussi petites que possible.

$(function() {
  setOnClick('<?php echo $divId; ?>');
});

En faisant cela (avoir des fichiers JS plus gros, pas 2-3 lignes où cela n'a pas d'importance), vous pouvez profiter de la compression du fichier JS et les développeurs frontaux se sentent très à l'aise de travailler uniquement avec JavaScript à mon avis (comme vous pourriez l'écrire Python, Ruby etc non seulement PHP - et le code pourrait devenir de plus en plus gros selon ce que vous devez faire là-bas).

8
alessioalex

Je ne pense pas que ce soit une mauvaise pratique. Si l'ID requis dans votre JavaScript est dynamique, il n'y a pas d'autre moyen de le faire.

6
CodeZombie

Je considérerais cette mauvaise pratique. Lorsque vous placez du contenu dynamique dans des blocs de script, vous devez toujours être conscient du fait que s'échapper à l'intérieur d'un contexte javascript n'est pas aussi simple que vous l'espérez. Si les valeurs ont été fournies par l'utilisateur, il n'est pas suffisant pour les échapper en HTML.

Le Aide-mémoire OWASP XSS a plus de détails, mais en gros, vous devriez adopter ce modèle:

<script id="init_data" type="application/json">
    <?php echo htmlspecialchars(json_encode($yourdata)); ?>
</script>

Ensuite, dans un fichier .js distinct lié à partir de votre html principal, chargez ce code:

var dataElement = document.getElementById('init_data');
var jsonText = dataElement.textContent || dataElement.innerText  // unescapes the content of the span
var initData = JSON.parse(jsonText);

La raison d'utiliser un fichier .js distinct est double:

  • Il peut être mis en cache, donc les performances sont meilleures
  • L'analyseur HTML n'est pas déclenché, donc il n'y a aucun risque qu'un bogue XSS ne se glisse à travers par quelqu'un mettant une balise <? Php rapide quelque part
6
Joeri Sebrechts

Je dirais qu'en général ne le faites pas. Cependant, si vous voulez passer des données de PHP -> Javascript, il ne me semblerait pas fou d'avoir un bloc Javascript en ligne où vous avez du code de la forme indiquée ci-dessous. Ici, le code ne fait que passer données de php à javascript, ne créant pas de logique à la volée ou similaire. La bonne partie de cela par rapport à un appel ajax est que les données sont disponibles dès que la page se charge et ne nécessite pas de voyage supplémentaire vers le serveur.

<script>
window.config = <?php echo json_encode($config);?>;
</script>

Bien sûr, une autre option consiste à créer un fichier de configuration javascript à partir de PHP via une forme de script de construction qui le mettra dans un fichier .js.

5
Zachary K

Certaines personnes diraient que c'est une mauvaise pratique. Non pas parce que c'est PHP dans JS, mais parce que c'est JS en ligne et donc ne sera pas mis en cache par le navigateur pour faciliter le chargement la prochaine fois.

OMI, il est toujours préférable d'utiliser JSON pour passer des variables entre les 2 langues, mais je suppose que cela dépend de vous.

5
Nick

La seule chose à laquelle je peux penser qui peut vraiment causer des problèmes est quand PHP sont définies pour être affichées et donc cela pousse une charge de HTML montrant le PHP erreur dans votre JavaScript.

Aussi parce que c'est dans le script, il ne s'affiche donc pas et il peut parfois prendre un certain temps pour comprendre pourquoi votre script est cassé.

4
Alex Coplan

Cela dépend de qui, et si vous me demandez, oui, je considère que c'est une pratique de retour pour plusieurs raisons. Tout d'abord, je préférerais avoir du code javascript dans son propre fichier JS que l'analyseur php ne pourrait pas toucher.

Deuxièmement, php s'exécute uniquement au moment du serveur, donc si vous dépendez d'une variable de php pour changer votre javascript, cela peut ne pas fonctionner très bien. S'il y a un paramètre de chargement de page que vous souhaitez contrôler avec javascript, je préfère généralement ajouter cette valeur au DOM avec php afin que javascript puisse l'atteindre quand et s'il le souhaite (dans un div caché, par exemple).

Enfin, juste à des fins d'organisation, cela peut devenir très ennuyeux. C'est déjà assez mauvais de mélanger du HTML et du PHP (à mon avis).

3
Explosion Pills

Contenant le PHP dans un objet de données config va à 90% du chemin, mais la meilleure pratique est de le séparer entièrement. Vous pouvez utiliser une API RESTful pour demander uniquement les données que vous besoin, c'est un peu plus javascript mais avec quelques avantages.

  • Le script est statique et peut être mis en cache de façon permanente
  • PHP n'est plus un vecteur XSS
  • Séparation complète des préoccupations

Inconvénients:

  • Nécessite une requête HTTP supplémentaire
  • javascript plus complexe

Scénario

//pure javascript
$.on('domready',function({
    //load the data
    $.get({
       url:'/charts/3D1A2E', 
       success: function(data){
           //now use the chart data here
           ChartModule.init(data);
       }
    });
})
1
roo2