Jak przekazać zmienne i dane z PHP do JavaScript?

664

Mam zmienną w PHP i potrzebuję jej wartości w kodzie JavaScript. Jak mogę uzyskać zmienną z PHP na JavaScript?

Mam kod, który wygląda następująco:

<?php
     ...
     $val = $myService->getValue(); // Makes an API and database call
?>

Mam kod JavaScript, który potrzebuje vali wygląda następująco:

<script>
    myPlugin.start($val); // I tried this, but it didn't work
    <?php myPlugin.start($val); ?> // This didn't work either
    myPlugin.start(<?=$val?> // This works sometimes, but sometimes it fails
</script>
Duch Madary
źródło
2
Czy brakujący nawias zamykający był myPlugin.start(<?=$val?>celowy? Czy to prawda, że ​​„czasem to działa”?
andrew
2
Cóż, ten w rzeczywistości był autorstwa Bena, ale powiedzmy, że jeśli $ val "42)"to będzie działać dobrze: D
Duch Madary

Odpowiedzi:

877

Istnieje na to kilka sposobów. Niektóre wymagają większego obciążenia niż inne, a niektóre uważa się za lepsze niż inne.

W szczególnej kolejności:

  1. Użyj AJAX, aby uzyskać potrzebne dane z serwera.
  2. Zapisz gdzieś dane na stronie i użyj JavaScript, aby uzyskać informacje z DOM.
  3. Echo danych bezpośrednio do JavaScript.

W tym poście sprawdzimy każdą z powyższych metod, zobaczymy zalety i wady każdej z nich, a także sposób ich wdrożenia.

1. Użyj AJAX, aby uzyskać potrzebne dane z serwera

Ta metoda jest uważana za najlepszą, ponieważ skrypty po stronie serwera i po stronie klienta są całkowicie oddzielne .

Plusy

  • Lepsza separacja między warstwami - jeśli jutro przestaniesz używać PHP i chcesz przejść do serwletu, interfejsu API REST lub innej usługi, nie musisz zmieniać dużej części kodu JavaScript.
  • Bardziej czytelny - JavaScript to JavaScript, PHP to PHP. Bez pomieszania tych dwóch elementów otrzymujesz bardziej czytelny kod w obu językach.
  • Pozwala na asynchroniczny transfer danych - Uzyskanie informacji z PHP może być kosztowne pod względem czasu / zasobów. Czasami po prostu nie chcesz czekać na informacje, ładować strony i mieć dostęp do informacji w dowolnym momencie.
  • Dane nie znajdują się bezpośrednio w znacznikach - oznacza to, że znaczniki są oczyszczone z wszelkich dodatkowych danych i tylko JavaScript je widzi.

Cons

  • Opóźnienie - AJAX tworzy żądanie HTTP, a żądania HTTP są przenoszone przez sieć i mają opóźnienia sieciowe.
  • Stan - dane pobrane za pomocą osobnego żądania HTTP nie będą zawierać żadnych informacji z żądania HTTP, które pobrało dokument HTML. Możesz potrzebować tych informacji (np. Jeśli dokument HTML jest generowany w odpowiedzi na przesłanie formularza), a jeśli tak, będziesz musiał go jakoś przenieść. Jeśli wykluczyłeś osadzanie danych na stronie (które masz, jeśli korzystasz z tej techniki), ogranicza to Cię do plików cookie / sesji, które mogą podlegać warunkom wyścigu.

Przykład realizacji

W AJAX potrzebujesz dwóch stron, jedna jest miejscem, w którym PHP generuje dane wyjściowe, a druga jest miejscem, w którym JavaScript pobiera dane wyjściowe:

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 echo the result.
                      // All data should be json_encode()d.

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

index.php (lub jak nazywa się rzeczywista strona)

<!-- 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 -->

Powyższa kombinacja dwóch plików powiadomi 42o zakończeniu ładowania pliku.

Więcej materiałów do czytania

2. Zapisz gdzieś dane na stronie i użyj JavaScript, aby uzyskać informacje z DOM

Ta metoda jest mniej preferowana niż AJAX, ale nadal ma swoje zalety. Nadal jest względnie oddzielony między PHP a JavaScript w tym sensie, że nie ma PHP bezpośrednio w JavaScript.

Plusy

  • Szybka - operacje DOM są często szybkie i stosunkowo szybko można przechowywać i uzyskiwać dostęp do wielu danych.

Cons

  • Potencjalnie niekonsekwentny znacznik - zwykle zdarza się, że używasz jakiegoś rodzaju <input type=hidden>do przechowywania informacji, ponieważ łatwiej jest je uzyskać inputNode.value, ale oznacza to, że masz bez znaczenia element w swoim HTML. HTML zawiera <meta>element danych o dokumencie, a HTML 5 wprowadza data-*atrybuty danych specjalnie do odczytu za pomocą JavaScript, które można powiązać z określonymi elementami.
  • Brudne źródła - dane generowane przez PHP są przesyłane bezpośrednio do źródła HTML, co oznacza, że ​​otrzymujesz większe i mniej skoncentrowane źródło HTML.
  • Trudniej uzyskać dane strukturalne - dane strukturalne będą musiały być poprawnym kodem HTML, w przeciwnym razie będziesz musiał samodzielnie uciec i przekonwertować ciągi.
  • Ściśle łączy PHP z logiką danych - ponieważ PHP jest używane w prezentacji, nie można ich dokładnie rozdzielić.

Przykład realizacji

W tym celu chodzi o stworzenie elementu, który nie będzie wyświetlany użytkownikowi, ale będzie widoczny dla 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. Prześlij dane bezpośrednio do JavaScript

Jest to prawdopodobnie najłatwiejszy do zrozumienia.

Plusy

  • Bardzo łatwa do wdrożenia - wdrożenie i zrozumienie zajmuje niewiele.
  • Nie zanieczyszcza źródła - Zmienne są wyprowadzane bezpośrednio do JavaScript, więc nie ma to wpływu na DOM.

Cons

  • Ściśle łączy PHP z logiką danych - ponieważ PHP jest używane w prezentacji, nie można ich dokładnie rozdzielić.

Przykład realizacji

Wdrożenie jest stosunkowo proste:

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

Powodzenia!

Duch Madary
źródło
70
„PHP nie ma trywialnych funkcji ucieczki JavaScript” - co jest nie tak json_encode?
Quentin
34
Nie zgadzam się z „Bardzo niepewny !!” oraz „Dane strukturalne są trudne”. Zakoduj dane jako JSON (w końcu JavaScript Object Notation) i gotowe!
el.pescado
14
A co ze znaczącym narzutem i złożonością kodu, jakie wprowadza asynchroniczność podczas tworzenia żądania AJAX? Podczas pracy na lekkiej stronie JavaScript - składanie żądania AJAX jest żmudne, a nie najlepsze praktyki.
Benjamin Gruenbaum
8
@BenjaminGruenbaum - JS jest nieprawidłowy JSON jest nieistotny. Nie mogę wymyślić żadnego kodu JSON, który jest nieprawidłowy w JavaScript po prawej stronie zadania.
Quentin
7
@SecondRikudo W metodzie 3 ten przykład może zabić witrynę. Przykład: <?php $output = '<!--<script>'; echo json_encode($output); ?>. Zobacz to pytanie, aby uzyskać szczegółowe informacje. Rozwiązanie: Użyj JSON_HEX_TAGaby uciec <i >(wymaga PHP 5.3.0).
Pang
90

Spróbuję prostszej odpowiedzi:

Wyjaśnienie problemu

Po pierwsze, zrozummy przepływ zdarzeń, gdy strona jest obsługiwana z naszego serwera:

  • Najpierw uruchamiane jest PHP, które generuje HTML, który jest dostarczany do klienta.
  • Następnie HTML jest dostarczany do klienta, po zakończeniu PHP, chciałbym podkreślić, że gdy kod opuści serwer - PHP jest z nim zrobione i nie może już uzyskać do niego dostępu.
  • Następnie HTML z JavaScript dociera do klienta, który może wykonać JavaScript na tym HTML.

Tak naprawdę najważniejszą rzeczą do zapamiętania jest to, że HTTP jest bezstanowy . Gdy żądanie opuści serwer, serwer nie może go dotknąć. To pozostawia nasze opcje:

  1. Wyślij więcej żądań od klienta po zakończeniu pierwszego żądania.
  2. Zakoduj to, co serwer miał do powiedzenia w pierwszym żądaniu.

Rozwiązania

Oto podstawowe pytanie, które powinieneś sobie zadać:

Czy piszę stronę internetową lub aplikację?

Strony internetowe są głównie oparte na stronach, a czas ładowania strony musi być tak szybki, jak to możliwe (na przykład - Wikipedia). Aplikacje internetowe są bardziej obciążone AJAX i wykonują wiele podróży w obie strony, aby uzyskać szybkie informacje o kliencie (na przykład - pulpit giełdowy).

Stronie internetowej

Wysyłanie większej liczby żądań od klienta po wykonaniu pierwszego żądania jest powolne, ponieważ wymaga większej liczby żądań HTTP, które mają znaczny narzut. Co więcej, wymaga asynchroniczności, ponieważ wykonanie żądania AJAX wymaga modułu obsługi po zakończeniu.

Bym nie polecam co innego żądania , chyba że witryna jest aplikacją dla uzyskania tych informacji z serwera.

Chcesz szybkich czasów reakcji, które mają ogromny wpływ na czas konwersji i ładowania. W tym przypadku wysyłanie żądań Ajax jest powolne i nie jest konieczne.

Istnieją dwa sposoby rozwiązania tego problemu

  • Ustaw plik cookie - pliki cookie to nagłówki wysyłane w żądaniach HTTP, które zarówno serwer, jak i klient mogą odczytać.
  • Zakoduj zmienną jako JSON - JSON wygląda bardzo blisko obiektów JavaScript, a większość obiektów JSON jest prawidłowymi zmiennymi JavaScript.

Ustawienie pliku cookie nie jest naprawdę trudne, wystarczy przypisać mu wartość:

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

Następnie możesz przeczytać w JavaScript za pomocą document.cookie:

Oto krótki analizator składany z krótką ręką, ale odpowiedź, którą podałem powyżej, ma lepiej przetestowane:

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.

Pliki cookie są dobre dla niewielkiej ilości danych. Właśnie to często robią usługi śledzenia.

Gdy mamy więcej danych, możemy zamiast tego zakodować je za pomocą JSON w zmiennej JavaScript:

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

Zakładając, że $valuejest w json_encodestanie po stronie PHP (zwykle jest). Ta technika jest tym, co robi na przykład przepełnienie stosu na czacie (używając tylko .NET zamiast PHP).

Podanie

Jeśli piszesz aplikację - nagle początkowy czas ładowania nie zawsze jest tak ważny, jak bieżąca wydajność aplikacji, i zaczyna się opłacać, aby ładować dane i kod osobno.

Moja odpowiedź tutaj wyjaśnia, jak ładować dane za pomocą AJAX w 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();

Lub z jQuery:

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

Teraz serwer musi zawierać tylko /your/urltrasę / plik zawierający kod, który pobiera dane i robi coś z tym, w twoim przypadku:

<$php
     ...
     $val = myService->getValue(); // Makes an API and database call
     echo json_encode($val); // Write it to the output
 $>

W ten sposób nasz plik JavaScript prosi o dane i pokazuje je zamiast pytać o kod lub układ. Jest to czystsze i zaczyna się opłacać, gdy aplikacja staje się wyższa. To także lepsze rozdzielenie problemów i pozwala przetestować kod po stronie klienta bez udziału technologii po stronie serwera, co jest kolejnym plusem.

Postscriptum: Musisz być bardzo świadomi XSS wektorów ataków podczas wstrzykiwania czegokolwiek z PHP do JavaScript. To bardzo trudno właściwie uciec wartości i to od kontekstu. Jeśli nie masz pewności, jak postępować z XSS lub nie wiesz o tym - przeczytaj ten artykuł OWASP , ten i to pytanie .

Benjamin Gruenbaum
źródło
4
@ cHao bardziej ogólnie - kodowanie jest definiowane jako ciąg znaków, a istnienie obiektów koncepcyjnych ma charakter filozoficzny. Istnieją jednak takie obiekty jak obiekty JSON i są one zdefiniowane przez gramatykę JSON. {}jest poprawnym obiektem JSON - patrz json.org
Benjamin
1
Jeśli jednak używasz tej definicji, wszystkie „obiekty JSON” są poprawne w JS.
cHao
1
@ cHao zwróć uwagę na subtelność: JavaScript ma pojęcie obiektu, a JSON pojęcie przedmiotu - nie są one takie same. Gdy ludzie niewłaściwie używają terminu „obiekt JSON”, mają na myśli obiekt JS, gdzie w JavaScript JavaScript - JSON jest używany jako format serializacji danych, a obiekty JSON pojawiają się wewnątrz ciągów (coś w rodzaju zapytań SQL w językach po stronie serwera). Jednak w tej odpowiedzi metoda JSON opiera się na fakcie, że większość obiektów JSON jest również poprawnymi obiektami JavaScript, dlatego zapisujemy obiekt JSON w kodzie JavaScript.
Benjamin Gruenbaum,
1
@ cHao Ah, ale przewidziałem ten moment wczoraj :) stackoverflow.com/questions/23752156/…
Benjamin Gruenbaum
2
OK, masz mnie tam. :) Jednak nadal jest bezpieczny; Domyślnym zachowaniem PHP jest ucieczka przed takimi znakami (wraz z innymi znakami spoza ASCII), więc nigdy nie trafiają one do wyjścia, z wyjątkiem jako \u2028itp. Trzeba by wyraźnie powiedzieć, żeby tego nie robić.
cHao
85

