Can't generate Javascript from data with parentheses - php

I'm using a PHP/MySQL connection to add a search suggestions feature to my site. It's all working except for one piece. My data all contains parentheses in the values, so when I'm trying to pass the returned data to the input field my onclick function fails! code is as follows:
while ($result = $query->fetch_object()) {
echo '</li><li onclick="fill(\''.$result->name.'\');">'.$result->name.'</li>';
}
The list populates from the returned search results, but the query returned looks like this:
</li><li onclick="fill('Boire Field, Nashua, NH, US (KASH)');">
Boire Field, Nashua, NH, US (KASH)</li>
Firebug gives me the following:
unterminated string literal
fill('Boire Field, Nashua, NH, US (KASH)
The ) in the result is prematurely ending the string. How can I escape this out so it will properly call the function?

As the Brad Suggests.. The best way is JSON_ENCODE
while ($result = $query->fetch_object()) {
echo '</li><li onclick="fill(\''.json_encode($result->name).'\');">'.$result->name.'</li>';
}

Related

How would this argument be properly escaped in PHP?

My site has some PHP generated content which echoes HTML elements. Some of these elements are responsive to javascript events...for one input element, the relevant event is onmouseout, but I can't seem to escape this properly.
$sql = mysqli_query($cxn, "SELECT stuff1, stuff2, stuff100, tags FROM myTable WHERE user_id = 'myID'");
while ($row = mysqli_fetch_assoc($sql)) {
$Tagstring = $row['tags'];
//lots of code
echo "<div class='myClass1 myClass2'>
<input type='text' name='myInput' value='".$Tagstring."' onmouseout='ajaxFunction(\"myString\", this.value.trim().replace(/,\s|\s,/g, ","))'>
</div>";
//more code
}
$Tagstring is a comma-separated string of text substrings. If a user edits his/her tags, I am trying to prevent the following:
$Tagstring = 'tag1,tag2'; //from database table
//User edits to 'tag1, tag2';
//Pointless ajax call and access of server, since if user input = original $Tagstring, this will return false as I have set up the ajax call, but if user input !== $Tagstring, then ajax function proceeds
I am not new to PHP and Javascript, so I know in PHP about str_replace or exploding the user input on "," and then trimming each member of the explode array. Alternatively, I could use Javascript to split on "," and then trim the pieces in a for loop (or something similar).
Can anyone tell me how to properly escape the following argument in my echoed function call?
this.value.trim().replace(/,\s|\s,/g, ",")
I tend to echo my output opposite of the way you have done it, which I feel is easier to control. Single quotes on the outside, and double quotes on the inside.
echo '<div class="myClass1 myClass2">
<input type="text" name="myInput" value="'.$TagString.'" onmouseout="ajaxFunction("myString", this.value.trim().replace(/,\s|\s,/g, ""))">
</div>';
What is the error you are seeing?
Fixed it...it seemed to be an escaping issue. This worked :
onmouseout='ajaxFunction(\"AStringNotAVariable\", this.value.trim().replace(/,\s|\s,/g, \",\"))'
whereas
//.replace(/,\s|\s,/g, ",") and .replace(/,\s|\s,/g, ',') and .replace(/,\s|\s,/g, \',\')
led to errors such as Uncaught SyntaxError: Unexpected token ILLEGAL

autocomplete shows all entries, Does not do any searching

