In my page I have this code with echo's.
<?php
include("../config.php");
$q = mysql_query("SELECT propertyaddress FROM propertydetail WHERE active='yes' and leasedatefrom='".date("m-d-Y", strtotime('+1 months'))."'");
$res = mysql_fetch_array($q);
echo "<br/>pdetail=".$pdetail=trim($res['propertyaddress']);
echo $query="SELECT * FROM tenantmaster WHERE propertyaddress like '".$pdetail."'";
//echo $query="SELECT * FROM tenantmaster ";
//echo $query="SELECT * FROM tenantmaster WHERE propertyaddress = '1934 Heron Ave Unit D Schaumburg IL 60193'";
$resultdb = mysql_query($query);
if (!$resultdb) {
die('Invalid query: ' . mysql_error());
}
else{
echo "<br/>right query";
}
echo "<br/>num of row===".mysql_num_rows($resultdb);
$rowt = mysql_fetch_array($resultdb);
echo "<br/>row===".$rowt['name'];
exit;
?>
config.php
<?php
$mysql_hostname = "localhost";
$mysql_user = "root";
$mysql_password = "";
$mysql_database = "gms_estate";
/*
$mysql_hostname = "localhost";
$mysql_user = "root";
$mysql_password = "";
$mysql_database = "gms_estate";
*/
$bd = mysql_connect($mysql_hostname, $mysql_user, $mysql_password)
or die("Opps some thing went wrong");
mysql_select_db($mysql_database, $bd) or die("Opps some thing went wrong");
?>
And problem is my first query $q is working but query $query is also working but mysql_num_rows($resultdb) is not working and display 0 rows but, when I run echo query to database it's displaying 1 row. Why?
I tried $res['propertyaddress'] variable with trim() but not any success.
But when I use 1934 Heron Ave Unit D Schaumburg IL 60193 (that's my variable value) instead of $res['propertyaddress'] then it's working.
So, when I give value of variable directly then it's working but when I give variable then not. Why?
A common problem with comparing text entry from multi-line fields is that you probably have a "newline" or "tab" in the results from the first query, but that is not in the second query. (Other gotchas are "non-breaking space").
As you are echoing in HTML you won't see those in the output (so copying and pasting works), but they will be used in the query (so direct input fails). Try "View Source" (which shows newlines) or run in command line as that might give you more clues.
For now, strip out anything other than alpha numeric and spaces using preg_replace
$pdetail = trim( preg_replace("/[^0-9a-zA-Z ]/", "", $res['propertyaddress']) );
Eventually you'll want to adjust that to cover all your use cases, or of you find it's a "newline" just remove those - but you need to find what's different.
And, as per comments: check out mysqli / PDO parameterized queries. If the original address contained a single quote mark, that would also fail (with unknown results). It's a pain first off, but it'll save you a lot later on, makes your code easier to read and also will get more help here on SO (as your code is easier to read).
http://php.net/manual/en/pdo.prepared-statements.php
<?php
include("../config.php");
$connect = new PDO("mysql:host=$mysql_hostname;dbname=$mysql_database", $mysql_user, $mysql_password);
$q = "SELECT propertyaddress FROM propertydetail WHERE active='yes' and leasedatefrom='".date("m-d-Y", strtotime('+1 months'))."'";
$result = $connect->prepare($q);
$status = $result->execute();
$res = $result->fetch(PDO::FETCH_ASSOC);
$pdetail = $res["propertyaddress"];
$q = "SELECT * FROM tenantmaster WHERE propertyaddress = ".$connect->quote($pdetail);
/* or
$q = "SELECT * FROM tenantmaster WHERE propertyaddress like ".$connect->quote($pdetail);
*/
$result = $connect->prepare($q);
$status = $result->execute();
echo "<br/>num of row===".$result->rowCount();
if (($status) && ($result->rowCount() > 0))
{
$res = $result->fetch(PDO::FETCH_ASSOC);
echo "<br/>row===".$res['name'];
}
$connect = null;
?>
First of all it is recommended to use the mysqli along with prepared statement since it will avoid the SQL Injections that will occur. Now your code is purely injectable and it can be rectified with the help of mysqli along with prepared statements or with the help of PDO.
Mysqli with Prepared Statement: http://php.net/manual/en/mysqli.prepare.php
PDO: http://php.net/manual/en/book.pdo.php
PDO with Prepared: http://php.net/manual/en/pdo.prepare.php
Explanations
As per the usage of trim() in your variable you will be getting the strategy as per this alone.
trim- Strip whitespace (or other characters) from the beginning and end of a string
Description: This function returns a string with whitespace stripped from the beginning and end of str. Without the second parameter, trim() will strip these characters:
" " (ASCII 32 (0x20)), an ordinary space.
"\t" (ASCII 9 (0x09)), a tab.
"\n" (ASCII 10 (0x0A)), a new line (line feed).
"\r" (ASCII 13 (0x0D)), a carriage return.
"\0" (ASCII 0 (0x00)), the NUL-byte.
"\x0B" (ASCII 11 (0x0B)), a vertical tab.
Note:
But trim() does not remove the white space which is present at the middle of the string that is given.
Example:
trim() trims characters from the beginning and end of a string, it may be confusing when characters are (or are not) removed from the middle. trim('abc', 'bad') removes both 'a' and 'b' because it trims 'a' thus moving 'b' to the beginning to also be trimmed. So, this is why it "works" whereas trim('abc', 'b') seemingly does not.
Scenario: Hence in order to remove all teh white space that is present in the string you have to use the following.
You have to first remove all the character other that alpha numeric and white spaces with the help of preg_replace() function.
After replacing all the above mentioned items you have to then trim upon the variable so that it will remove all the white spaces that has been present and hence your string will look as the string which you give in hard code or directly.
3. You can directly adopt the method by strong the trimmed value into a variable and then echo it.
preg_match - Perform a regular expression match
Description: Searches subject for a match to the regular expression given in pattern.
Return Values: preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
Solution to your Problem
But when I use 1934 Heron Ave Unit D Schaumburg IL 60193 (that's my variable value) instead of $res['propertyaddress'] then it's working.
Reason: This Error occurs when you printing the values directly from the Database.
If you have used any editor it will store the content directly to the DB as HTML tags alone.
Hence in order remove the HTML tags you have first store the DB value into a variable by replacing all the values and then you have to display it.
If you echo it directly you will not be seeing the HTML tags but if you view it by using CTRL+U you will be seeing it in the seeing it and it is not recommended. Hence you have to remove or strip of the parameters and then trim it.
Query:
preg_replace("/(\W)+/", "", $word_to_undergo);
Note: \W - Anything that isn't a letter, number or underscore.
So, in terms of Unicode character classes, \W is equivalent to every character that are not in the L or N character classes and that aren't the underscore character.
Alternative Solution:
To remove just put a plain space into your character class:
Query:
$needed_text = preg_replace("/[^A-Za-z0-9 ]/", "", $word_to_undergo);
Along with the above Solution you have to preform the trim so that it produces a perfect string as per your choice and it will match up with the query and produce the result.
As per Suggestion One: It should be
$final_value = preg_replace("/(\W)+/", "", $word_to_undergo);
$final_value = preg_replace("/(\W)+/", "", $res['propertyaddress']);
As per Suggestion Two: It should be
$final_value = preg_replace("/[^A-Za-z0-9 ]/", "", $word_to_undergo);
$final_value = preg_replace("/[^A-Za-z0-9 ]/", "", $res['propertyaddress']);
Addition to the above solution you can try using like this to.
<?php
$display=trim($res['propertyaddress']);
echo $display;
?>
Instead
echo "<br/>pdetail=".$pdetail=trim($res['propertyaddress']);
Use
$pdetail=trim($res['propertyaddress']);
echo "<br/><pre>pdetail='".$pdetail."'</pre>";
And you will can see real variable value
Change your query from
echo $query="SELECT * FROM tenantmaster WHERE propertyaddress like '".$pdetail."'";
To
echo $query="SELECT * FROM tenantmaster WHERE propertyaddress like '%".$pdetail."'%";
Please try with this query. It will be helpful for getting your result
$query='SELECT * FROM tenantmaster WHERE propertyaddress like "'.$pdetail.'";
You are missing mysql_free_result($q); and mysql_free_result($query) to announce that you are finished with the query.
And do change to mysqli (or PDO).
Related
I am doing a fulltext search in PHP in BOOLEAN mode, which is working 95% of the time. However when I enter a special character like ", the query fails.
The table in question holds around 6,000 records, with a large quantity being commercial grade fasteners.
Example Data:
7/16" UNF x 2 1/4" Hex
Before the query is performed, the input is cleaned using the following function
function clean($db, $str) {
$str = #trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
$str = htmlspecialchars($str, ENT_NOQUOTES);
$str = preg_replace("/[[:blank:]]+/"," ",$str);
return mysqli_real_escape_string($db, $str);
}
When searching for 7/16" and nothing else, I should get a few hundred results but I'm getting nothing and I believe it's to do with how the input is being escaped incorrectly.
Once the input is cleaned I add + to the beginning of each word to ensure it is included in the results. This is done using the following:
$symbol = '+';
$string = $symbol . str_replace(' ', " $symbol", $term);
Example Query:
SELECT * FROM products WHERE MATCH (code, desc) AGAINST ('+7\/16\\\"' IN BOOLEAN MODE) ORDER BY desc ASC
As you can see the original input of 7/16" has been changed to +7/16\\". Here is where I suspect the problem lies.
I'm really not sure what part of the clean function is causing this, I thought by adding ENT_NOQUOTES to htmlspecialchars would have resolved it but it hasn't.
I have searched for similar questions and have found this
but it has not helped for my situation. On my site, a user inputs an answer. The string is sent via an ajax call to a php file. The string may or may not contain special characters, so I use
encodeURIComponent()
before the string is sent to the php file.
The user-inputted string is compared in the php file with a string that represents the "correct answer", and if the strings are found to be equivalent strings after processing, the user-inputted answer is "correct". I have not had a problem with any strings lately until today. Until today, strings with letters, special characters (parentheses, minus sign, plus sign) and numbers have worked fine using the following processing in php:
<?php include 'connect.php';
$UserInput = trim($_GET['userinput']);
$QID = mysqli_real_escape_string($cxn, $_GET['qid']);
$sqlIQ = mysqli_fetch_assoc(mysqli_query($cxn, "SELECT answer FROM IndexQuestions WHERE sampqid = $QID"));
$StrReplaceArray = array("<i>", "</i>", "</sup>", " ");
$CorrectAnswer1 = str_replace($StrReplaceArray, "", $sqlIQ['answer']);
$CorrectAnswer2 = str_replace("<sup>", "^", $CorrectAnswer1);
$UserAnswer1 = str_replace(" ", "", $UserInput);
$UserAnswer2 = str_replace("+-", "-", $UserAnswer1);
if (strcasecmp($UserAnswer2, $CorrectAnswer2) == 0) {
$CorrectOrNot = 'Correct';
} else {
$CorrectOrNot = 'Incorrect';
}
However, the latest string is not working. The user-inputted string is -2 ± √3 which is sent to the php file as -2 ± √3 (with or without the whitespace). The "correct answer" saved in another table is -2 ± √3. I have echoed the following:
echo $UserAnswer2 . " " . $CorrectAnswer2; //after str_replace processing shown above
and the html output for each variable looks identical to me. I have also tried the following for comparative purposes (instead of strcasecmp):
if ($UserAnswer2 == htmlentities($CorrectAnswer2)) { //etc.
but still the same.
When I check a separate table (which stores the user's answer), the answer is stored the way I want it to be:
$unixtime = time();
$AnswerID = substr(md5(rand(0, 1000000)), 0, 10).$unixtime;
$sqlIQStats = mysqli_query($cxn, "INSERT INTO IQStats (answer_id, useranswer) VALUES ('$AnswerID', '".htmlentities($UserAnswer2)."')");
and appears in the database as -2 ± √3.
The html charset the site uses is charset=utf-8.
var_dump gives the following (with no spaces for user answer): $UserInput and $UserAnswer2 both give string(8) "-2±√3" whereas $CorrectAnswer2 gives string(18) "-2±√3"
Does anyone have any ideas as to why the strings, after string-processing and comparison in the php file, are found to be inequivalent strings?
OK...solved it by changing $UserInput to:
$UserInput = htmlentities(trim($_GET['userinput']));
I am trying to handle text which may contains single quotes and other special char. If it is enclised with single quote, it does not proceed. So I am trying to enclose single quoted string into double quoted string.
I already checked previous threads.
Here is the code:
Check result : http://ideone.com/gWFdUb
<?php
function clean($string) {
eval('$string = "'.$string.'";');
$string = str_replace(' ', ' ', $string); // Replaces all spaces with hyphens.
return preg_replace('/[^A-Za-z0-9 #\-]/', '', $string); // Removes special chars.
}
$d = clean('this was readlly n'ice 'test for#me to') ;
echo $d;
What wrong with eval line?
I am processing user tweets, post for two purpose.
To store into mysql table. (mysqli_real_escape) did not help
To process the each string into text for matching and POS(part of speech) tagging.
I get stuck due to such characters in text. So trying to remove it before I start processing.
UPDATE:
Check this, here I am already using mysqli_real_escape_String even the script stops when it reach this
...
mention-179
May Thanks #ShaleMarkets #01Finser #52York #AB_CutRock #AFSPG #AJSmith222 #AlbertaEnergy #andymartin #annemullettamg #APGQ_officiel-440929408564477952-Tue Mar 04 19:18:57 +0000 2014-19:03:572014:03:04201403Adnan Aftab Nizamani0131
mention-180
Thank you for #ShaleMarkets, to promoting, thank you very much for an award. Glad to have been able to help you :)-440897048963850240-Tue Mar 04 17:10:22 +0000 2014-17:03:222014:03:04201403♘-₭ℜi℘-0582
mention-181
#ShaleMarkets https://t.co/aM8liykQqR-440890009273393152-Tue Mar 04 16:42:24 +0000 2014-16:03:242014:03:04201403Bre Burey018
What's wrong in mention-181 so that it got stuck? Here is the code
foreach ($tweets1 as $item)
{
$count = $count + 1;
$text = $item->text;
//echo $userid.$text;
$text_id = $item->id;
$constant = 'mention';
$time = $item->created_at;
//echo $time;
//$dt = new DateTime('#' . strtotime($time));
$dt = \DateTime::createFromFormat('D M d H:i:s e Y', $time);
//var_dump($dt);
$tweet_time = $dt->format('H:m:s');
$tweet_dtm = $dt->format('Y:m:d');
$year = $dt->format('Y');
$month = $dt->format('m');
$user_name = $item->user->name;
// echo $year.$month.$user_name;
$inreplyto = $item->in_reply_to_screen_name;
$rt_count = $item->retweet_count;
$follower_count = $item->user->followers_count;
echo $constant."-".$count."<br>".$text."-".$text_id."-".$time."-".$tweet_time.$tweet_dtm.$year.$month.$user_name.$rt_count.$follower_count."<br>";
echo "<br>";
$con = mysqli_connect('127.0.0.1', 'root', 'root', 'root');
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
return;
}
$text = mysqli_real_escape_string($con,$text);
$insertQuery1 = "INSERT INTO twitter_mention(`username`,`userid`,`tweet_text`,`text_id`,`time`,`month`,`year`,`date`,`user_follower_count`,`rt_count`,`constant`,`in_reply_to`) VALUES ('".$twitteruser."','".$userid."','".$text."','".$text_id."','".$tweet_time."','".$month."','".$year."','".$tweet_dtm."','".$follower_count."','".$rt_count."','".$constant."','".$inreplyto."')";
if (!mysqli_query($con,$insertQuery1))
{
// die('Error: ' . mysqli_error($con));
// echo "error";
}
Always use contextual escaping
You can't generically "clean" data without any context of what it's for. Do not try to build a single function to handle all the possible cases. Just don't. It's pointless. In your function, you're trying to "clean" the string by removing certain characters. You can't clean a string by removing a set of characters. That idea is flawed because you're always going to have to allow the use of some characters that are special in some syntax or the other.
Instead, treat the string according to the context where it's going to be used. For example:
If you are going to use this string in an SQL query, you have to use prepared statements (or mysqli_real_escape_string()) to properly escape the data.
If you're going to output this value in HTML markup, you need to use htmlspecialchars() to escape the data.
If you're going to use it as command-line argument, you need to use escapeshellcmd() or escapeshellarg().
Further reading:
Security.SE — What's the best way to sanitize user input in PHP?
What's the best method for sanitizing user input with PHP?
Does eliminating dangerous characters avoid SQL-injection?
In this answer, I'll try to address your original question:
What wrong with eval line?
Nothing. The second-to-last line is the only line that contains a syntax error. You aren't escaping the single-quotes correctly. Try the following:
$d = clean('this was readlly n\'ice \'test for#me to');
It should now produce this output:
this was readlly nice test for#me to
I'm not sure if this is the expected result. If you update the question to include what exactly you're trying to achieve and why do you care which type of quotes the string was wrapped in, maybe I can help you find a solution.
Try this one-
<?php
function clean($string) {
eval("\$string = \"$string\";");
$string = str_replace(' ', ' ', $string); // Replaces all spaces with hyphens.
return preg_replace('/[^a-zA-Z0-9_ %\[\]\.\(\)%&-]/s', '', $string); // Removes special chars.
}
$d = clean("this was readlly n'ice 'test for#me to") ;
echo $d;
?>
The output is- this was readlly nice test forme to
I have text that consist of some sentences. I have to parse the sentences that separated by dot and count words in every sentence. The sentences that contain more than 5 words will be inserted into database. here's my code :
<?php
require_once 'conf/conf.php';// connect to database
function saveContent ($text) {
//I have to get every sentence without lose the dot
$text1 = str_replace('.', ".dot", $text);
$text2 = explode ('dot',$text1);
//Text that contain ' cannot be inserted to database, so i need to remove it
$text3 = str_replace("'", "", $text2);
//Selecting the sentence that only consist of more than words
for ($i=0;$i<count($text3);$i++){
if(count(explode(" ", $text3[$i]))>5){
$save = $text3[$i];
$q0 = mysql_query("INSERT INTO tbdocument VALUES('','$files','".$save."','','','') ");
}
}
}
$text= "I have some text files in my folder. I get them from extraction process of pdf journals files into txt files. here's my code";
$a = saveContent($text);
?>
The result is only 1 sentence (the first sentence) that can be inserted in database.
I need your help, thank you so much : )
There are many ways to improve this (and to make it work correctly).
Rather than replace . with .dot, you can simply explode on the . and remember to replace it later. However, what if your sentence is something like Mr. Smith went to Washington.? You can't differentiate those periods with much reliability.
The variable $files in your INSERT is not defined in scope of this function. We don't know where it comes from or what you expect it to contain, but here, it will be NULL.
function saveContent ($text) {
// Just explode on the . and replace it later...
$sentences = explode(".", $text);
// Don't remove single quotes. They'll be properly escaped later...
// Rather than an incremental loop, use a proper foreach loop:
foreach ($sentences as $sentence) {
// Using preg_split() instead of explode() in case there are multiple spaces in sequence
if (count(preg_split('/\s+/', $sentence)) > 5) {
// Escape and insert
// And add the . back onto it
$save = mysql_real_escape_string($sentence) . ".";
// $files is not defined in scope of this function!
$q = mysql_query("INSERT INTO tbdocument VALUES('', '$files', '$sentence', '', '', '')");
// Don't forget to check for errors.
if (!$q) {
echo mysql_error();
}
}
}
}
In the long run, consider moving away from the mysql_*() functions and begin learning an API which supports prepared statements such as PDO or MySQLi. The old mysql_*() functions are soon to be deprecated and lack the security offered by prepared statements.
A problem I recently ran into was that when trying to update a field in my database using this code would not work. I traced it back to having a % sign in the text being updated ($note, then $note_escaped)... Inserting it with sprintf worked fine though.
Should I not be using sprintf for updates, or should it be formed differently?
I did some searching but couldn't come up with anything.
$id = mysql_real_escape_string($id);
$note_escaped = mysql_real_escape_string($note);
$editedby = mysql_real_escape_string($author);
$editdate = mysql_real_escape_string($date);
//insert info from form into database
$query= sprintf("UPDATE notes_$suffix SET note='$note_escaped', editedby='$editedby', editdate='$editdate' WHERE id='$id' LIMIT 1");
You are using sprintf totally wrong. Removing the function call in your code would still do the same thing. It should be:
sprintf("UPDATE notes_%s SET note='%s', editedby='%s', editdate='%s' WHERE id=%d LIMIT 1", $suffix, $note_escaped, $editedby, $editdate, $id);
You should read the manual.
first of all you should be using prepared statements instead of a sprintf-call
but if you absolutely have to do it this way you have to use:
$id = mysql_real_escape_string($id);
$note_escaped = mysql_real_escape_string($note);
$editedby = mysql_real_escape_string($author);
$editdate = mysql_real_escape_string($date);
//insert info from form into database
$query= sprintf("
UPDATE notes_%s /* this is still open for injection, and cannot be properly escaped with mysql_real_escape_string */
SET note='%s',
editedby='%s',
editdate='%s'
WHERE id='%d'
LIMIT 1",
$suffix,
$note_escaped, $editedby, $editdate, $id);
You can escape the % in the source text by replacing it with \% in mysql.
sprintf() is not used much in PHP, unless you need to format data somehow. These two statements work identically in PHP:
$num = 42;
$char = 'q';
$text = sprintf('The number is %d and the character is %s', $num, $char);
$text = "The number is $num and the character is $char";
sprintf's used more in C for "printing" variable data into a string. But PHP can already do that with double-quoted strings, so unless you need to use sprintf's special formatting functions (e.g. %0.2f for a 2-decimal-place float), it's easier to use the regular string method.
From http://php.net/manual/en/function.mysql-real-escape-string.php:
Note: mysql_real_escape_string() does not escape % and _. These are wildcards in MySQL if combined with LIKE, GRANT, or REVOKE.
You need to manually escape the % and _ if any with \% and _. I don't recommend using sprintf, but just improving your escape function.