Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
179 views
in Technique[技术] by (71.8m points)

In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?

I am working on a form with the possiblity for the user to use illegal/special characters in the string that is to be submitted to the database. I want to escape/negate these characters in the string and have been using htmlspecialchars(). However, is there is a better/faster method?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are no "illegal" characters for the database. Database that cannot store some characters is a nonsense. There are some service characters, like quotes, used to delimit strings. These characters should be just escaped, not eliminated.

To send a query to the database, you have 2 options:

  1. Build a query usual way, to make it look exactly as SQL query you can run in sql console.
    To do it, one should understand a whole set of rules, not just "use mysql_real_escape_string".
    Rules such as:

    • Strings should be both enclosed in quotes and escaped. That's the only meaning of escaping: It's just escape delimiters! (and some other characters - string termination char and escape character itself). Without surrounding quotes mysql_real_escape_string is just useless.
    • Numbers should be cast to it's type explicitly. Though while data numbers can be threaten just like strings, there are some numbers, like LIMIT clause parameters, which cannot be escaped and can be only cast.
  2. To send query and data separately.
    This is most preferred way as it can be shortened to just "use binding". All strings, numbers and LIMIT parameters can be bound - no worry at all.
    Using this method, your query with placeholders being sent to database as is, and bound data being sent in separate packets, so, it cannot interfere. It is just like code and data separation. You send your program (query itself) separated from the data.

But!

Everything said above covers only data part of the query.
But sometimes we have to make our query even more dynamic, adding operators or identifiers.
In this case every dynamic parameter should be hardcoded in our script and chosen from that set.
For example, to do dynamic ordering:

$orders  = array("name","price","qty"); //field names
$key     = array_search($_GET['sort'],$orders)); // see if we have such a name
$orderby = $orders[$key]; //if not, first one will be set automatically. smart enuf :)
$query   = "SELECT * FROM `table` ORDER BY $orderby"; //value is safe

or dynamic search:

$w     = array();
$where = '';

if (!empty($_GET['rooms']))     $w[]="rooms='".mesc($_GET['rooms'])."'";
if (!empty($_GET['space']))     $w[]="space='".mesc($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mesc($_GET['max_price'])."'";

if (count($w)) $where="WHERE ".implode(' AND ',$w);
$query="select * from table $where";

In this example we're adding to the query only data entered by user, not field names, which are all hardcoded in the script. For the binding the algorithm would be very similar.

And so on.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...