From within PHP, I want at a certain point to change the content of a DIV called "menu".
In PHP, I do the following:
echo "<script> document.getElementById(\"menu\").innerHTML = \"NewContent\"; </script>";
And it perfectly works.
Then, things get more complicated, and I have a function that "creates" a piece of HTML, like this:
function createNewDiv() {
$o = "Click 'here'";
$o. = "<i onclick=\" $(\"#maindiv\").load('another.php'); return false; \">XXX</i>";
$o .= "<b>... and much, much more...</b>";
return $o;
}
In another area of the page, I do:
echo createNewDiv();
and it prints nicely, no syntax error whatsoever.
If I now try to do something like this:
echo "<script> document.getElementById(\"menu\").innerHTML = \"".createNewDiv()."\"; </script>";
it stops working with some syntax error (from the browser) due to strings that are interrupted "somewhere" by some quotes/double quotes.
I guess I must escape the quotes/double quotes somehow, I tried with addslashes() but it did not work.
Then I realized I only needed to escape the double quotes, so I did
$escaped = str_replace("\"", "\\\"", createNewDiv());
echo "<script> document.getElementById(\"menu\").innerHTML = \"$escaped\"; </script>";
But still it doesn't work! I know it's a truncated string somewhere, but unfortunately I cannot access the source because it's in an AJAX-updated div and the browser only shows me the main page.
I am just going mad thinking about the first function output, going into the str_replace, then into innerHTML, then printed by PHP, then interpreted by the browser... And I get lost "where" the quotes should be escaped ;)
You have nested double-quotes in:
$o. = "<i onclick=\" $(\"#maindiv\").load('another.php'); return false; \">XXX</i>";
It outputs:
<i onclick=" $("#maindiv").load('another.php'); return false; ">XXX</i>
Replace inner double quotes (around #maindiv) with single quotes:
<i onclick=" $('#maindiv').load('another.php'); return false; ">XXX</i>
or replace nested double-quotes with the " entity:
<i onclick=" $("#maindiv").load('another.php'); return false; ">XXX</i>
To make such replacement automatically, use the PHP's built-in htmlspecialchars() function.
By the way, during debug, it's generally a good idea to separate client side from server side. First make static HTML working, then convert it to a server-side scripted one. And consider using a template engine instead of hardcoding HTML into PHP code.
Related
All PHP generated Javascript Code I’ve done works, but this doesn’t … any idea?
echo "E-Mail an $row[firma] senden …<br />\n";
I’ve tried everything … print <<<HTML, print <<<JS … other quotes (single quotes, no quotes) … it just executes an HTML link …
It's hard to be sure - what's the value of $r and $row? Which part isn't working? What is the actual output of the markup, when you view the source? Are there any javascript errors in the Web Developer console?
I will make an assumption that $r and $row are valid PHP variables in this context, and that the linkTo_UnCryptMailto() javascript function exists.
I also note that the firma key is not enclosed in quotes - I am going to assume that's a typo.
Try simplifying the code and not parsing the variables within a "double quoted" string:
echo 'E-Mail an ' . $row['firma'] . ' senden …<br />';
The issue I'm having is with escaped html inside of a javascript function, passed from blade. $message contains basic html or strings with quotes, so if I use {!! !!} it doesn't work because it seems that the output from blade into the function needs to be in quotes.
Inside javascript script tag
#foreach ($messages as $message)
addMessages('{{$message['message']}}', '{{$message['message_side']}}');
#endforeach
addMessages javascript function
addMessages = function (text, message_side) {
var $messages, message;
if (text.trim() === '') {
return;
}
$('.message_input').val('');
$messages = $('.messages');
message = new Message({
text: text,
message_side: message_side
});
message.draw();
return $messages.animate({ scrollTop: $messages.prop('scrollHeight') }, 300);
};
So I believe the issue is in double-escaping: first data is escaped by Blades with calling htmlspecialchars()(according to docs) and later it's escaped somewhere in JS code(it may not be escaped directly rather threated as a text through createTextNode(message) or innerText = message).
So you need to turn one of these escape calls off.
As you mentioned you could use { !! } to output raw text on Blade side. And yes, this still needs to be wrapped with quotes(single or double) to be valid JS code. But you should care about the-same-type-quotes(single or double) inside you text to omit such a case:
addMessage('It's me. I'm broken')
To achieve that you can just escape approrpiate quote mark manually with a slash to get something like
addMessage('It\'s me. I\'m broken')
[UPD] as #Ian Fain mentioned it's possible to call functions right inside the { !! }
So finally this escaping can be done without any custom directive as easy as
#foreach ($messages as $message)
addMessages({!! json_encode($message['message']) !!}, {!! json_encode($message['message_side']) !!})
#endforeach
Also mention json_encode adds additional double quotes so they are not needed to be inserted directly anymore.
Please tell me why this code tells me
SyntaxError: unterminated string literal
My code:
<script>
console.log(" <?php $geladen = file_get_contents("./testtext"); echo $geladen; ?> ");
</script>
That's a JavaScript error message, which strongly implies one of two things:
the JavaScript that reaches the browser still includes the <?php etc., meaning the PHP didn't get parsed on the server (and thus the browser flipped out on "./testtext"), or
the file testtext (and therefore your variable $geladen) contains quotation marks. Either is possible from the very little information you have posted.
You can figure out which it is by looking at the HTML in your browser.
If it's the former (if you see <?php in the HTML), then you need to fix your server configuration.
If it's the latter (if testtext contains any " marks), then you need to encode it properly before echoing, using json_encode() like this:
<script>
console.log(" <?php $geladen = file_get_contents("./testtext"); echo json_encode($geladen); ?> ");
</script>
All that said, mixing PHP and HTML (not to mention PHP, HTML, and JavaScript) this way is not a great practice. You'd be much better off using a templating engine of some sort (Twig, Blade, etc.).
If the contents of 'testtext' contains a quote mark, it will break the javascript. Try addslashes().
<script>
console.log(" <?php $geladen = addslashes(file_get_contents("./testtext")); echo $geladen; ?> ");
</script>
I want to update innerhtml of div with id NotifyDiv
I want to change it with following html code.
$html="<ul id='js-news'><li>HELLO WORLD!</li></ul>";
I am using following code to change it.
echo "<script>document.getElementById('NotifyDiv').innerHTML='$html'</script>";
But no changes occur.
However it I remove id = 'js-news' from the above ul tag it works.But I'll need the id.
If you check the source code of your browser you will see this:
<script>document.getElementById('NotifyDiv').innerHTML='<ul id='js-news'><li>HELLO WORLD!</li></ul>'</script>
So we can see that in the JavaScript string you are using apotrophes, but the string is already encloded with apostrophes, so it attempts to end the string early: (before the letter j in js-news)
'<ul id='js-news'><li>HELLO WORLD!</li></ul>'
This can be solved by using escaped quotation marks for the JS string:
echo "<script>document.getElementById('NotifyDiv').innerHTML=\"$html\"</script>";
Basically, the code you have causes a syntax error in JS:
echo "...innerHTML='$html'</script>";
expands to:
// opening ' closing ' => js-news === syntax error!
// \/ \/
echo "...innerHTML='<ul id='js-news'><li>HELLO WORLD!</li></ul>'</script>";
Resulting JS code:
document.getElementById('NotifyDiv').innerHTML='<ul id='js-news'><li>HELLO WORLD!</li></ul>'
The syntax highlighting shows the problem
Note the single quotes around $html and the single quotes inside the $html string. The best way to echo PHP values in JS would be to use json_encode:
echo "...document.getElementById('NotifyDiv').innerHTML=", json_encode($html), "</script>";
The output should be something like:
<script>document.getElementById('NotifyDiv').innerHTML="<ul id='js-news'><li>HELLO WORLD!<\/li><\/ul>"</script>
Now, those slashes are escaped, and you probably don't want that. Thankfully, there's a second parameter you can pass to json_encode: cf the docs. Passing JSON_UNESCAPED_SLASHES is what you need to do here:
$html="<ul id='js-news'><li>HELLO WORLD!</li></ul>";
echo "<script>document.getElementById('NotifyDiv').innerHTML=".json_encode($html, JSON_UNESCAPED_SLASHES)."</script>";
The output:
<script>document.getElementById('NotifyDiv').innerHTML="<ul id='js-news'><li>HELLO WORLD!</li></ul>"</script>
DEMO
Perfect ans to your query is as under (just copy n paste and check it)
<?php
$html="<ul id='js-news'><li>HELLO WORLD!</li></ul>";
?>
<script type="text/javascript">
document.getElementById('NotifyDiv').innerHTML="<?php echo $html; ?>";
</script>";
You need to pass PHP variable with PHP syntax that is <?php ?>
Even if we can mix PHP, JavaScript and HTML together, we need to initialize proper languages before using their variables in case of JavaScript and PHP.
So, final code should be:
echo "<script>document.getElementById('NotifyDiv').innerHTML = '<?php echo $html;?>'</script>";
Otherwise, everything looks correct.
I have a database form on a MySql table on which I have a javascript function to populate the options of a select tag. Those options are fetched from a table of clients who have a status of either "Active" or "Inactive", and the return values are of those clients where their status is active. In the event an order is loaded where the client status is inactive, I'm trying to add a handler for inactive clients. The form loads from a php script that left joins the client table to the main table, where clientId in the main table is equal to Id in the client table. So, I have the name and id of the client fetched outside of the function to populate the options list, regardless of their status.
There is one line that is causing me fits. I have searched this site and others and have found many solutions, but none have worked for me so far. This is the line:
var txt = <?php echo $row[`clients`.'name']; ?> ;
What is returned in Chrome and Firefox debuggers is, "Uncaught syntax error: Unexpected token <". The debugger shows: var txt = <br />
I've tried enclosing the php script in single quotes, double quotes, and without quotes, and still no luck. Any thoughts, anyone?
About an hour later--> I found a workaround. I tried all of your suggestions, but none worked in this instance. var_dump and json_encode confirmed what I knew already, that the returned data was valid. Regardless of any of the variations in syntax, they all returned the same error. What I did was to apply the same syntax as above, but in a hidden input:
<input type="text" id="cName" hidden value="<?php echo $row[`clients`.'name']?>" />
Then changed the javascript code to this:
var txt = document.getElementById('cName').value;
Everything else works perfectly. Of course, I still have lingering thoughts about the use of backticks, and would prefer that I had a better, and safer code. As I mentioned somewhere, I simply copied the sql syntax directly from phpMyAdmin. In this instance, if I substitute single quotes for the backticks, the input returns nothing. Well, thanks all. If anyone wants to contribute more, I'll be glad to hear about it.
That's illegal PHP syntax, and very dangerous syntax in general. Try doing a var_dump($row) to see exactly what's in that array. Probably you want something more like
var txt = <?php echo json_encode($row['clients.name']); ?>;
instead.
Note the use of json_encode(). This will ENSURE that whatever you're spitting out in the JS code block is actually syntactically valid javascript.
e.g. consider what'd happen if you ended up with
var txt = Miles O'Brien;
^^^^^--undefined variable;
^--- another undefined var
^--- start of a string
^^^^^^^---unterminated string.
with json_encode(), you end up with
var txt = "Miles O'Brien";
and everything's a-ok.
var txt = "<?php echo $row['clients']['name']; ?>";
var txt = <?php echo $row[`clients`.'name']; ?> ;
Consider how PHP parses this:
var txt = is to be output directly to the client.
Enter PHP mode.
echo the following expression.
Evaluate $row[`clients`.'name'].
First we need to determine the array index, which is the concatenation of `clients` and 'name'.
Backtick in PHP is the execution operator, identical to shell_exec(). So PHP attempts to execute the shell command clients, which probably fails because that isn't what you intended and it doesn't exist. Consequently, at this stage, PHP outputs an HTML error message, starting with a line break <br />.
Your client now has var txt = <br /> (you can verify this by inspecting the HTML source of the page returned to your browser), which it attempts to evaluate in its JavaScript context. This gives rise to the "unexpected token" error that you have witnessed.
As others have mentioned, you probably meant to do something like $row['clients']['name'] or $row['clients.name'] instead—but without seeing the rest of your PHP, it's impossible to be sure. Also, as #MarcB has observed, you need to be certain that the resulting output is valid JavaScript and may wish to use a function like json_encode() to suitably escape the value.
The error comes from the fact that your return value (a string in javascript) must be in quotes.
Single quotes will take whatever is between them literally, escapes (like \n ) will not be interpreted, with double quotes they will.
var txt = "<?php echo $row['clients']['name']; ?>";
is what you want
Change this
var txt = <?php echo $row['clients'.'name']; ?> ;
to this:
var txt = <?php echo $row['clients']['name']; ?> ;