Jak przekazać zmienne i dane z PHP do JavaScript?
Mam zmienną w PHP i potrzebuję jej wartości w moim kodzie JavaScript. Jak mogę przenieść moją zmienną z PHP do 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 val
i 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>
Odpowiedzi
W rzeczywistości istnieje kilka podejść do tego. Niektóre wymagają więcej kosztów niż inne, a niektóre są uważane za lepsze od innych.
W przypadkowej kolejności:
- Użyj AJAX, aby uzyskać potrzebne dane z serwera.
- Powtórz dane na stronie i użyj JavaScript, aby uzyskać informacje z DOM.
- Echo danych bezpośrednio do JavaScript.
W tym poście przeanalizujemy każdą z powyższych metod i zobaczymy wady i zalety każdej z nich, a także sposób ich wdrożenia.
1. Użyj AJAX, aby pobrać 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 przenieść się 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 mieszania tych dwóch otrzymasz bardziej czytelny kod w obu językach.
- Umożliwia asynchroniczny transfer danych - pobieranie informacji z PHP może być czasochłonne / kosztowne. Czasami po prostu nie chcesz czekać na informacje, załadować strony i mieć informacje, które docierają w dowolnym momencie.
- Danych nie można znaleźć bezpośrednio w znaczniku - oznacza to, że znacznik jest wolny od wszelkich dodatkowych danych i widzi je tylko JavaScript.
Cons
- Opóźnienie - AJAX tworzy żądanie HTTP, a żądania HTTP są przenoszone przez sieć i mają opóźnienia sieciowe.
- Stan - dane pobrane przez oddzielne żądanie 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 to zrobisz, będziesz musiał je w jakiś sposób przenieść. Jeśli wykluczyłeś umieszczanie danych na stronie (które masz, jeśli używasz tej techniki), ogranicza to Cię do plików cookie / sesji, które mogą podlegać warunkom wyścigu.
Przykład implementacji
W przypadku AJAX potrzebujesz dwóch stron, z których jedna to PHP generuje dane wyjściowe, a druga to miejsce, 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 jakakolwiek inna nazwa strony)
<!-- 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 zostanie ostrzeżona, 42
gdy zakończy się ładowanie pliku.
Więcej materiałów do czytania
- Korzystanie z XMLHttpRequest - MDN
- Dokumentacja XMLHttpRequest - MDN
- Jak zwrócić odpowiedź z wywołania asynchronicznego?
2. Echo danych gdzieś na stronie i użyj JavaScript, aby pobrać informacje z DOM
Ta metoda jest mniej preferowana niż AJAX, ale nadal ma swoje zalety. Wciąż jest stosunkowo oddzielony między PHP i JavaScript w tym sensie, że nie ma PHP bezpośrednio w JavaScript.
Plusy
- Szybkość - operacje DOM są często szybkie i stosunkowo szybko można przechowywać wiele danych i uzyskiwać do nich dostęp.
Cons
- Potencjalnie nieemantyczne znaczniki - zwykle zdarza się, że używasz jakiegoś rodzaju
<input type=hidden>
do przechowywania informacji, ponieważ łatwiej jest je wydobyćinputNode.value
, ale oznacza to, że masz pozbawiony znaczenia element w kodzie HTML. HTML zawiera<meta>
element danych o dokumencie, a HTML 5 wprowadzadata-*
atrybuty danych specjalnie do odczytu za pomocą JavaScript, które można powiązać z określonymi elementami. - Dirties up the Source - dane generowane przez PHP są wysył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ć prawidłowym kodem HTML, w przeciwnym razie będziesz musiał samodzielnie uciec i przekonwertować ciągi.
- Ściśle łączy język PHP z logiką danych - ponieważ PHP jest używane w prezentacji, nie można ich jednoznacznie rozdzielić.
Przykład implementacji
Chodzi o to, aby stworzyć element, 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. Echo danych bezpośrednio do JavaScript
Jest to prawdopodobnie najłatwiejsze do zrozumienia.
Plusy
- Bardzo łatwa implementacja - wdrożenie tego i zrozumienie zajmuje bardzo niewiele.
- Nie zanieczyszcza źródła - zmienne są wysyłane bezpośrednio do JavaScript, więc nie ma to wpływu na DOM.
Cons
- Ściśle łączy język PHP z logiką danych - ponieważ PHP jest używane w prezentacji, nie można ich jednoznacznie rozdzielić.
Przykład implementacji
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!
Spróbuję prostszej odpowiedzi:
Wyjaśnienie problemu
Najpierw przyjrzyjmy się przepływowi zdarzeń, gdy strona jest wyświetlana z naszego serwera:
- Najpierw uruchamiane jest PHP, które generuje kod HTML, który jest udostępniany klientowi.
- Następnie HTML jest dostarczany do klienta, po tym jak PHP jest już z nim zrobione, chciałbym podkreślić, że gdy kod opuści serwer - PHP jest z nim zrobione i nie ma już do niego dostępu.
- Następnie kod HTML z JavaScript dociera do klienta, który może wykonać JavaScript w tym kodzie HTML.
Tak naprawdę, najważniejszą rzeczą do zapamiętania jest to, że HTTP jest bezstanowe . Gdy żądanie opuściło serwer, serwer nie może go dotknąć. To pozostawia nam opcje:
- Wyślij więcej żądań od klienta po wykonaniu pierwszego żądania.
- Zakoduj, co serwer miał do powiedzenia w początkowym żądaniu.
Rozwiązania
Oto podstawowe pytanie, które powinieneś sobie zadać:
Piszę stronę internetową lub aplikację?
Witryny internetowe opierają się głównie na stronach, a ich czas ładowania musi być jak najkrótszy (na przykład - Wikipedia). Aplikacje internetowe są bardziej obciążone technologią AJAX i wykonują wiele podróży w obie strony, aby szybko uzyskać informacje o kliencie (na przykład - pulpit magazynowy).
Stronie internetowej
Wysyłanie większej liczby żądań od klienta po wykonaniu żądania początkowego jest powolne, ponieważ wymaga większej liczby żądań HTTP, które mają znaczny narzut. Co więcej, wymaga asynchroniczności, ponieważ wysyłanie żądania AJAX wymaga procedury obsługi, gdy zostanie ukończone.
Bym nie polecam co innego żądania , chyba że witryna jest aplikacją dla uzyskania tych informacji z serwera.
Chcesz szybkich czasów odpowiedzi, które mają ogromny wpływ na czasy konwersji i ładowania. Wysyłanie żądań Ajax jest w tym przypadku powolne przez początkowy czas pracy i niepotrzebne.
Masz dwa sposoby rozwiązania tego problemu
- Ustaw plik cookie - pliki cookie to nagłówki wysyłane w żądaniach HTTP, które mogą odczytać zarówno serwer, jak i klient.
- Zakoduj zmienną jako JSON - JSON wygląda bardzo podobnie do obiektów JavaScript, a większość obiektów JSON to prawidłowe zmienne JavaScript.
Ustawienie pliku cookie nie jest naprawdę trudne, po prostu przypisujesz 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 go przeczytać za pomocą JavaScript za pomocą document.cookie
:
Oto parser z krótką ręką, ale odpowiedź, z którą się łączył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 małych danych. To właśnie 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 $value
jest w json_encode
stanie po stronie PHP (zwykle jest). Ta technika jest tym, co Stack Overflow robi na przykład z czatem (tylko przy użyciu .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 oddzielnie.
Moja odpowiedź tutaj wyjaśnia, w jaki sposób dane obciążenia z wykorzystaniem 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 tylko zawierać /your/url
trasę / plik, który zawiera kod, który przechwytuje dane i coś z nimi robi, 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 wyświetla je zamiast prosić o kod lub układ. Jest to czystsze i zaczyna się opłacać, gdy aplikacja rośnie. Jest to również lepsze rozdzielenie problemów i pozwala na testowanie kodu po stronie klienta bez użycia jakiejkolwiek technologii po stronie serwera, co jest kolejnym plusem.
Postscript: Musisz być bardzo świadomy wektorów ataku XSS, kiedy wstrzykujesz cokolwiek, od PHP po JavaScript. To bardzo trudno właściwie uciec wartości i to od kontekstu. Jeśli nie jesteś pewien, jak sobie radzić z XSS lub nie jesteś tego świadomy - przeczytaj ten artykuł OWASP , ten i to pytanie .
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 zastosowano jQuery, ale można go dostosować do innej biblioteki lub zwykłego JavaScript.
Możesz przeczytać więcej o właściwości zbioru danych tutaj: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset
<script>
var jsvar = <?php echo json_encode($PHPVar); ?>;
</script>
json_encode () wymaga:
- PHP 5.2.0 lub nowszy
$PHPVar
zakodowane jako UTF-8, Unicode.
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>
Bardzo podoba mi się sposób, w jaki WordPress działa z jego funkcjami enqueue i localize , więc zgodnie z tym modelem napisałem prostą klasę do umieszczania skryptów na stronie zgodnie z zależnościami skryptów oraz 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 dodania skryptu, ustawienia ź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 tego, że skrypt „jquery” jest umieszczony w kolejce po „jquery-ui”, jest drukowany wcześniej, ponieważ w „jquery-ui” zdefiniowano, że zależy od „jquery”. Dodatkowe dane dla „skryptu niestandardowego” znajdują się w nowym bloku skryptu i są umieszczone przed nim, zawierają mydata
obiekt, który przechowuje dodatkowe dane, teraz dostępny dla „skryptu niestandardowego”.
Spróbuj tego:
<?php
echo "<script> var x = " . json_encode($phpVariable) . "</script>";
?>
-
-Po próbowaniu tego przez chwilę
Chociaż działa, spowalnia działanie. Ponieważ PHP jest skryptem po stronie serwera, a JavaScript jest po stronie użytkownika.
myPlugin.start($val); // Tried this, didn't work
To nie działa, ponieważ $val
jest niezdefiniowane, jeśli chodzi o JavaScript, tj. Kod PHP nie wypisał nic dla $val
. Spróbuj wyświetlić źródło w przeglądarce, a zobaczysz to:
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 będzie próbowało traktować myPlugin
jako stałą, a gdy to się nie powiedzie, będzie próbowało traktować to jako ciąg, 'myPlugin'
który będzie próbował połączyć z wyjściem funkcji PHP, start()
a ponieważ jest on niezdefiniowany, spowoduje to fatal błąd.
I
myPlugin.start(<?=$val?> // This works sometimes, but sometimes it fails
Chociaż najprawdopodobniej to zadziała, ponieważ kod PHP tworzy prawidłowy kod JavaScript z oczekiwanymi argumentami, jeśli się nie powiedzie, istnieje prawdopodobieństwo, że myPlugin
nie jest jeszcze gotowy. Sprawdź swoją kolejność wykonania.
Należy również zauważyć, że kod wyjściowy PHP jest niezabezpieczony i powinien być filtrowany za pomocą json_encode()
.
EDYTOWAĆ
Ponieważ nie zauważyłem brakującego nawiasu w myPlugin.start(<?=$val?>
: - \
Jak wskazuje @Second Rikudo, aby działało poprawnie, $val
musiałoby zawierać nawias zamykający, na przykład:$val="42);"
Oznacza to, że PHP będzie teraz produkować myPlugin.start(42);
i działać zgodnie z oczekiwaniami po wykonaniu przez kod JavaScript.
Wymyśliłem prostą metodę przypisywania zmiennych JavaScript za pomocą PHP.
Używa atrybutów danych HTML5 do przechowywania zmiennych PHP, a następnie jest przypisywany do JavaScript podczas ładowania strony.
Pełen 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");
}
- Konwertuj dane na JSON
- Zadzwoń do AJAX, aby otrzymać plik JSON
- 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);
}
}
}
Oto jedna, której nie widzę opublikowanej jako opcja. Jest podobny do używania 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, tak jak w tym przykładzie:
<script type="text/javascript" src="url_to_your_php_file.php?var1=value1" /></script>
Następnie w „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 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;
?>
Oto sztuczka:
Oto twoje 'PHP', aby użyć tej zmiennej:
<?php $name = 'PHP variable'; echo '<script>'; echo 'var name = ' . json_encode($name) . ';'; echo '</script>'; ?>
Teraz masz zmienną JavaScript o nazwie
'name'
, a oto twój kod JavaScript do używania tej zmiennej:<script> console.log("I am everywhere " + name); </script>
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 spróbujesz powyższej metody, otrzymasz coś takiego:
<script>var number = abcd;alert(number);</script>
Ale w JavaScript jest to błąd składni.
Więc w PHP mamy wywołanie funkcji, json_encode
która 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ż abcd
w 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
Po wielu badaniach stwierdziłem, że najłatwiejszą metodą jest łatwe przekazywanie wszystkich rodzajów 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 po prostu wywołaj te zmienne.
Zakładam, że dane do przesłania to ciąg.
Jak stwierdzili inni komentatorzy, jednym z możliwych rozwiązań jest AJAX, ale wady przeważają nad zaletami: ma opóźnienie i jest trudniejsze do zaprogramowania (potrzebuje kodu, aby pobrać wartość zarówno po stronie serwera, jak i klienta), gdy prostsza funkcja ucieczki powinna wystarczyć.
Więc wracamy do ucieczki. json_encode($string)
działa, jeśli najpierw zakodujesz łańcuch źródłowy jako UTF-8, w przypadku gdy jeszcze nie jest, ponieważ json_encode
wymaga 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 iconv
najpierw wykonać konwersję.
Ale jest duży problem. Jeśli używasz go w wydarzeniach, musisz uruchomić htmlspecialchars()
wynik, aby uczynić go poprawnym kodem. Następnie musisz albo uważać, aby użyć podwójnych cudzysłowów w celu ujęcia zdarzenia, albo zawsze dodawać je ENT_QUOTES
do 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żesz jednak używać htmlspecialchars
zwykłego kodu JavaScript (kod zawarty w tagach <script>
... </script>
). To sprawia, że korzystanie z tej funkcji jest podatne na błędy, polegające na zapominaniu o htmlspecialchars
wyniku podczas pisania kodu zdarzenia.
Możliwe jest napisanie funkcji, która nie ma tego problemu i może być używana zarówno w zdarzeniach, jak iw zwykłym kodzie JavaScript, o ile zdarzenia są zawsze ujęte w pojedyncze cudzysłowy lub zawsze w podwójne cudzysłowy. Oto moja propozycja, wymagająca, aby były w podwójnych cudzysłowach (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'";
}
Funkcja wymaga PHP w wersji 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>';
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 z span id, w tym przypadku nie musisz wykonywać żadnego wywołania serwera, ani Ajax, ani nic innego.
Twoja strona wydrukuje ją za pomocą PHP, a JavaScript uzyska wartość za pomocą DOM.
<?php
$val = $myService->getValue(); // Makes an API and database call
echo "
<script>
myPlugin.start({$val});
</script> ";
?>