echo '<li onclick="fill(\''.$row["value"].'\');">'.$row["value"].'</li>';
Ouch. You've got a JavaScript string literal, inside an HTML-encoded attribute, inside a PHP string literal. No wonder the escaping is confusing you.
Well, first: you're outputting $row['value']
in the list item's text without escaping. This means trouble (potentially security trouble) when that value contains special characters like <
, &
and "
. This needs to be wrapped in htmlspecialchars()
.
Next, you're putting something in a JavaScript string literal. That means if the string delimiter character '
or the escaping backslash \
is used in the value, it can break out of the string and inject JavaScript code into the page: again, a potential security issue. addslashes()
can be used to escape a string for inclusion in a JS string literal; note you still have to htmlspecialchars()
it afterwards because the string literal is itself inside an HTML-encoded attribute.
So we're looking at:
echo "<li onclick=\"fill('".htmlspecialchars(addslashes($row['value']), ENT_QUOTES)."');\">".htmlspecialchars($row['value']).'</li>';
Not very readable, is it? Well, we can improve that:
We can lose the PHP string literal by using PHP itself to interpolate strings (as demonstrated by Jonathan). PHP is a templating language, take advantage of that!
We can define a function with a shorter name than htmlspecialchars
, which is a good idea since we need to use that function a lot in a typical template.
We can avoid the JavaScript string literal by having the JavaScript side read the data it needs from the contents of the list item (text()
, in jQuery, since that's what you seem to be using), rather than having to wrap it inside an ugly inline event handler.
For example:
<?php
function h($text) {
echo(htmlspecialchars($text, ENT_QUOTES));
}
?>
<ul id="suggesties">
<?php while ($row= mysql_fetch_array($r)) { ?>
<li><?php h($row['value']); ?></li>
<?php } ?>
</ul>
<script type="text/javascript">
$('#suggesties>li').click(function() {
$('#inputString').val($(this).text());
$('#suggesties').hide();
});
</script>