Zwykle używam atrybutów data- * w 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');

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

W tym przykładzie użyto jQuery, ale można go dostosować do innej biblioteki lub waniliowego JavaScript.

Możesz przeczytać więcej o właściwości zestawu danych tutaj: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset

yuikonnu
źródło
4
Zgadzam się, nie chcę zbytnio analizować i wdrażać fantazyjnych rozwiązań prostych problemów. Ta metoda oddziela PHP od Javascript, dzięki czemu PHP nadal generuje tylko HTML, podczas gdy JavaScript może być zewnętrzny w stosunku do pliku PHP.
alds
2
Zgadzam się, że to najlepsza opcja. Rozwiązuje wszystkie problemy bezpieczeństwa, bez opóźnień. Możesz trzymać JS całkowicie z dala od stron HTML. Serwer aplikacji musi obsługiwać HTML, ale JS (i CSS) nie. Jest również bardziej semantyczny.
Ryan
1
@Quentin Powinieneś uciec WSZYSTKIM wyjściowym, chyba że wyjściowym jest sam HTML.
yuikonnu
2
@asdasd - Cóż, tak, właśnie rozwiązałem konkretny problem z kodem w twojej odpowiedzi, a nie ogólny przypadek.
Quentin
1
@kanji - nie ma najlepszej praktyki; divjest w porządku, ale możesz użyć dowolnego tagu, który ci się podoba; musi być w tym bodyjednak.
Timm,
38
<script>
  var jsvar = <?php echo json_encode($PHPVar); ?>;