Please help me ...
I'm a newbie! Please tell me what to do.
processed.php
<?php
include_once('../../dbConnect.inc.php');
$sql="SELECT name FROM artist";
$artist = select($sql);
disconnect();
$output_items = array();
while($row = mysql_fetch_array($artist))
{
$results[] = array('label' => $row['name']);
}
echo json_encode($results);
?>
index.php
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#artist").autocomplete(
{
source: 'processed.php',
});
});
</script>
I have this problem: http://jsbin.com/alaci5
Autocomplete expects the source (when an URL is specified to filter out the results).
From documentation:
String: When a string is used, the Autocomplete plugin expects that
string to point to a URL resource that will return JSON data. It can
be on the same host or on a different one (must provide JSONP). The
Autocomplete plugin does not filter the results, instead a query
string is added with a term field, which the server-side script should
use for filtering the results. For example, if the source option is
set to "http://example.com" and the user types foo, a GET request
would be made to http://example.com?term=foo. The data itself can be
in the same format as the local data described above.
So in your PHP code you have to do:
include_once('../../dbConnect.inc.php');
$sql="SELECT name FROM artist WHERE `name` like '%".mysql_real_escape_string($_GET['term'])."%'";
$artist = select($sql);
$output_items = array();
while($row = mysql_fetch_array($artist)) {
$results[] = array('label' => $row['name']);
}
echo json_encode($results);
That autocomplete function is probably passing a few variables to your processed.php page.
Use var_dump($_GET) to see all the things you're being passed.
Inside one of those $_GET elements, you'll have the contents of the text box as they exist on the page. For the sake of demonstration, I'm going to use $_GET['text']. You'll need to find out which part holds the data you need.
What you'll need to do is search the database using this value for a list of results to return.
$sql="SELECT name FROM artist";
$artist = select($sql);
This is your script as it exists. What it may end up looking similar to is this.
$text_input = mysql_escape_string($_GET['text']);
$sql="SELECT name FROM artists WHERE name LIKE '%$text_input%'";
$artist = select($sql);
You'll want to get results that are similar to the inputted text on the user-facing page.
A few notes for you
I used mysql_escape_string() solely to may what you already have. While this does work (driving around a busted-ass chevy pacer works too, but there are much better ways though), its not recommended, which sets us up for point 2.
Using the old mysql extension is not really a good idea, its been replaced by mysqli, and PDO.
you'll need to escape your data, this is how its done with mysqli.

Using jquery and javascript to display variable from PHP

I'm trying to display a PHP variable using javascript/jquery but it's displaying 'null'.
if(mysql_num_rows($checkBan) > 0){
$bannedDate = $checkBan['banLength'];
if(preg_match('/[0-9]/',$bannedDate)){
list($yyyy,$mm,$dd) = explode('-',$bannedDate);
$date = $mm."-".$dd."-".$yyyy;
}
//$date = "test"; when this is uncommented it appears in the alert so I know the json_encode is working fine
?>
<script type ="text/javascript">
var bannedUntil= <?php echo json_encode($date); ?>;
alert('Your account has been banned until ' + bannedUntil +'. Please contant an administrator if you believe this is an error');
</script>
<?
}
The alert appears just fine, but the bannedUntil variable is null. However, when the second date variable is uncommented it appears in the alert. It's not a separate function so I don't see why the scope would be an issue.
I am seeing you use $checkBan as a result resource in mysql_num_rows(), then attempt to access an array key from it without fetching. You appear to be missing a call to mysql_fetch_assoc():
if(mysql_num_rows($checkBan) > 0){
// Fetch a row from the result resource $checkBan
$row = mysql_fetch_assoc($checkBan);
$bannedDate = $row['banLength'];
// etc...
}
Another tip: It looks like you are getting a standard MySQL date format back as YYYY-MM-DD and converting it with string operations in PHP to MM-DD-YYYY. Just retrieve it in that format in your query to begin with and avoid the explode() and list() calls in your PHP application code.
SELECT DATE_FORMAT(banLength, '%m-%d-%Y') FROM yourtable

How to return a specific variable from PHP to Android

I have followed his popular tutorial to connect Android to MySQL:
http://www.helloandroid.com/tutorials/connecting-mysql-database
It is great at encoding the data back in JSON and displaying rows of data.
My question: What id I want to return just a single value, a single varaible from PHP to Java?
Here is my PHP:
$sql="SELECT AVG(rating) FROM ratings WHERE item_id = 1";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);
echo $row[0];
I want to send that last "echo" back to Android, on the guidelines of that tutorial above, how would I do this?
$row is an array and it should have a value like:
$row['AVG(rating)'] = <some value>
All you need to do is throw the json_encode function around row and echo it out
print(json_encode($row));
This should get you the single value json encoded string that the java code can read.
If you are using WebView try addJavascriptInterface(new JavaScriptInterface(this), "Android") http://developer.android.com/guide/webapps/webview.html and call
<script type="text/javascript">
function showAndroidToast(avg_value) {
Android.echo(avg_value);
}
</script>

Display personal messages list

