I'm trying to use PHP to echo a set of buttons (buy & sell) in a stock trading game. The buttons will eventually have an onclick= event handler that calls a JavaScript function to populate some fields on a form, but I'm just trying to get an alert() with one piece of data to work. I just can't get the results from my echo statement to print the alert correctly, so it doesn't even trigger. I've also used print_r ($stockInfo) to ensure my array is properly filled with test data.

Here's my array:

$stockInfo = array(
    array('name' => 'Company 1', 'description' => 'Description 1', 'price' => '100', 'yield' => '.05'),
    array('name' => 'Company 2', 'description' => 'Description 2', 'price' => '89', 'yield' => '.06'),
    array('name' => 'Company 3', 'description' => 'Description 3', 'price' => '110', 'yield' => '.03')
);

And my PHP code that attempts to generate a button:

<?php
echo <<<EOT
    <button id="buy" class="btn btn-primary btn-small" onclick="alert('$stockInfo[0]["name"]');">Buy</button>
EOT;
?>

The result of that code is:

<button id="buy" class="btn btn-primary btn-small" onclick="alert('Array["name"]');">Buy</button>

I just can't figure out why I can't get even a simple alert to fire. Running:

echo $stockInfo[0]["name"];

Correctly prints out "Company 1", but it doesn't print that text in the argument of the alert().

I've read Stackoverflow, lots of web articles, and experimented for the past day and I just can't figure this out. If anyone can provide any help, I'd GREATLY appreciate it.

Thanks!

share|improve this question

3 Answers

up vote 4 down vote accepted

To use variables in heredoc syntax, you have to put curly brackets around them:

<?php
echo <<<EOT
    <button id="buy" class="btn btn-primary btn-small" onclick="alert('{$stockInfo[0]["name"]}');">Buy</button>
EOT;
?>
share|improve this answer
@Madmartigan Thanks, I was just adding that when I got the message that my answer already had been edited. – jeroen Mar 19 '12 at 21:30
Since this isn't always true, I'm looking for the actual passage that explains it, the closest I found was: "Heredoc text behaves just like a double-quoted string, without the double quotes. This means that quotes in a heredoc do not need to be escaped, but the escape codes listed above can still be used. Variables are expanded, but the same care must be taken when expressing complex variables inside a heredoc as with strings. " – mog Mar 19 '12 at 21:31
Thank you so much jeroen & Madmartigan (I loved Willow!). That worked. I'm very new to PHP and echoing complex strings is definitely the thing that's tripping me up the most right now. I'll use your code as a base for other things I write. Thanks again! – Kyle Carlson Mar 20 '12 at 2:09
And just an FYI to others using HEREDOC syntax, the final "EOT;" must have NOTHING in front of it. I got an error when there was a tab in front, but the statement worked once I pushed it all the way to the left. Weird, but at least it's working. – Kyle Carlson Mar 20 '12 at 2:35
1  
@jeroen Yep, I saw that after fiddling around with HEREDOC for a while. I didn't start with the official docs, I just read some blog posts & tutorials and none of them mentioned that EOT needed to be pushed all the way to the left. Still doesn't make much sense why leading spaces/tabs would make a difference, but at least I know :) – Kyle Carlson Mar 20 '12 at 13:26
show 1 more comment

Ideally, you don't want to put variables directly into your output like that because if there's just a single ' in that string your JavaScript will screw up.

Instead, avoid both problems by not using HEREDOC and using the proper method:

echo "<button id=\"buy\" class=\"...\"
   onclick=\"alert(".htmlspecialchars(json_encode($stockInfo[0]['name'])).");\">Buy</button>";

json_encode essentially makes any PHP variable (except resources) able to be dumped directly into JavaScript code.

htmlspecialchars makes the result safe to use in an HTML attribute.

share|improve this answer
That looks just about perfect, and the HTML that it renders is: <button id="buy" class="buy0" onclick="alert("Company 1");">Buy</button>, but it still doesn't work. That looks like the exact markup that should produce an alert though. – Kyle Carlson Mar 20 '12 at 2:05
It wouldn't work because json_encode produces double quotes, and the attribute is already using them. – mog Mar 20 '12 at 7:51
Good point. I forgot to take that into account. Fixing in 5 seconds. – Kolink Mar 20 '12 at 8:51
Happened to notice your update but you just made more problems. You need the alert()'s value single quoted, or change the onclick attribute's quotes to singles. Good to use htmlspecialchars, but you're doing it backwards. There's really no need for json_encode here. Your statement about "makes any PHP variable (except resources) able to be dumped directly into JavaScript code" is much too broad to be useful, so I'm afraid I have to mark down this answer. Here is a demo of your code: codepad.org/aXw3esy6 – mog Mar 20 '12 at 18:19
Your statement about htmlspecialchars making any attribute safe is also misleading, especially in the context of javascript where you can do tricks without the use of HTML special characters. It's just better not to put untrusted data in js event attributes altogether. But yes, it would make it "safe" in the sense that it would be valid HTML/JS. – mog Mar 20 '12 at 18:25
show 3 more comments
echo <<<EOT
    <button id="buy" class="btn btn-primary btn-small" onclick="alert({$stockInfo[0]["name"]});">Buy</button>
EOT;
?>
share|improve this answer
Thanks a lot, but that didn't work for me :( – Kyle Carlson Mar 20 '12 at 2:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.