</script>

json_encode () wymaga:

  • PHP 5.2.0 lub więcej
  • $PHPVar zakodowany jako UTF-8, Unicode.
Jessé Catrinck
źródło
19

Po prostu użyj jednej z następujących metod.

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

LUB

<script type="text/javascript">
    var js_variable = <?php echo json_encode($php_variable); ?>; 
</script>
Nishant Mendiratta
źródło
4
Jaką wartość to dodaje do istniejących odpowiedzi?
Benjamin Gruenbaum,
5
Prostota i prostota. Dla wszystkich użytkowników, którzy mają dużo czasu na szczegółowe wyjaśnienia
Nishant Mendiratta,
1
Proste jest lepsze
Doberon
Być może jest to głupie pytanie, ale jestem absolutnie nowy w świecie PHP. W jaki sposób mogę uzyskać dostęp do „js_variable” w moim pliku JavaScript lub pliku „index.html” po zapisaniu powyższego kodu w pliku .php?
Ankit Prajapati,
@AnkitPrajapati Spróbuj uzyskać do niego dostęp, sprawdzając stan gotowości dokumentu. Za pomocą następującego skryptu. document.onreadystatechange = () => { if (document.readyState === 'complete') { // document ready alert(js_variable) } };
Nishant Mendiratta
11

Bardzo podoba mi się sposób, w jaki WordPress działa z funkcją kolejkowania i lokalizowania , dlatego zgodnie z tym modelem napisałem prostą klasę do umieszczania skryptów na stronie zgodnie z zależnościami skryptów i do udostępniania dodatkowych danych dla skryptu.

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

Wywołanie enqueue_script()funkcji służy do dodawania skryptu, ustawiania źródła i zależności od innych skryptów oraz dodatkowych danych potrzebnych do skryptu.

$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();

I print_scripts()metoda z powyższego przykładu wyśle ​​to wyjście:

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

Niezależnie od faktu, że skrypt „jquery” jest kolejkowany po „jquery-ui”, jest drukowany wcześniej, ponieważ jest zdefiniowany w „jquery-ui”, że zależy od „jquery”. Dodatkowe dane dla „skryptu niestandardowego” znajdują się w nowym bloku skryptu i są umieszczone przed nim, zawiera mydataobiekt zawierający dodatkowe dane, teraz dostępne dla „skryptu niestandardowego”.

Danijel
źródło
10

Spróbuj tego:

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

-

- Po wypróbowaniu tego przez chwilę

Chociaż działa, jednak spowalnia działanie. Ponieważ PHP jest skryptem po stronie serwera, podczas gdy JavaScript jest po stronie użytkownika.

Yosra Nagati
źródło
4
Szukamy długich odpowiedzi, które zawierają wyjaśnienia i kontekst. Nie udzielaj odpowiedzi tylko w jednym wierszu; wyjaśnij, dlaczego Twoja odpowiedź jest poprawna, najlepiej z cytatami. Odpowiedzi, które nie zawierają wyjaśnień, mogą zostać usunięte. To jest napisane na pytanie.
Duch Madary
3
nic wielkiego do wyjaśnienia zapisz zmienną php w tagu <script>, który znajduje się w kodzie php
Yosra Nagati
5
Jesteś pewny? Czy widziałeś najlepszą odpowiedź na to pytanie? To sporo wyjaśnia. Nie wspominając o tym, że twoje rozwiązanie nie jest bezpieczne. $phpVariable = '42"; alert("I am evil!");';
Duch Madary
9
to jest moja sugestia, która rozwiązała mój problem i nie znajduję go w poprzednich odpowiedziach, więc dodałem, mając nadzieję, że ktoś uzna to za interesujące
Yosra Nagati,
1
dodano tutaj echo, aby wydrukować go na stronie internetowej zawierającej ten kod php, czy też jest to tylko część składni umieszczania danych w zmiennej js. @ YosraNagati
SUMIT KUMAR SINGH
8
myPlugin.start($val); // Tried this, didn't work

Nie działa, ponieważ nie $valjest zdefiniowany w JavaScript, tzn. Kod PHP nie wyświetlał niczego $val. Spróbuj wyświetlić źródło w przeglądarce, a oto, co zobaczysz:

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

I

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

To nie działa, ponieważ PHP spróbuje traktować myPluginjako stałą, a gdy to się nie powiedzie, spróbuje potraktować go jako ciąg znaków, 'myPlugin'który spróbuje połączyć z wyjściem funkcji PHP, start()a ponieważ nie jest to zdefiniowane, spowoduje śmierć błąd.

I

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

Chociaż najprawdopodobniej to zadziała, ponieważ kod PHP generuje poprawny kod JavaScript z oczekiwanymi argumentami, jeśli się nie powiedzie, są szanse, że myPluginnie jest jeszcze gotowy. Sprawdź kolejność realizacji.

Należy również pamiętać, że dane wyjściowe kodu PHP są niepewne i należy je filtrować json_encode().

EDYTOWAĆ

Ponieważ nie zauważyłem brakującego nawiasu w myPlugin.start(<?=$val?>: - \

Jak wskazuje @Second Rikudo, aby działać poprawnie, $valmusiałby zawierać nawias zamykający, na przykład:$val="42);"

Oznacza to, że PHP będzie teraz produkować myPlugin.start(42);i będzie działać zgodnie z oczekiwaniami, gdy zostanie wykonane przez kod JavaScript.

Andrzej
źródło
JSON koduje twoje dane:myPlugin.start(<?=json_encode($val)?>);
kingprawn
6

Wyszedłem z łatwą metodą przypisywania zmiennych JavaScript za pomocą PHP.

Używa atrybutów danych HTML5 do przechowywania zmiennych PHP, a następnie jest przypisywany do JavaScript przy ładowaniu strony.

Kompletny samouczek można znaleźć tutaj .

Przykład:

<?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

Oto kod JavaScript

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");
}
qnimate
źródło
2
Chociaż atrybuty danych są rozsądnym rozwiązaniem problemu, w przypadku danych nie można uniknąć podobnego problemu do pierwotnego pytania. Musisz tylko uciec przed nimi w HTML zamiast JS.
Quentin,
5
  1. Konwertuj dane na JSON
  2. Zadzwoń do AJAX, aby otrzymać plik JSON
  3. Konwertuj JSON na obiekt Javascript

Przykład:

KROK 1

<?php

   $servername = "localhost";
   $username = "";
   $password = "";
   $dbname = "";
   $conn = new mysqli($servername, $username, $password, $dbname);

   if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
   } 

   $sql = "SELECT id, name, image FROM phone";
   $result = $conn->query($sql);

   while($row = $result->fetch_assoc()){ 
      $v[] = $row;    
   }

  echo json_encode($v);

  $conn->close();
?>

KROK 2

function showUser(fnc) {
   var xhttp = new XMLHttpRequest();

   xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
         // STEP 3    
         var p = JSON.parse(this.responseText);
      }
   }
}
DeV
źródło
5

