Question Comment passer des variables et des données de PHP à JavaScript?


J'ai une variable en PHP, et j'ai besoin de sa valeur dans mon code JavaScript. Comment puis-je obtenir ma variable de PHP en JavaScript?

J'ai un code qui ressemble à ceci:

<?php
     ...
     $val = $myService->getValue(); // makes an api and db call
?>

J'ai le code JavaScript qui a besoin val et ressemble à:

<script>
    myPlugin.start($val); // tried this, didn't work
    <?php myPlugin.start($val); ?> // this didn't work either
    myPlugin.start(<?=$val?> // this works sometimes, but sometimes it fails
</script>

546
2018-05-19 14:37


origine


Réponses:


Il existe actuellement plusieurs approches pour le faire. Certains nécessitent plus de frais généraux que d'autres, et certains sont considérés comme meilleurs que d'autres.

Dans aucun ordre particulier:

  1. Utilisez AJAX pour obtenir les données dont vous avez besoin sur le serveur.
  2. Écho des données dans la page quelque part, et utiliser JavaScript pour obtenir les informations du DOM.
  3. Echo les données directement à JavaScript.

Dans ce post, nous allons examiner chacune des méthodes ci-dessus, et voir les avantages et les inconvénients de chacun, ainsi que la façon de les mettre en œuvre.

1. Utilisez AJAX pour obtenir les données dont vous avez besoin du serveur

Cette méthode est considérée comme la meilleure, car vos scripts côté serveur et côté client sont complètement séparés.

Avantages

  • Meilleure séparation entre les couches - Si demain vous arrêtez d'utiliser PHP, et que vous voulez passer à une servlet, une API REST, ou un autre service, vous n'avez pas besoin de changer une grande partie du code JavaScript.
  • Plus lisible - JavaScript est JavaScript, PHP est PHP. Sans mélanger les deux, vous obtenez un code plus lisible sur les deux langues.
  • Permet le transfert de données asynchrone - Obtenir l'information de PHP pourrait être temps / ressources chères. Parfois, vous ne voulez pas attendre l'information, charger la page et avoir l'information à portée de main.
  • Les données ne se trouvent pas directement dans le balisage - Cela signifie que votre balisage reste propre de toute donnée supplémentaire, et seul JavaScript le voit.

Les inconvénients

  • Latence - AJAX crée une requête HTTP, et les requêtes HTTP sont transmises sur le réseau et ont des latences réseau.
  • Etat - Les données récupérées via une requête HTTP séparée n'incluent aucune information de la requête HTTP qui a récupéré le document HTML. Vous pouvez avoir besoin de ces informations (par exemple si le document HTML est généré en réponse à une soumission de formulaire) et, si vous le faites, devrez le transférer d'une manière ou d'une autre. Si vous avez exclu l'intégration des données dans la page (ce que vous avez si vous utilisez cette technique), cela vous limite aux cookies / sessions qui peuvent être soumis à des conditions de course.

Exemple d'implémentation

Avec AJAX, vous avez besoin de deux pages, l'une où PHP génère la sortie, et l'autre où JavaScript obtient cette sortie:

get-data.php

/* Do some operation here, like talk to the database, the file-session
 * The world beyond, limbo, the city of shimmers, and Canada.
 * 
 * AJAX generally uses strings, but you can output JSON, HTML and XML as well. 
 * It all depends on the Content-type header that you send with your AJAX
 * request. */

echo json_encode(42); //In the end, you need to écho the result. 
                      //All data should be json_encode ()d.

                      //You can json_encode() any value in PHP, arrays, strings,
                      //even objects.

index.php (ou quelle que soit la page en question)

<!-- snip -->
<script>
    function reqListener () {
      console.log(this.responseText);
    }

    var oReq = new XMLHttpRequest(); //New request object
    oReq.onload = function() {
        //This is where you handle what to do with the response.
        //The actual data is found on this.responseText
        alert(this.responseText); //Will alert: 42
    };
    oReq.open("get", "get-data.php", true);
    //                               ^ Don't block the rest of the execution.
    //                                 Don't wait until the request finishes to 
    //                                 continue.
    oReq.send();
</script>
<!-- snip -->

La combinaison ci-dessus des deux fichiers alertera 42 lorsque le fichier est terminé.

Un peu plus de matériel de lecture

2. Echo les données dans la page quelque part, et utiliser JavaScript pour obtenir les informations du DOM

Cette méthode est moins préférable à AJAX, mais elle a encore ses avantages. C'est toujours relativement séparé entre PHP et JavaScript dans un sens qu'il n'y a pas de PHP directement dans le JavaScript.

Avantages

  • Vite - Les opérations DOM sont souvent rapides et vous pouvez stocker et accéder à un grand nombre de données relativement rapidement.

Les inconvénients

  • Balisage potentiellement insémantique - Habituellement, ce qui se passe est que vous utilisez une sorte de <input type=hidden> pour stocker les informations, car il est plus facile d'obtenir l'information de inputNode.value, mais cela signifie que vous avez un élément dénué de sens dans votre code HTML. HTML a le <meta> élément pour les données sur le document, et HTML 5 introduit data-* attributs pour les données spécifiquement pour la lecture avec JS qui peuvent être associés à des éléments particuliers.
  • Dirty up la source - Les données générées par PHP sont envoyées directement à la source HTML, ce qui signifie que vous obtenez une source HTML plus grande et moins ciblée.
  • Plus difficile d'obtenir des données structurées - Les données structurées devront être en HTML valide, sinon vous devrez vous échapper et convertir les chaînes vous-même.
  • Couples étroitement PHP à votre logique de données - Parce que PHP est utilisé dans la présentation, vous ne pouvez pas séparer les deux proprement.

Exemple d'implémentation

Avec cela, l'idée est de créer une sorte d'élément qui ne sera pas affiché pour l'utilisateur, mais visible pour JavaScript.

index.php

<!-- snip -->
<div id="dom-target" style="display: none;">
    <?php 
        $output = "42"; //Again, do some operation, get the output.
        echo htmlspecialchars($output); /* You have to escape because the result
                                           will not be valid HTML otherwise. */
    ?>
</div>
<script>
    var div = document.getElementById("dom-target");
    var myData = div.textContent;
</script>
<!-- snip -->

3. Echo les données directement à JavaScript

C'est probablement le plus facile à comprendre et le plus horrible à utiliser. Ne fais pas ça à moins de savoir ce que tu fais.

Avantages

  • Très facilement mis en œuvre - Il faut très peu pour l'implémenter et comprendre.
  • Ne pas source sale - Les variables sont sorties directement en JavaScript, donc le DOM n'est pas affecté.

Les inconvénients

  • Peu sûr - PHP n'a pas de fonctions d'échappement JavaScript triviales, et elles ne sont pas triviales à implémenter. Surtout lors de l'utilisation des entrées utilisateur, vous êtes extrêmement vulnérables aux injections de deuxième niveau. Contesté voir les commentaires
  • Couples étroitement PHP à votre logique de données - Parce que PHP est utilisé dans la présentation, vous ne pouvez pas séparer les deux proprement.
  • Les données structurées sont difficiles - Vous pouvez probablement faire JSON ... un peu. Mais XML et HTML exigeront une attention particulière.

Exemple d'implémentation

La mise en œuvre est relativement simple:

<!-- snip -->
<script>
    var data = <?php echo json_encode("42", JSON_HEX_TAG); ?>; //Don't forget the extra semicolon!
</script>
<!-- snip -->

Bonne chance!


738
2018-05-19 14:37



Je vais essayer une réponse plus simple:

Explication du problème

Tout d'abord, comprenons le flux des événements lorsqu'une page est diffusée depuis notre serveur:

  • Le premier PHP est exécuté, il génère le HTML qui est servi au client.
  • Ensuite, le code HTML est livré au client, une fois que PHP est terminé, je tiens à souligner qu'une fois que le code quitte le serveur - PHP est fait avec et ne peut plus y accéder.
  • Ensuite, le code HTML avec JavaScript atteint le client, qui peut exécuter JS sur ce code HTML.

Donc, vraiment, la chose essentielle à retenir ici est que HTTP est sans état. Une fois qu'une demande a quitté le serveur, le serveur ne peut pas le toucher. Donc, cela laisse nos options à:

  1. Envoyer plus de demandes du client après la demande initiale est terminée.
  2. Encodez ce que le serveur avait à dire dans la demande initiale.

Solutions

C'est la question fondamentale que vous devriez vous poser:

Est-ce que j'écris un site web ou une application?

Les sites Web sont principalement basés sur des pages, et les temps de chargement des pages doivent être aussi rapides que possible (par exemple - Wikipedia). Les applications Web sont plus lourdes AJAX et effectuent beaucoup d'allers-retours pour obtenir rapidement des informations sur le client (par exemple, un tableau de bord de stock).

Site Internet

Envoyer plus de demandes du client après la demande initiale est lent car cela nécessite plus de requêtes HTTP qui ont un surcoût important. De plus, il nécessite asynchronisme comme faire une requête AJAX nécessite un gestionnaire pour quand il est terminé.

je voudrais ne pas recommander de faire une autre demande sauf si votre site est une application pour obtenir cette information du serveur.

Vous voulez des temps de réponse rapides qui ont un énorme impact sur les temps de conversion et de chargement. Faire des requêtes ajax est lent pour la disponibilité initiale dans ce cas et inutile.

Vous avez deux façons de résoudre le problème

  • Définir un cookie - les cookies sont des en-têtes envoyés dans des requêtes HTTP que le serveur et le client peuvent lire.
  • Encoder la variable en JSON - JSON semble très proche des objets JavaScript et plus Les objets JSON sont des variables JavaScript valides.

Définir un cookie n'est vraiment pas très difficile, vous lui attribuez simplement une valeur:

setcookie("MyCookie", $value); // sets the cookie to the value, remember, do not
                               // set it with HTTP only to true.

Ensuite vous pouvez le lire avec JavaScript en utilisant document.cookie:

Voici un petit analyseur roulé à la main, mais la réponse à laquelle je suis lié juste au-dessus de celui-ci a mieux testé ceux:

var cookies = document.cookie.split(";").
    map(function(el){ return el.split("="); }).
    reduce(function(prev,cur){ prev[cur[0]] = cur[1];return prev },{});

cookies["MyCookie"] // value set with php.

Les cookies sont bons pour un peu de données. C'est ce que font souvent les services de suivi.

Une fois que nous avons plus de données, nous pouvons l'encoder avec JSON dans une variable JS à la place:

<script>
    var myServerData = <?=json_encode($value)?>; // don't forget to sanitize 
                                                 //server data
</script>

En supposant $value est json_encodecapable du côté PHP (c'est généralement le cas). Cette technique est ce que StackOverflow fait avec son chat par exemple (en utilisant seulement .net au lieu de php).

Application

Si vous écrivez une application, le temps de chargement initial n'est pas toujours aussi important que la performance continue de l'application et commence à payer pour charger les données et le code séparément.

Ma réponse ici explique comment charger des données en utilisant AJAX en JavaScript:

function callback(data){
    // what do I do with the response?
}

var httpRequest = new XMLHttpRequest;
httpRequest.onreadystatechange = function(){
    if (httpRequest.readyState === 4) {// request is done
        if (httpRequest.status === 200) {// successfully
            callback(httpRequest.responseText);// we're calling our method
        }
    }
};
httpRequest.open('GET', "/echo/json");
httpRequest.send();

Ou avec jQuery:

$.get("/your/url").done(function(data){
    // what do I do with the data?
});

Maintenant, le serveur doit juste contenir un /your/url route / fichier qui contient du code qui saisit les données et fait quelque chose avec lui, dans votre cas:

<$php
 ...
 $val = myService->getValue(); // makes an api and db call
 echo json_encode($val); // write it to the output
 $>

De cette façon, notre fichier JS demande les données et les affiche plutôt que de demander du code ou de la mise en page. Ceci est plus propre et commence à porter ses fruits lorsque l'application devient plus élevée. C'est aussi une meilleure séparation des préoccupations et cela permet de tester le code côté client sans aucune technologie côté serveur qui est un autre avantage.

Postscript: Vous devez être très au courant des vecteurs d'attaque XSS lorsque vous injectez quelque chose de PHP en JavaScript. Ses très difficile d'échapper aux valeurs correctement et il est sensible au contexte. Si vous ne savez pas comment gérer XSS, ou si vous ne le savez pas, veuillez lire cet article OWASP, celui-là et cette question.


79
2018-05-19 15:02



J'utilise habituellement les attributs data- * en html.

<div class="service-container" data-service="<?php echo $myService->getValue(); ?>">

</div>

<script>
$(document).ready(function() {
    $('.service-container').each(function() {
        var container = $(this);
        var service = container.data('service');

        // service variable now contains the value of $myService->getValue();
    });
});
</script>

Cet exemple utilise jQuery mais peut être adapté pour une autre bibliothèque ou Javascript en vanille.

Vous pouvez en savoir plus sur la propriété dataset ici: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset


69
2018-05-22 17:14



<script>
  var jsvar = <?php echo json_encode($PHPVar); ?>;
</script>

json_encode () nécessite:

  • PHP 5.2.0 ou plus
  • $PHPVar codé comme UTF-8, Unicode.

32
2017-07-18 22:00



Utilisez simplement l'une des méthodes suivantes.

<script type="text/javascript">
var js_variable  = '<?php echo $php_variable;?>';
<script>

OU 

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

12
2018-04-13 18:59



J'aime bien la façon dont le Wordpress fonctionne avec enqueue et localiser fonctions, donc en suivant ce modèle, j'ai écrit une classe simple pour mettre un script en page en fonction des dépendances de script, et pour rendre des données supplémentaires disponibles pour le script.

class mHeader {

    private $scripts = array();

    /**
     * @param string $id        unique script identifier
     * @param string $src   script src attribute
     * @param array  $deps      an array of dependencies ( script identifiers ).
     * @param array  $data      an array, data that will be json_encoded and available to the script.
     */
    function enqueue_script( $id, $src, $deps = array(), $data = array() ) {
        $this->scripts[$id] = array( 'src' => $src, 'deps' => $deps, 'data' => $data );
    }

    private function dependencies( $script ) {
        if ( $script['deps'] ) {
            return array_map( array( $this, 'dependencies' ), array_intersect_key( $this->scripts, array_flip( $script['deps'] ) ) );
        }
    }

    private function _unset( $key, &$deps, &$out ) {
        $out[$key] = $this->scripts[$key];
        unset( $deps[$key] );
    }

    private function flattern( &$deps, &$out = array() ) {

        foreach( $deps as $key => $value ) {            
            empty($value) ? $this->_unset( $key, $deps, $out ) : $this->flattern( $deps[$key], $out );
        }
    }   

    function print_scripts() {

        if ( !$this->scripts ) return;

        $deps = array_map( array( $this, 'dependencies' ), $this->scripts );
        while ( $deps ) 
            $this->flattern( $deps, $js );

        foreach( $js as $key => $script ) {
            $script['data'] && printf( "<script> var %s = %s; </script>" . PHP_EOL, key( $script['data'] ), json_encode( current( $script['data'] ) ) );
            echo "<script id=\"$key-js\" src=\"$script[src]\" type=\"text/javascript\"></script>" . PHP_EOL;
        }
    }
}

Appeler pour enqueue_script() La fonction permet d'ajouter un script, de définir la source et les dépendances sur d'autres scripts, ainsi que les données supplémentaires nécessaires au script.

$header = new mHeader();

$header->enqueue_script( 'jquery-ui', '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js', array( 'jquery' ) );
$header->enqueue_script( 'jquery', '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js' );
$header->enqueue_script( 'custom-script', '//custom-script.min.js', array( 'jquery-ui' ), array( 'mydata' => array( 'value' => 20 ) ) );

$header->print_scripts();

Et, print_scripts() La méthode de l'exemple ci-dessus enverra cette sortie:

<script id="jquery-js" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
<script id="jquery-ui-js" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js" type="text/javascript"></script>
<script> var mydata = {"value":20}; </script>
<script id="custom-script-js" src="//custom-script.min.js" type="text/javascript"></script>

Indépendamment du fait que le script 'jquery' est mis en file d'attente après le 'jquery-ui', il est imprimé avant car il est défini dans 'jquery-ui' qu'il dépend de 'jquery'. Des données supplémentaires pour le «script personnalisé» sont à l'intérieur d'un nouveau bloc de script et sont placées devant, il contient mydata objet qui contient des données supplémentaires, maintenant disponible pour 'script personnalisé'.


9
2017-10-29 20:24



myPlugin.start($val); // tried this, didn't work    

Ça ne marche pas parce que $val est indéfini en ce qui concerne javascript, c'est à dire. le php n'a rien sorti pour $val. Essayez de voir la source dans votre navigateur et voici ce que vous verrez:

myPlugin.start(); // tried this, didn't work    

Et

<?php myPlugin.start($val); ?> // this didn't work either

Cela ne fonctionne pas car php va essayer de traiter myPlugin comme une constante et quand cela échoue, il va essayer de le traiter comme la chaîne 'myPlugin' qu'il va essayer de concaténer avec la sortie de la fonction php start() et puisque cela est indéfini, il va produire une erreur fatale

Et

 myPlugin.start(<?=$val?> // this works sometimes, but sometimes it fails

Bien que ce soit le plus susceptible de fonctionner, puisque le php produit un javascript valide avec les arguments attendus, s'il échoue, les chances sont les myPlugin n'est pas encore prêt. Vérifiez votre ordre d'exécution.

Aussi, vous devriez noter que la sortie php n'est pas sûre et devrait être filtrée avec json_encode()

MODIFIER 

Parce que je n'ai pas remarqué la parenthèse manquante myPlugin.start(<?=$val?> : - \

Comme le souligne @Second Rikudo, pour qu'il fonctionne correctement $val aurait besoin de contenir la parenthèse fermante, par exemple: $val="42);" 

Ce qui signifie que le php va maintenant produire myPlugin.start(42); et fonctionnera comme prévu lorsqu'il est exécuté par le javascript


7
2018-05-19 15:20



essaye ça

<?php
    echo "<script> var x = ". json_encode($phpVariable)."</script>";
?>

-

-Après avoir essayé pendant un moment Bien que cela fonctionne, cependant, il ralentit la performance. comme php est un script côté serveur alors que javascript est un côté utilisateur.


7
2017-09-02 10:04



Je suis sorti avec une méthode facile pour attribuer des variables JavaScript en utilisant PHP.

Il utilise des attributs de données HTML5 pour stocker les variables PHP, puis son assigné à JavaScript lors du chargement de la page.

Tutoriel complet peut être trouvé ici

Exemple:

<?php

$variable_1 = "QNimate";
$variable_2 = "QScutter";

?>
    <span id="storage" data-variable-one="<?php echo $variable_1; ?>" data-variable-two="<?php echo $variable_2; ?>"></span>
<?php

Hers est le code JS

var variable_1 = undefined;
var variable_2 = undefined;

window.onload = function(){
    variable_1 = document.getElementById("storage").getAttribute("data-variable-one");
    variable_2 = document.getElementById("storage").getAttribute("data-variable-two");
}

3
2018-01-19 15:04



en voici un que je ne vois pas affiché en option. c'est comme utiliser ajax, mais clairement différent.

Tout d'abord, définissez la source d'un script directement dans un fichier PHP.

<script type="text/javascript" src="url_to_your_php_file.php" /></script>

vous pourriez même transmettre une variable au fichier PHP tel que cet exemple:

<script type="text/javascript" src="url_to_your_php_file.php?var1=value1" /></script>

puis dans "your_php_file.php":

<?php
// THIS IS A SIMPLE EXAMPLE
// it demonstrates one method of using the src attribute to link
// to a PHP file which can generate javascripts dynamically
// and share data between PHP and javascript
// you may take this learning example and develop it further
// relying on your own coding skills for validating data
// and avoiding errors, of course
header( 'content-type: text/javascript' );

// if you pass a $_GET variable from the javascript
// you should add code to validate your $_GET variable(s)

// you can add code to query a database
// using $_GET['var1'] or some other criteria

// you can add simple variable assignments
$value = 'some value';

// for the OP's needs (assumes the class object has been defined)
$val = $myService->getValue();

?>
function name() {
    // pay attention because you need to use quotes properly
    // and account for possible quotes in the variable strings
    // to avoid both php and javascript errors
    // example assumes $val has been returned as a string
    // validate $val as needed using your method of choice
    var example1 = '<?php echo '"' . $val . '"'; ?>';
    var example2 = '<?php echo '"' . $value . '"'; ?>';
    var example3 = '<?php echo '"some other data"'; ?>';
    alert( example1 + ' / ' + example2 );
}
<?php
// you may even want to include additional files (.php or .js, etc)
@include 'local_path_to_some_other_js_file.js';
@include 'local_path_to_some_other_php_file.php';

exit;
?>

2
2018-05-18 20:12