2

Like this:

<script>
 setSomeStuffUp();
 <?php if ($otherStuffNeedsToBeDone === true) { ?>
 doSomeOtherStuff();
 <?php } ?>
 breakSomeStuffDown();
</script>

Came across something like this at work- done with templating (Smarty), so it looks a bit cleaner- but not by much! Also echoes some template variables used for things such as jQuery selectors, and other little unpleasant-looking bits.

What's the proper way to do this? Load the data that needs to be used for logic in the JS as JSON via AJAX? HTML data attributes?

Something about it just smells bad, bad, bad.

Thanks everyone.

asked Jul 25, 2012 at 21:03
5
  • I normally don't do stuff like that myself, but see it all the time, and as far as I know there's nothing wrong about using serverside languages to output javascript, or anything else for that matter, one is on the server, the other on the client, they don't really interact. Commented Jul 25, 2012 at 21:08
  • Don't see anything wrong with it. Commented Jul 25, 2012 at 21:08
  • 2
    I don't see anything wrong with it, however i do everything i can to stay away from it to keep the separation between client-side and server-side. Commented Jul 25, 2012 at 21:10
  • As long as the chunk in doSomeOtherStuff(); is not a large amount of code I think it is acceptable. Commented Jul 25, 2012 at 21:15
  • 1
    It's nothing wrong with it. However, I tend to run away from such things. As Oscar Jara said, it's bad practice to use language X to generate code in language Y. Try whenever to decouple PHP and JS, better even HTML and JS. Commented Jul 26, 2012 at 12:39

5 Answers 5

4

It is bad practice to use language X to generate code in language Y.

Try "decoupling" the two languages, for example, like this:

<script type="text/javascript">
 var data = {
 id: "<?php echo $id ?>",
 ...
 };
 $(document).ready(function(){
 $("#" + data.id).on("click", function(){
 /*do something*/
 });
 });
</script>

This way, PHP only cares about populating the data structure and JavaScript only cares about consuming the data structure.

answered Jul 25, 2012 at 21:12
Sign up to request clarification or add additional context in comments.

8 Comments

+1 for basically the best and most succinct answer possible to this question. Keep as much of your JS code as possible static, and where possible, only generate data structures dynamically.
Strictly speaking this is not decoupling the two languages at all.
@Mahn that's why I used quotes.
But it's still relying on PHP. You can put make up to a horse, but that won't make it less of a horse.
@Mahn It's just a expression, don't be so strict. This way you are reducing mess.
|
3

Echoing configuration variables and some javascript initialization code from server doesn't sound too bad in general, but if such js-injection-from-server pieces are all over the place then you're right, it's ugly, at least because such code is difficult to manage.

Just try to centralize any kinds of initialization and do the rest in statically-defined client-side JavaScript logic.

UPD. @Oscar Jara is talking about the same thing and provided a good illustration. But often even such cases can be avoided if server-side logic provides data for JavaScript processing via HTML (after all, that's what HTML is for).

Here's a trivial example that you can often encounter. Say you want to output a gallery that will be enhanced into a carousel via JavaScript.

Server generated HTML:

<ul id="myGallery">
 <li><img src="img1.jpg /></li>
 <li><img src="img2.jpg /></li>
 <li><img src="img3.jpg /></li>
 ...
</ul>

And then you have your static JavaScript code initialize the carousel when DOM is ready:

// when DOM ready...
AwesomeCarousel.init($('#myGallery'));

Here the data prepared by the server is this piece of HTML with a list of images, no need to generate JavaScript explicitly loading every image. You can pass arbitrary data via the data-* attributes.

answered Jul 25, 2012 at 21:12

Comments

2

Personally, I use PHP in JS in many instances. Sometimes it is to populate a variable with JSON data, a page id, or something of that nature. As far as I am concerned, PHP is designed to write the code that appears on the page, and JS is designed to interact with the user once the content is there.

I do get what you are saying, in that there are probably cleaner ways of doing this. You mentioned AJAX, which would probably be cleaner and would definitely help the flow of the document being output. The only issue is that you have to make a second request to the server for some very simple and meanial variable. A few milliseconds isn't huge, but in the a production website, you probably don't want to be making that additional request and bogging down server resources.

In response to what the cleanest way to do it would be, if it was that big of a deal... I would create a separate JS file with that code and then use the server to include that individual file if needed. Again, I don't do this, but I think it would look the cleanest in the template.

answered Jul 25, 2012 at 21:12

Comments

2

If you want to get really out-there, you can have the HTML page request a .js file, coupled with their session-id or some other indicator of who they are, operate the .js call as a PHP call, dynamically build the JS based on what their session requires and then output it back to the browser as a .js filetype.

But that's a lot of work.

If you'd like something that smells less, have PHP dump either a JSON-string at the end of your file:

var cfg_string = "{\"username\":\"Norguard\", \"new_messages\":[......]}"; // client
$cfg_obj = array(); // whole lot o'PHP
$json_encoded_cfg = json_encode($cfg_obj);
echo "var cfg_string = {$json_encoded_cfg};" //server-side

And then parse it, in the client for added safety...

...or just outright create a map in the template:

$cfg_string = "var dataMap = {";
foreach ($cfg_obj as $key => $val) {
 // print key:val all pretty-like,
 // handle commas (ie: no trailing comma at the end), indent with tabs or spaces
 // if you want, count the number of items so that the object closes ({})
 // without any newline operator, if there are no config settings 
}
echo $cfg_string;

Both of these are clean and unobtrusive and keep everything separate. The config data/text can go right above whatever your init/loading code is going to be, and be passed in as a parameter to that init-logic.

answered Jul 25, 2012 at 21:31

Comments

1

If all you're doing is passing data from the server-side language to the JavaScript code, then that's fine. Plenty of CMS packages out there do it.

I don't really see the need to conditionally generate JavaScript code on the server side. Maybe there's a use case for it but JavaScript is a language itself, so why not just put the logic in the JavaScript code?

answered Jul 25, 2012 at 21:09

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.