Oto jeden, którego nie widzę opublikowanego jako opcji. Jest podobny do korzystania z Ajax, ale wyraźnie inny.

Najpierw ustaw źródło skryptu bezpośrednio na plik PHP.

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

Możesz nawet przekazać zmienną z powrotem do pliku PHP, takiego jak ten przykład:

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

Następnie w „twój_plik_pliku.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 JavaScript code 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;
?>
aequalsb
źródło
Ponieważ zmienna istnieje w skrypcie PHP, który generuje HTML, przeoczyłeś ważny etap dynamicznego generowania var1=value1. W tej chwili twój skrypt się zepsuje, jeśli dane zawierają 'znak.
Quentin,
@Quent w kodzie PRZYKŁAD działa bezbłędnie, jak przedstawiono. ma to na celu wykazanie użycia. jeśli programista jest tak daleko w kodowaniu, zrozumie implikacje pojedynczych cudzysłowów / podwójnych cudzysłowów w zmiennych $ _GET - które i tak powinny zostać zakodowane.var1 != [some HTML code]... WYRAŹNIE var1=="value1". Mówiąc wprost, mylisz się, że coś przeoczyłem. skrypt PRZYKŁADOWY jest kompletny i, jak widać, nie generuje żadnego HTML - a OP nie wspomniał o HTML. nie zasługuje na ocenę przez jakiegoś wyzwalacza szczęśliwego bypassera
wycofaj
Kod w pytaniu pokazuje, że OP nie rozumie cytowania / zmiany znaczenia. Brak zrozumienia na ten temat to cały problem! Chociaż przykład jest kompletny, nie jest to przykład rozwiązania problemu wyrażonego w pytaniu.
Quentin,
@Quentin, w jaki sposób OP wykazuje, że nie rozumie cytowania / ucieczki? jest to przykład rozwiązania problemu, ponieważ OP zapytał, jak pobrać dane PHP do javascript - mój przykład jest jedną z metod, która nie została odnotowana w żadnej innej odpowiedzi
aequalsb
Z tym fragmentem kodu, który nie robi nic, aby uciec lub zakodować, $vali który czasami działa, a czasami nie:myPlugin.start(<?=$val?> // this works sometimes, but sometimes it fails
Quentin
3

Oto sztuczka:

  1. Oto twój „PHP”, aby użyć tej zmiennej:

    <?php
        $name = 'PHP variable';
        echo '<script>';
        echo 'var name = ' . json_encode($name) . ';';
        echo '</script>';
    ?>
  2. Teraz masz zmienną JavaScript o nazwie 'name', a oto twój kod JavaScript, aby użyć tej zmiennej:

    <script>
         console.log("I am everywhere " + name);
    </script>
Ramin Taghizada
źródło
Czy jest jakiś sposób, aby uzyskać go tak, aby faktycznie nie drukował w kodzie źródłowym? Mam ogromną tablicę, którą mijam, która zapycha źródło.
William Howley,
1
Czy możesz podać przykładowy przypadek testowy?
Ramin Taghizada
Czy to nie to samo, co „3. Echo danych bezpośrednio do JavaScript” w tej odpowiedzi ? Ten wygląda jeszcze lepiej.
kanji
3

Powiedzmy, że twoja zmienna jest zawsze liczbą całkowitą. W takim przypadku jest to łatwiejsze:

<?PHP
    $number = 4;

    echo '<script>';
    echo 'var number = ' . $number . ';';
    echo 'alert(number);';
    echo '</script>';
?>

Wyjście :

<script>var number = 4;alert(number);</script>

Powiedzmy, że twoja zmienna nie jest liczbą całkowitą, ale jeśli wypróbujesz powyższą metodę, otrzymasz coś takiego:

<script>var number = abcd;alert(number);</script>

Ale w JavaScript jest to błąd składniowy.

Tak więc w PHP mamy wywołanie funkcji, json_encodektóre koduje ciąg znaków do obiektu JSON.

<?PHP
    $number = 'abcd';

    echo '<script>';
    echo 'var number = ' . json_encode($number) . ';';
    echo 'alert(number);';
    echo '</script>';
?>

Ponieważ abcdw JSON jest "abcd", wygląda to tak:

<script>var number = "abcd";alert(number);</script>

Możesz użyć tej samej metody dla tablic:

<?PHP
    $details = [
    'name' => 'supun',
    'age' => 456,
    'weight' => '55'
    ];

    echo '<script>';
    echo 'var details = ' . json_encode($details) . ';';
    echo 'alert(details);';
    echo 'console.log(details);';
    echo '</script>';
?>

Twój kod JavaScript wygląda następująco:

<script>var details = {"name":"supun","age":456,"weight":"55"};alert(details);console.log(details);</script>

Wyjście konsoli

Wpisz opis zdjęcia tutaj

Supun Praneeth
źródło
2

Po wielu badaniach odkryłem, że najłatwiejszą metodą jest łatwe przekazywanie wszystkich zmiennych.

W skrypcie serwera masz dwie zmienne i próbujesz wysłać je do skryptów klienta:

$php_var1 ="Hello world";
$php_var2 ="Helloow";
echo '<script>';
echo 'var js_variable1= ' . json_encode($php_var1) . ';';
echo 'var js_variable2= ' . json_encode($php_var2) . ';';
echo '</script>';

W dowolnym kodzie JavaScript wywoływanym na stronie wystarczy wywołać te zmienne.

Max
źródło
1

Zakładam, że dane do przesłania są ciągiem.

Jak stwierdzili inni komentatorzy, AJAX jest jednym z możliwych rozwiązań, ale wady przeważają nad zaletami: ma opóźnienie i trudniej jest programować (potrzebuje kodu, aby pobrać wartość zarówno po stronie serwera, jak i klienta), gdy jest to prostsze funkcja ucieczki powinna wystarczyć.

Wracamy do ucieczki. json_encode($string)działa, jeśli najpierw kodujesz łańcuch źródłowy jako UTF-8, jeśli jeszcze go nie ma, ponieważ json_encodewymaga danych UTF-8. Jeśli ciąg jest w ISO-8859-1, możesz po prostu użyć json_encode(utf8_encode($string)); w przeciwnym razie zawsze możesz użyć iconvnajpierw do konwersji.

Ale jest duża gotcha. Jeśli używasz go w zdarzeniach, musisz uruchomić htmlspecialchars()wynik, aby poprawić kod. A potem musisz albo użyć podwójnych cudzysłowów, aby załączyć zdarzenie, albo zawsze dodawać ENT_QUOTESdo htmlspecialchars. Na przykład:

<?php
    $myvar = "I'm in \"UTF-8\" encoding and I have <script>script tags</script> & ampersand!";
    // Fails:
    //echo '<body onload="alert(', json_encode($myvar), ');">';
    // Fails:
    //echo "<body onload='alert(", json_encode($myvar), ");'>";
    // Fails:
    //echo "<body onload='alert(", htmlspecialchars(json_encode($myvar)), ");'>";

    // Works:
    //echo "<body onload='alert(", htmlspecialchars(json_encode($myvar), ENT_QUOTES), ");'>";
    // Works:
    echo '<body onload="alert(', htmlspecialchars(json_encode($myvar)), ');">';

    echo "</body>";

Nie można jednak używać htmlspecialcharszwykłego kodu JavaScript (kod zawarty w <script>... </script>znacznikach). Dzięki temu ta funkcja jest podatna na błędy, zapominając ohtmlspecialchars wyniku podczas pisania kodu zdarzenia.

Możliwe jest napisanie funkcji, która nie ma tego problemu i można jej używać zarówno w zdarzeniach, jak i zwykłym kodzie JavaScript, pod warunkiem, że wydarzenia będą zawsze ujęte w pojedyncze cudzysłowy lub zawsze w podwójne cudzysłowy. Oto moja propozycja, która wymaga podwójnego cudzysłowu (co wolę):

<?php
    // Optionally pass the encoding of the source string, if not UTF-8
    function escapeJSString($string, $encoding = 'UTF-8')
    {
        if ($encoding != 'UTF-8')
            $string = iconv($encoding, 'UTF-8', $string);
        $flags = JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_UNESCAPED_SLASHES;
        $string = substr(json_encode($string, $flags), 1, -1);
        return "'$string'";
    }

Ta funkcja wymaga PHP 5.4+. Przykładowe użycie:

<?php
    $myvar = "I'm in \"UTF-8\" encoding and I have <script>script tags</script> & ampersand!";
    // Note use of double quotes to enclose the event definition!
    echo '<body onload="alert(', escapeJSString($myvar), ');">';
    // Example with regular code:
    echo '<script>alert(', escapeJSString($myvar), ');</script>';
    echo '</body>';
Pedro Gimeno
źródło
0

Zgodnie z Twoim kodem

<$php
     $val = $myService->getValue(); // Makes an API and database call
     echo '<span id="value">'.$val.'</span>';
$>

Teraz możesz uzyskać wartość za pomocą DOM, użyj innerHTML span id, w tym przypadku nie musisz wykonywać żadnego połączenia z serwerem, Ajaxem lub inną rzeczą.

Twoja strona wydrukuje go za pomocą PHP, a JavaScript uzyska wartość za pomocą DOM.

Amit Shah
źródło
Ten kod jest wrażliwy na XSS, ponieważ nie ucieka od znaków takich jak <i >. Podobne rozwiązania zostały już zasugerowane.
Michał Perłakowski
0
<?php

    $val = $myService->getValue(); // Makes an API and database call

    echo "
        <script>
            myPlugin.start({$val});
        </script> ";

?>
antylopa
źródło
0

PHP

$fruits = array("apple" => "yellow", "strawberry" => "red", "kiwi" => "green");
<script>
    var color = <?php echo json_encode($fruits) ?>;
</script>
<script src="../yourexternal.js"></script>

JS (yourexternal.js)

alert("The apple color is" + color['apple'] + ", the strawberry color is " + color['strawberry'] + " and the kiwi color is " + color['kiwi'] + ".");

WYNIK

Kolor jabłka jest żółty, kolor truskawek jest czerwony, a kolor kiwi - zielony.

Marco Concas
źródło
-2

Dla tych, którzy mają problem z używaniem poniższego kodu i ciągle go wyświetla <?php echo $username?>lub coś takiego, edytuj httpd.conf w sekcji mime_module, dodając tę ​​aplikację „AddType / x-httpd-php .html .htm”, ponieważ może być wyłączona domyślnie.

<?php
    $username = 1;
?>

<script type="text/javascript">
    var myData = <?php echo $username ?>;
    console.log(myData);
    alert(myData);
</script>
Tapasit Suesasiton
źródło
@MadaraUchiha czy możesz wyjaśnić, dlaczego?
Nikita 웃
3
Ponieważ jeśli $username === "hello", to masz, var myData = hello;co okropnie się zepsuje.
Madara's Ghost
-2

Posługiwać się:

<?php
    $your_php_variable= 22;
    echo "<script type='text/javascript'>var your_javascript_variable = $your_php_variable;</script>";
?>

i to zadziała. Po prostu przypisuje zmienną JavaScript, a następnie przekazuje wartość istniejącej zmiennej PHP. Ponieważ PHP zapisuje tutaj wiersze JavaScript, ma wartość zmiennej PHP i może przekazać ją bezpośrednio.

Neo
źródło