How to enable auto mysql real escape to all queries? - php

I'm running php 5.2.13 and i have an app that contains tons of files but they all calling one file at the beginning, i want to put some line in that file to automatically mysql real escape any query, because i don't want to go across every file and change code.
Thanks!

I don't know how well that would work. What you really need is to escape the input not things like table names, fields, etc. If you pass the entire query to an escape, I'd be willing to bet you'd find a good number of queries that will fail because it will turn things like
select * from tablename where name = 'foo'
into
select * from tablename where name = \'foo\'
Which would choke.
And, having a wrapper function in your code helps a lot (assuming you don't want to use a framework, etc). If you have "mysql_query()" littered around your code, you probably are in for a bit of work to change it up. If you can't/don't-want-to adopt a framework, at least wrap it in a function of your own, like "db_query()" like this:
function db_query($query,$and,$other,$arguments)
{
mysql_query( ... ); // you can change this to some other database later if you want
}
I did that in a project a few years ago and it helped a ton when I wanted to log some errors. I just added it to that function instead of having it in 200 places in the code.
But even that won't really help if you didn't escape input properly in the first place. In that case your only option is to take some time and fix it.

Hans has some good suggestions. But i think the bottom line is youre going to have to modify a lot of code. There is no magic bullet on this one. Whoever wrote it should have known better, and now you my friend are going to pay the price. Personally if youre going to have to go in and manually edit i would urge you to switch to PDO or mysqli. That way you can make use of prepared statements which will handle the escaping of variables for you provided you use them correctly.

If you have a large project, and need to change the data access, I would suggest to move to an ORM, my personal pick is Propel.
With that you would solve the whole escaping sql's problem, would make your app more scalable and you could also reverse your database diagram in order to generate the classes needed for Propel.
Propel will give you benefits like transactions, parameters and many more, so you should reaally think about it.
Best regards

Take note that it's not queries that you will want to escape, it's user supplied variables that are to be included in the query (unless you're writing malformed SQL yourself on purpose). So what you can do is to run mysql_real_escape_string() on, say, the $_POST array with array_map(), provided that you are not going to use that array for anything else.
mysql_real_escape_string() is still only the second best solution to the issue anyway. I you can use prepared statements (AKA parametrized queries) and you're home free.

Related

PHP+Mysql : update not work if use '&' contain WHERE

This code not work :
UPDATE `test` SET `done`='1' WHERE `name`='x_&_y'
But this is work :
UPDATE `test` SET `done`='1' WHERE `name`='x_y'
Both of code return 1 value but first code not work and table not updated !
PHP code :
$value = 'x_&_y'; // send by $_GET['value']
$value = htmlspecialchars(trim($value),ENT_QUOTES,'UTF-8');
UPDATE `league` SET `leagueUpdateDone`='1' WHERE `leagueCountry`='$value';
The problem is you're running your query wrong. Never, ever use htmlspecialchars on input if you're trying to match things. & is a reserved character in HTML, it will be mangled.
Your final query looks like:
'x_&_y'
Instead use prepared statements with placeholder values, like this:
$stmt = $db->prepare('UPDATE `league` SET `leagueUpdateDone`='1' WHERE `leagueCountry`=?');
Then bind values against that. The procedure varies in implementation based on your use of mysqli or PDO.
Note: htmlspecialchars is only used for displaying HTML. Keep the content in your database as neutral as possible, never pre-escaped. You want to treat everything in your database as raw, escaping it for the context it's used in, be that JSON, HTML, email or otherwise, on a case-by-case basis. If you presume it's HTML that can make life very ugly if you need to undo that and re-do it for JSON, for example.
I don't know where you learned that htmlspecialchars technique, but it's highly probable this is cargo cult programming where incantations are used without their purpose being fully understood. This is a common problem with a lot of YouTube tutorial-type training where they drown you in code but offer very little in the way of theoretical foundation or practical explanations.
I'm trying not to be too hard on you here, you're just trying to learn, but it's important to understand the code you're using instead of just using it because someone told you to. Try to dig a little deeper, look up the documentation on the methods you're using. PHP has a fantastic manual with a comments section full of people helping to clarify any misunderstandings.

Common words used over thousands of row in MySQL Database using PHP (or query)

I have a MySQL database that has large amount of records. For each record there is a field of text called "Comment" and I've put 3 examples below:
"Very fast payment, thank you. "
"love the thank you"
"Fast delivery thank u "
My question is this:
How do I interrogate each record look at the contents of the "Comment" field and then work out what the top 20 words used are?
For example using the 3 comments above the words
"thank" appears 3 times,
"Fast" 2 times
And the rest of the words used are only used once.
I am guessing that I'll need to use PHP to work through each record, explode out using a " " (space), remove characters like commas & full stops, then store the results and then count those.
But I am really not sure on the best approach and not sure how to handle plurals such as "thanks" & "thank". Hence the question :)
Matt
Because they are all in the one column you can't really do much SQL filtering here.
If the data set isn't too huge (i.e. php running out of memory huge) then you should be able to read it into php and process it.
You can use explode to split on spaces and work with the data as a huge array. And you can use preg_match function to do string compare operations, see: http://us3.php.net/preg_match - you should spend some time investigating regular expressions.
It would be easier to use the SQL like function in the where clause if you were looking for something specific like SELECT COUNT(comment) where comment like '%thank%'` but you would have to do that manually.
Also, you may want to consider dumping it out to a file and using unix-based commands like wc which can help you with what you are after. You can also use PHP to interact with these commands if you are in a unix-like environment.
Short of writing the code there isn't much more I can tell you.
Possible, perhaps. However, MySQL is not really good for this type of querying. If you did attempt this using MySQL is is likely to take a long time to actually complete and would not be practical if you wanted to run this type of query frequently.
I'd suggest you look into indexing your data using something that is specifically designed for these kind of queries. Some kind of Apache Lucene derivative would do nicely, for example you could use Elasticsearch. Here are the docs from ES that describe the kind of query you are looking to run: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-terms-facet.html
Unlike MySQL running these kind of queries on something like ES would execute very quickly as it is specifically designed for it.

What's the best way to compare variable string equality in PHP/MySQL?

I'm trying to check a string passed through the URL and get back all results from a MySQL database where that string is a match.
I send different queries based on the input, but the one in question looks basically like this (it's really much longer):
if ($projectsname) {$result = mysql_query("SELECT item FROM items WHERE projectname=$projectsname",$db)}
The issue is that $projectsname is a string. All my other queries return an integer and work fine. But in this case I can't get it to give me a proper result in the actual PHP code unless I put it in quotes, and here's how I did that:
$projectsname = (isset($_GET['projectname']) && !empty($_GET['projectname'])) ? '"'. $_GET['projectname'] .'"' : 0;
...by appending the quotes to the data that creates the variable. And that works. It just seems wrong to me.
Is there a better way of making this comparison?
(I wish I could say this was a newbie question, but it's something I've often had trouble with in my years as a designer who tries to code.)
Feel free to edit the question if you know better terminology than I have used here (and let me know what your edits were--I'm having a hard time phrasing the question.).
if ($projectsname) {$result = mysql_query("SELECT item FROM items WHERE projectname='$projectsname'",$db)}
You need to quote strings that you pass to mysql.
Run
echo "SELECT item FROM items WHERE projectname=$projectsname";
to see what query you're actually sending.
Also read up about mysql_real_escape_string and about SQL injections in general. Consider the following example of a very typical SQL injection your code is prone to:
$projectsname = "123 OR 1=1";
echo "DELETE FROM items WHERE projectname=$projectsname";
Using pure PHP for complete application projects is highly discouraged. It puts the coder in the position of worrying about elementary problems such as escaping queries, validating form data, security, templating, loading libraries, etc., etc. Instead of worrying about the program logic the coder puts too much time worrying about the syntax. Only newbies do that. We don't because time is money for us.
My recommendation: use framework. I personally recommend Codeigniter or Zend. Believe me it'll save you a lot of headache.

Parsing timestamps - do it in MySQL or in PHP?

Let's say you've got a table with a timestamp column, and you want to parse that column into two arrays - $date and $time.
Do you, personally:
a) query like this DATE(timestamp), TIME(timestamp) , or perhaps even going as far as HOUR(timestamp), MINUTE(timestamp
b) grab the timestamp column and parse it out as needed with a loop in PHP
I feel like (a) is easier... but I know that I don't know anything. And it feels a little naughty to make my query hit the same column 2 or 3 times for output...
Is there a best-practice for this?
(a) is probably fine, if it is easier for your code base. I am a big fan of not having to write extra code that is not needed and I love only optimizing when necessary. To me pulling the whole date and then parsing seems like premature optimization.
Always remember that sql servers have a whole lot of smarts in them for optimizing queries so you don't have to.
So go with a), if you find it is dog slow or cause problems, then go to b). I suspect that a) will do all you want and you will never think about it again.
I would personally do (b). You're going to be looping the rows anyway, and PHP's strtotime() and date() functions are so flexible that they will handle most of the date/time formatting issues you run into.
I tend to try to keep my database result sets as small as possible, just so I don't have to deal with lots of array indexes after a database fetch. I'd much rather take a single timestamp out of a result row and turn it into several values in PHP than have to deal with multiple representations of the same data in a result row, or edit my SQL queries to get specific formatting.
b) is what I follow and I use it every time. It also gives you the flexibility of being able to control how you want it to appear in your front end. Think about this: If you are following a) and you want to do a change, you will need to change all the queries manually. But if you are using b) you can just call a function on this value (from the DB) and you are good to go. If you ever need to change anything, just change it within this function and viola! Doesn't that sound like a time saver to you ???
Hope that helps.
I would also use b). I think it is important that, if I at some point need to use names on the days, or the months in another language. I can use PHP locale support to translate it to the given language, that wouldn't be the case in a).
If you need it in the SQL query itself (e.g. in a WHERE, GROUP BY, ORDER BY, etc), then way a) is preferred. If you rather need it in the code logic (PHP or whatever), then way b) is preferred.
If your PHP code actually does a task which can be as good done with SQL, then I'd go for that as well. In other words, way b) is only preferred if you are going to format the date for pure display purposes only.
I think it boils down to this, do you feel more at home writing php code or mysql queries?
I think this is more a question of coding style than technical feasibility, and you get to choose your style.

Functions in MySQL or PHP

Is it generally better to run functions on the webserver, or in the database?
Example:
INSERT INTO example (hash) VALUE (MD5('hello'))
or
INSERT INTO example (hash) VALUE ('5d41402abc4b2a76b9719d911017c592')
Ok so that's a really trivial example, but for scalability when a site grows to multiple websites or database servers, where is it best to "do the work"?
I try to think of the database as the place to persist stuff only, and put all abstraction code elsewhere. Database expressions are complex enough already without adding functions to them.
Also, the query optimizer will trip over any expressions with functions if you should ever end up wanting to do something like "SELECT .... WHERE MD5(xxx) = ... "
And database functions aren't very portable in general.
I try to use functions in my scripting language whenever calculations like that are required. I keep my SQL function useage down to a minimum, for a number of reasons.
The primary reason is that my one SQL database is responsible for hosting multiple websites. If the SQL server were to get bogged down with requests from one site, it would adversely affect the rest. This is even more important to consider if you are working on a shared server for example, although in this case you have little control over what the other users are doing.
The secondary reason is that I like my SQL code to be as portable as possible. I don't even want to try to count the different flavors of SQL that exist, so I try to keep functions (especially non-standard extensions) out of my SQL code, except for things like SUM or MIN/MAX.
I guess what I'm saying is, SQL is designed to store and retrieve data, and it should be kept to that purpose. Use your serving language of choice to perform any calculations beforehand, and keep your SQL code portable.
Personally, I try to keep the database as simple (to the minimum) with Insert, Update, Delete without having too much function that can be used in code. Stored Proc is the same, contain only task that are very close to persistence data and not business logic related.
I would put the MD5 outside. This will let met have this "data manipulation" outside the storage scope of the database.
But, your example is quite "easy" and I do not think it's bad to have it inside...
Use your database as means of persisting and mantaining data integrity. And leave business logic outside of it.
If you put business logic, any of it, in your database, you are making it more complex to manage and mantain in the future.
I think most of the time, you're going to want to leave the data manipulation to the webserver but, if you want to process databases with regards to tables, relations, etc., then go for the DB.
I'm personally lobbying my company to upgrade our MySQL server to 5.0 so that I can start taking advantage of procedures (which is killing a couple of sites we administer).
Like the other answers so far, I prefer to keep all the business logic in one place. Namely, my application language. (More specifically, in the object model, if one is present, but not all code is OO.)
However, if you look around StackOverflow for (my)sql-tagged questions about whether to use inline SQL or stored procedures, you'll find that most of the people responding to those are strongly in favor of using stored procs whenever and whereever possible, even for the most trivial queries. You may want to check out some of those questions to see some of the arguments favoring the other approach.

Categories