I have a personal message system in my website done simply with php/sql. Actually I am facing the trouble to display them using jquery. The db has as fields: message_id, message_from, message_to, message_topic, message_subject and message_status. The way I am showing the message_topic is repeating eight times the following:
echo '<table><tr><td>';
retrieve_msg_topic($result);
echo '</td></tr>'; //of course I won't make 8 tables!!!
the function called is:
function retrieve_msg_topic($result)
{
if($row = mysql_fetch_assoc($result))
{
echo $row['usernombre'];
$message_topic = stripslashes($row['message_topic']);
echo '<div id="msg'.$row['message_id'].'">';
echo $message_topic;
echo '</div>';
//this will return: <div id="msgN">message topic (title, commonly subject)</div>
}
} //end function retrieve msg topic
So far I have a list on a table with the last eight messages sent to the user. The following row is reserved for pagination (next/prior page) and, after that, another row showing the message I select from the list presented, like we see in Outlook. Here is my headache. My approach is to call another function (8 times) and have all of them hidden until I click on one of the messages, like this:
echo '<tr><td>';
retrieve_msg_content($result);
retrieve_msg_content($result); //repeat 8 times
echo '</td></tr></table>';
the function this time would be something like this:
function retrieve_msg_content($result)
{
if($row = mysql_fetch_assoc($result))
{
echo '<script type="text/javascript">
$(document).ready(function(){
$("#msg'.$row['message_id'].'").click(function(){
    $(".msgs").hide(1000);
$("#'.$row['message_id'].'").show(1000);
});
});
</script>';
echo '<div class="msgs" id="'.$row['message_id'].'" style="display: none">'
.$row['message_subject'].
'</div>';
}
/* This function returns:
// <script type="text/javascript">
// $(document).ready(function(){
// $("#msgN").click(function(){
// $(".msgs").hide(1000);
// $("#N").show(1000);
// });
// });
// </script>
// <div class="msgs" id="N" style="display: none">Message subject (body of message)</div>
*/
} //end function retrieve msg content/subject
I could simply explain that the problem is that it doesn't work and it is because I do if($row = mysql_fetch_assoc($result)) twice, so for the second time it doesn't have any more values!
The other approach I had was to call both the message_topic and message_subject in the same function but I end up with a sort of accordion which is not what I want.
I hope I was clear enough.
The easiest way to fix your troubles would be to copy the results of the MySQL query into an array
while($row = mysql_fetch_assoc($result)) {
$yourArray[] = $row;
}
And then use that to build your tables.
edit: What I meant was more along the lines of this:
while($row = mysql_fetch_assoc($result)) {
$yourArray[] = $row;
}
echo '<table>';
foreach($yourArray as $i) {
retrieve_msg_topic($i);
}
echo '<tr><td>';
foreach($yourArray as $i) {
retrieve_msg_content($i);
}
echo '</tr></td></table>';
And then removing everything to do with the SQL query from those functions, like this:
function retrieve_msg_topic($result) {
echo '<tr></td>'$result['usernombre'];
echo '<div id="msg'.$result['message_id'].'">';
echo stripslashes($result['message_topic']);
echo '</div><td></tr>';
}
Right now you're doing some weird key mojo with ret[0] being the topic and $ret[1] being the message, which isn't a good practise. Also, I don't see the declaration of $i anywhere in that code.
The error suggests that the result is empty or the query is malformed. I can't be sure from the code I've seen.
A few other notes: it seems weird that you're using stripslashes() on data that's directly from the DB. Are you sure you're not escaping stuff twice when inserting content into the DB?
Always use loops instead of writing something out x times (like the 8 times you said in your question). Think of a situation where you have to change something about the function call (the name, the parameters, whatever). With loops you have to edit 1 place. Without, you need to edit 8 different places.
BTW, another solution to this problem would be using AJAX to load content into the last cell. If you're curious, I could show you how.
more edits:
For AJAX, build your message list as usual and leave the target td empty. Then, add a jQuery AJAX call:
$('MSG_LIST_ELEMENT').click(function() {
var msgId = $(this).attr('id').replace('msg','');
$.get(AJAX_URL+'?msgID='+msgId,function(data) {
$('TARGET_TD').html(data);
})
});
Replace the capitalized variables with the ones you need. As for the PHP, just echo out the contents of the message with the ID $_GET['msgID'].
However, make sure you authenticate the user before echoing out any messages, so that someone else can't read someone's messages by switching the id number. Not sure how authentication works on your site, but this can be done by using session variables.

Categories