How to pass variables and data from PHP to JavaScript?
I have a variable in PHP, and I need its value in my JavaScript code. How can I get my variable from PHP to JavaScript?
I have code that looks like this:
<?php
...
$val = $myService->getValue(); // makes an api and db call
?>
I have JavaScript code that needs val
and looks along the lines of:
<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>
There are actually several approaches to do this. Some require more overhead than others, and some are considered better than others.
In no particular order:
In this post, we'll examine each of the above methods, and see the pros and cons of each, as well as how to implement them.
1. Use AJAX to get the data you need from the server
This method is considered the best, because your server side and client side scripts are completely separate .
Pros
Cons
Implementation Example
With AJAX, you need two pages, one is where PHP generates the output, and the second is where JavaScript gets that output:
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 (or whatever the actual page is named like)
<!-- 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 -->
The above combination of the two files will alert 42
when the file finishes loading.
Some more reading material
2. Echo the data into the page somewhere, and use JavaScript to get the information from the DOM
This method is less preferable to AJAX, but it still has its advantages. It's still relatively separated between PHP and JavaScript in a sense that there is no PHP directly in the JavaScript.
Pros
Cons
<input type=hidden>
to store the information, because it's easier to get the information out of inputNode.value
, but doing so means that you have a meaningless element in your HTML. HTML has the <meta>
element for data about the document, and HTML 5 introduces data-*
attributes for data specifically for reading with JS that can be associated with particular elements. Implementation Example
With this, the idea is to create some sort of element which will not be displayed to the user, but is visible to 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 the data directly to JavaScript
This is probably the easiest to understand, and the most horrible to use. Don't do this unless you know what you're doing.
Pros
Cons
Implementation Example
Implementation is relatively straightforward:
<!-- snip -->
<script>
var data = <?php echo json_encode("42", JSON_HEX_TAG); ?>; //Don't forget the extra semicolon!
</script>
<!-- snip -->
Good luck!
I'm going to try a simpler answer:
Explanation of the problem
First, let's understand the flow of events when a page is served from our server:
So really, the core thing to remember here is that HTTP is stateless . Once a request left the server, the server can not touch it. So, that leaves our options to:
Solutions
That's the core question you should be asking yourself is:
Am I writing a website or an application?
Websites are mainly page based, and the page load times needs to be as fast as possible (for example - Wikipedia) . Web applications are more AJAX heavy and perform a lot of round trips to get the client fast information (for example - a stock dashboard).
Website
Sending more requests from the client after the initial request is done is slow as it requires more HTTP requests which have significant overhead. Moreover, it requires asynchronousity as making an AJAX request requires a handler for when it's complete.
I would not recommend making another request unless your site is an application for getting that information from the server.
You want fast response times which have a huge impact on conversion and load times. Making ajax requests is slow for the initial uptime in this case and unneeded.
You have two ways to tackle the issue
Setting a cookie is really not very difficult, you just assign it a value:
setcookie("MyCookie", $value); // sets the cookie to the value, remember, do not
// set it with HTTP only to true.
Then, you can read it with JavaScript using document.cookie
:
Here is a short hand rolled parser, but the answer I linked to right above this has better tested ones:
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.
Cookies are good for a little data. This is what tracking services often do.
Once we have more data, we can encode it with JSON inside a JS variable instead:
<script>
var myServerData = <?=json_encode($value)?>; // don't forget to sanitize
//server data
</script>
Assuming $value
is json_encode
able on the PHP side (it usually is). This technique is what StackOverflow does with its chat for example (only using .net instead of php).
Application
If you're writing an application - suddenly the initial load time isn't always as important as the ongoing performance of the app and it starts to pay off to load data and code separately.
My answer here explains how to load data using AJAX in 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();
Or with jQuery:
$.get("/your/url").done(function(data){
// what do I do with the data?
});
Now, the server just needs to contain a /your/url
route/file that contains code that grabs the data and does something with it, in your case:
<$php
...
$val = myService->getValue(); // makes an api and db call
echo json_encode($val); // write it to the output
$>
This way, our JS file asks for the data and shows it rather than asking for code or for layout. This is cleaner and starts to pay off as the application gets higher. It's also better separation of concerns and it allows testing the client side code without any server side technology involved which is another plus.
Postscript: You have to be very aware of XSS attack vectors when you inject anything from PHP to JavaScript. It's very hard to escape values properly and it's context sensitive. If you're unsure how to deal with XSS, or unaware of it - please read this OWASP article, this one and this question.
I usually use data-* attributes in 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>
This example uses jQuery but can be adapted for another library or vanilla Javascript.
You can read more about the dataset property here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset
链接地址: http://www.djcxy.com/p/23652.html