I am fetching data from a MySQL table to display it on a page. The script is displaying the information, but in my table normal quotes we're inserted as another type of quote characters such as. ( ’ ) and ( “ ” ) which are automatically formatted this way when something is typed in Microsoft Word 2010, which was used to type most of the entries in the table. So my guess are those are special characters. But whenever i test out displaying a field with actual single quotes ( ' ) and ( " " ) i receive a mysql_fetch_row expects parameter 1 to be a resource, boolean given error. This is the code i use:
$result = mysql_query("SELECT `question` FROM {$db_table_alt}");
while($field = mysql_fetch_row($result)) {
foreach($field as $fields) {
//build a unique section ID based on the ID that the Question belongs to
$uid = mysql_query("SELECT `id` FROM `questions` WHERE `question` LIKE '%$fields%'");
while($uidfield = mysql_fetch_row($uid)) {
But whenever i use this line
$fields = mysql_real_escape_string(stripslashes($fields));
The field with real quotes will display, but with forward slashes before the quote.
Can somebody help me find a solution to this please?
If mysql_fetch_row() is complaining about a boolean that means mysql_query either returned no rows or the SQL had an error (mysql_error() will tell you which).
If you're getting backslashes before the quotes in your returned data, then they are getting put in the database. That sounds like magic_quotes are enabled. You really want to turn that off as it's an obsolete and broken solution to a problem.
Also, I think you're going to have to learn about character encodings. A default MySQL install will be not be UTF8, I'm afraid, it will probably be ISO-8859-15. Word used to like writing text in Windows-1252 which is not the same. And then it gets more complicated with whatever browser, website and other things that talk to the database use. I believe PhpMyAdmin tries to run in UTF8, so data will get converted into your tables if they're not UTF8. This will also affect your queries looking for the "smart quotes".
You seem to have two distinct problems here.
One where $result is evaluating to a boolean, which means there is an error in the query generated (SELECT question FROM {$db_table_alt}). Try echoing that query out and manually running it. It may be that the table/view named by {$db_table_alt} does not exist.
The second is a string escaping problem. I expect the quotes are escaped in the database - using mysql_real_escape_string on the query will not alter whether the returned results are escaped or not.
Also, if your data in the database is escaped by slashes, you should read up on magic quotes and what to do about them: PHP docs on magic quotes. You should not have to do any string escaping when pulling data out of the DB.
Related
I wrote a script to insert record in my DB. The only issue I am getting is when I try to store data which contains ' character then the script does not work and it does not store anything in the DB. For example John's Birthday , Amy's Home etc . Any solution to this problem which allows special character like ' to store in the DB and retrieving them without any harm to security?
mysqli_query($con,"INSERT INTO Story (desc)
VALUES ('$mytext')");
PHP's mysqli_real_escape_string is made specifically for this purpose. You problem is that quotes are being interpreted by MySQL as part of the query instead of values. You need to escape characters like this so they won't affect your query - this is what SQL injection is.
$mytext = mysqli_real_escape_string($con, $mytext);
// continue with your query
Manual: http://php.net/manual/en/mysqli.real-escape-string.php
Filter the variable part of the query through mysqli_real_escape_string.
I have some special characters stored in a MySQL database. Specifically ®. I want to SELECT all entries with these characters. I am currently using this statement:
mysql_query("SELECT * FROM table WHERE description LIKE '%®%' OR name
LIKE '%®%'");
It returns 0 entries. When i try something with %a% it returns a lot so I know everything is right, it is just some kind of a charset problem or something.
When I echo "®" it returns "å¨".
Also when I do the exact same query in phpmyadmin it works properly. Please help!
Read this its very help full to you
Just simply add those symbols to your text, and execute it as SQL query:
INSERT INTO tbl_name VALUES ("Here's my text: ©®");
When you want to display it one the website don't do anything with these symbols (but remember to escape at least <, >, & (using htmlspecialchars()) cause those has special meaning in XML/SGML (HTML) documents)
PS. Also remember to escape text passed to SQL query using mysql_real_escape_string() to avoid any SQL Injection problems. If your server has magic_quotes_gpc enabled disable it or at least filter your GET/POST/COOKIE data to its raw value. You should always consciously escape values.
EDIT:
According to your comment... I don't remember whether magic_quotes_gpc are enabled by default but you can easily undone magic quotes effect. Just on the very beginning of your PHP code add something like this:
if (get_magic_quotes_gpc()) {
array_walk_recursive($_GET, 'stripslashes');
array_walk_recursive($_POST, 'stripslashes');
array_walk_recursive($_COOKIE, 'stripslashes');
}
Now each GPC value should be always raw - without quotes - so you have to escape it manually before passing any variable into query.
Newbie here. The following function works fine when $color refers to an entry in the "style" field that is numberic e.g. "5000". But if the entry is "5000B" or letters entirely, it can't find it. Is this an indexing problem?
function get_shirt_colors_by_style($color)
{
db_connect();
$query = "SELECT style,sanmar_mainframe_color,unique_key,color_square_image
FROM sanmar_products WHERE style=$color
GROUP BY style ORDER BY style";
$result = mysql_query($query);
$data = mysql_fetch_array($result);
return $data;
}
It is failing to find alphanumeric comnbinations because the string is not quoted:
$query = "SELECT style,sanmar_mainframe_color,unique_key,color_square_image FROM sanmar_products WHERE style='$color' GROUP BY style ORDER BY style";
//-----------------------------------------------------------------------------------------------------------^^^^^^^^^
Numeric values need not be quoted in a MySQL query, but string values must always be surrounded in single quotes like '5000B'.
We assume the value of $color has already been escaped against SQL injection:
// Hopefully this happened already.
// If not, do it before running mysql_query()
$color = mysql_real_escape_string($color);
Is this an indexing problem?
No its a really bad coding problem.
Non-numeric values should be enclosed in quotes - actually literal values should always be enclosed in quotes when the underlying column type is numeric - otherwise you're likely to run into performance issues. You've also got a problem with managing errors in your code - if a query containing "WHERE style=5000B" is sent to the database it will always return an error - that you have no visibility of this error means that you've got a lot of important functionality missing from your site. Indeed, since content representations whould always be validated / changed at the point where the value leaves PHP, that also implies that your code is probably wide open to SQL injection attacks.
...and then there's the database design issues evident here: 'style' implies a non-unique identifier yet you are returning a single row from your query without any explicit ordering other than on the field you've selected on (i.e. even if it were unique, its very innefficient).
try using single quotes here:
WHERE style='$color'
I am currently building a query where both the field/column and value parts possibly consist of user inputted data.
The problem is escaping the fieldnames.
I'm using prepared statements in order to properly escape and quote the values but when escaping the fieldnames i run into trouble.
mysql_real_escape_string requires a mysql connection resource in order to us so that is ruled out
PDO::quote adds quotes around the fieldnames which renders them useless in a query too
addslashes works but isn't really safe
Anyone has an idea on what the best way is to properly insert the fieldnames into the query before passing it to PDO::prepare?
The ANSI standard way of doing a delimited identifier is:
SELECT "field1" ...
and if there's a " in the name, double it:
SELECT "some""thing" ...
Unfortunately this doesn't work in MySQL with the default settings, because MySQL prefers to think double quotes are an alternative to single quotes for string literals. In this case you have to use backticks (as outlined by Björn) and backslash-escaping.
To do backslash escaping correctly, you would need mysql_real_escape_string, because it's character-set-dependent. But the point is moot, because neither mysql_real_escape_string nor addslashes escape the backquote character. If you can be sure there will never be non-ASCII characters in the column names you can get away with just manually backslash-escaping the ` and \ characters.
Either way, this isn't compatible with other databases. You can tell MySQL to allow the ANSI syntax by setting the config option ANSI_QUOTES. Similarly, SQL Server also chokes on double quotes by default; it uses yet another syntax, namely square brackets. Again, you can configure it to support the ANSI syntax with the ‘quoted_identifier’ option.
Summary: if you only need MySQL compatibility:
a. use backquotes and disallow the backquote, backslash and nul character in names because escaping them is unreliable
If you need cross-DBMS compatibility, either:
b. use double quotes and require MySQL/SQL-Server users to change the configuration appropriately. Disallow double-quote characters in the name (as Oracle can't handle them even escaped). Or,
c. have a setting for MySQL vs SQL Server vs Others, and produce either the backquote, square bracket, or double-quote syntax depending on that. Disallow both double-quotes and backslash/backquote/nul.
This is something you'd hope the data access layer would have a function for, but PDO doesn't.
Summary of the summary: arbitrary column names are a problem, best avoided if you can help it.
Summary of the summary of the summary: gnnnnnnnnnnnh.
The correct answer, is str_replace("`", "``", $fieldname)
Wrong:
mysql> SELECT `col\"umn` FROM user;
ERROR 1054 (42S22): Unknown column 'col\"umn' in 'field list'
Right:
mysql> SELECT `kid``s` FROM user;
ERROR 1054 (42S22): Unknown column 'kid`s' in 'field list'
mysql> SELECT ```column``name``` FROM user;
ERROR 1054 (42S22): Unknown column '`column`name`' in 'field list'
(Note that in last example, the column name has 3 (three) extra back-ticks in it, just to show an extreme case)
This may affect performance, but it should be secure.
First run a DESCRIBE table query to get a list of allowed field names, then match these agaisnt the user submitted data.
If there's a match then you can use the user-submitted data without the need for any escaping.
If there's not match then it's a typo or a hack - either way it's an 'error' in the inputted data and the query should not be run.
The same could be done for 'dynamic' table names by running a SHOW TABLES query and matching from that result set.
In one of my applications I have an 'install' script; part of this queries the database and table field names and then writes a php file that is always referred back to so I'm not constantly running DESCRIBE queries agains the database, eg
$db_allowed_names['tableName1']['id'] = 1;
$db_allowed_names['tableName1']['field1'] = 1;
$db_allowed_names['tableName1']['field2'] = 1;
$db_allowed_names['tableName2']['id'] = 1;
$db_allowed_names['tableName2']['field1'] = 1;
$db_allowed_names['tableName2']['field2'] = 1;
$db_allowed_names['tableName2']['field3'] = 1;
if($db_allowed_names['tableName1'][$_POST['field']]) {
//ok
}
I use array keys like this as the if statement is a little faster than an in_array lookup
How about something like this?
function filter_identifier($str, $extra='') {
return preg_replace('/[^a-zA-Z0-9_'.$extra.']/', '', $str);
}
try {
$res = $db->query('SELECT '.filter_identifier($_GET['column'], '\*').' FROM '.filter_identifier($_GET['table']).' WHERE id = ?', $id);
} catch (PDOException $e) {
die('error querying database');
}
This is a simple white-list based character list. Any characters not in the list will get removed. Fortunately for me, I was able to make the database and tables, so I know there will never be any characters outside "a-zA-Z0-9_" (note: no space). You can add extra characters to the list via the $extra arg. If someone were to try and put "(SELECT * FROM users);--" in 'column', it would filter down to "SELECT*FROMusers", which would thrown an exception :)
I try to avoid doing extra queries if at all possible (I'm very performance sensitive). So things like doing a DESCRIBE beforehand or hard-coding an array of tables/columns to check against is something I'd rather not do.
Wierd design of a project, but for your problem: Surround your field names with ` and use addslashes for the name as well.
select `field1`, `field2` from table where `field3`=:value
I am building a blog site and am having trouble with updating fields in my MYSQL database. Whenever I hit the update button on the form that uses PHP, it adds extra space before the text string in the MYSQL text field. Here is the PHP code:
//UPDATE TEXT
$updated_text = $_POST['text'.$the_post['ID'][$n]];
if ($updated_text != "") {
$sql = "UPDATE posts SET TEXT = '".addslashes($updated_text)."' WHERE ID = '".$the_post['ID'][$n]."'";
$text_result = mysql_query($sql) or die(mysql_error());
}
Thanks
Not sure why you have this problem, but you could first try using trim to remove white-characters at the beginning and end of your string :
$updated_text = trim($_POST['text'.$the_post['ID'][$n]]);
If this solves the problem, it's because you are receiving those whitespaces from the form -- else... Well, strange ^^
A couple of other notes :
When escaping data to send it to your DB server, yOu should use the functions that are specific to your DB. Here, you are working with a MySQL database, and the mysql_* function, which means you should use mysql_real_escape_string instead of addslashes.
You are escaping the data you're putting in the TEXT ; but, to avoid SQL injections, you should protect the data use in the where clause too.
If your ID is a char/varchar in DB, it means using mysql_real_escape_string on $the_post['ID'][$n] too
If your ID is an integer in database :
the quotes arround the value are not necessary : quotes, in SQL, are the string-delimiter ; there is no need for any delimiter for integers
you should make sure you are sending an integer to the DB ; for instance, using intval($the_post['ID'][$n])
This will not change anything about your problem -- but taking care of security is always best ;-)
Perhaps its an issue of the text-area tag of your html - for example if its indented or so..
I found that the empty mySQL field was inserting " " into my html form value, so I used:
$variable = trim($variable," ");
to trim the unwanted space.
If you have a space or line break (in your code editor) in between and then remove them. I had the same issue earlier, but is now fixed.