On one of my servers I've had a strange thing happen.
Normally, when a script does mysql_query($query) it just works if mysql_connect() was successfully called beforehand.
Now, it isn't working more than half the time. Now I've suddenly had to edit an entire shopping cart worth of mysql_query calls to include what used to be an optional DB link. In other words mysql_query($query, $db_link) is now what the code looks like.
I've done this temporarily so that visitors can still use the site but I really need to know what could have caused such an event.
Is there some setting that could have somehow changed in one of the php.ini files that would cause this? I know I wasn't touching them when this happened and I was the only one logged into the server at the time (as far as I can tell).
Calling mysql_query() without a connection parameter will use the most recently established connection. So as long as you're only connecting to one database, you won't see any problems.
From the docs:
If the link identifier is not specified, the last link opened by mysql_connect() is assumed. If no such link is found, it will try to create one as if mysql_connect() was called with no arguments. If no connection is found or established, an E_WARNING level error is generated.
If you add or include some new code that's connecting to a different database though - perhaps a hit tracker, or an analytics tool, for example - then that can break your existing code because it establishes another mysql connection - and any of your queries that happen after that new connection is established will now be using the wrong connection.
This will happen even if the extra code is properly written and always uses its own connection identifier - it won't have problems of accidentally using your connection, but your code will still accidentally use its connection.
To safely use mysql_query(), you really need to keep track of the database connection, and use it in every query.
All that being said - if you're making changes to all the mysql_* calls anyways, please consider switching to mysqli. The mysql_* functions are deprecated and no longer supported. The mysqli extension can be almost a drop-in replacement, and also provides support for features such as prepared statements.
The PDO extension is another possible replacement, but would require a bit more rewriting when switching from using mysql_*.
Related
I'm refactoring PHP code to move from mysql_* and mysqli_* functions to PDO, and would like to accomplish this as efficiently as possible.
I use a file I call 'core.common.php'. I initializes the PDO database access object, has $_SESSION management features, and other features such as generic message and error notification functions (in the form of s.) I use the MsgBox() and ErrBox() functions extensively while developing and debugging. This file gets included at the top of every PHP-generated web page.
I have managed, at least through some testing, to successfully pass the PDO object (by injecting the PDO object in the __construct method) to classes that require database access.
It seems to me that this approach, while it still works so far, would only apply to each visitor of the site... Each visitor can use the same PDO connector throughout all pages they visit on the site.
My real questions are...
What happens when there are many visitors ?? Does each get their own PDO instance ? Would this mean that there would be many instances of database connections ?
The reason I'm asking is the host I currently use has "limited my resource usage" due to... according to them... "excessive resource usage". It is a "shared server". They suggest upgrading to a VPS (Virtual Private Server), and, of course at additional cost.
Is the host scamming me for more $$ ??
What, in the eyes of the Pros here, would be my best approach to this issue ?
And... Absolutely for all... Be critical and specific.
Any ideas are greatly welcomed !
What happens when there are many visitors ??
Exactly the same thing that happened with mysql and mysqli functions.
Does each get their own PDO instance ?
Yes. In a way.
Would this mean that there would be many instances of database connections ?
Yes. Just like it was with mysql functions.
the host I currently use has "limited my resource usage" due to... according to them... "excessive resource usage".
Make sure there is only one connection per script instance. According to your description it is already so, but just to be sure. That could be only issue with PDO. Also turn off persistent connection if used.
Regarding other aspects of this excessive usage, you better start a separate question, to ask recommendations on how to profile your code to get to the bottleneck.
In the function mssql_connect, there is a fourth parameter called new_link.
If a second call is made to mssql_connect() with the same arguments,
no new link will be established, but instead, the link identifier of
the already opened link will be returned. This parameter modifies this
behavior and makes mssql_connect() always open a new link, even if
mssql_connect() was called before with the same parameters.
I've noticed that a number of our scripts have been setting this parameter to true. The problem is, the person who made this decision can no longer be reached and I'm really struggling to think of a valid (read: sane) reason why a new connection should be forced open when a valid connection already exists.
Note that the function mysql_connect also has a similar param.
there surely are only quite rare use cases.
My understanding is this:
<vendor>_connect() opens a connection to the DB server, not to a specific database.
If you want to work with different DBs on the same server within the same request, you'll need to manage the access - either several calls to <vendor>_select_db (mssql_select_db) on the same connection, or different connections with different selected DBs to the same DB server.
Same problem arises if you want to set connection specific parameter for some calls to the DB, but not all. For example the horrors surrounding the right charset (at least when working with mysql) mysql_set_charset('utf8',$link);, if some legacy nightmare let's you work with both latin-1 and utf8 content.
[edit] folks, don't use mysql_* functions! they will be deprecated soon and pose security risks. The example is only used for brevity and semantic similarity to the mssql_* functions!
This is how I understand this and do not claim it is 100% correct.
If you open connection twice with same parameters, connection id will be same and this can mess up stuff, if you make transactions for example. Here comes new_link parameters - connections will use different ids and so everything should be fine.
Ok , so many people are asking this question, and there are many approaches on how to make the connection to DB secure,
Now I did some googling , many suggest, putting the connection to DB code in a file outside the html_public , and to call it from there when I need to make a connection.
to be honest, am happy with what I have, though I'm not sure how secure it is,
this is how I connect to the DB:
first, I make sure all inputs are fully escaped and validated...
after , in the same page , i make the connection, for example:
mysql_connect("localhost","Admin","Password") or
die ("DB Connection Error");
mysql_select_db("Users") or die ("DB Error");
and the rest of the code after, I close the mysql connection.
Now , It just don't feel right that the DB user info are written in the page, but how can someone (a "hacker") , get this info?
I mean , all inputs are fully escaped and validated, the users I use have very limited previleges, like select and update... only.
Is this secure?? and if not, can u please suggest a more secure way?
Thank you very much for ur help in advance :)
shady
The reason you should consider putting this file outside the web root is that some hosting providers have temporarily stopped interpreting PHP from time to time (due to configuration faults, often after an update on their part). The code will then get sent in clear text and the password will be out in the wild.
Consider this directory structure, where public_html is the web root:
/include1.php
/public_html/index.php
/public_html/includes/include0.php
Now consider this index.php:
<?php
include('includes/include0.php');
do_db_work_and_serve_page_to_visitor();
?>
If the web server starts serving this file in the open, it won't take long before someone tries to download include0.php. Nobody will be able to download include1.php, however, because it's outside the web root and therefore never handled by the web server.
I've personally not heard of a hosting provider not interpreting PHP, leading to your php source code going public. I just did a quick test on this on a RHEL5-Based server without php installed, and just got back a blank page when trying to access a php document.
mysql_* functions have become deprecated with the latest releases of php, and are now moving towards mysqli, as an overall more efficient and secure solution; I'd recommend taking a look into that; http://php.net/manual/en/book.mysqli.php - there's no deprecation errors or anything of the sort yet in PHP5.4 for using plain mysql_ functions, but if you're looking to keep on top of things, take a look into mysqli.
As for a quick answer to your above question, to be honest, I'd see that method as reasonably secure. Just make sure you've got escape chars etc set up, and I don't think you'll run into any issues.
Edit: Some people have posted that in very rare cases, some providers can leak your php source code in this manner. If this is the case, my first advice would be to switch provider.. but using an include_once to load your db info from another php file/lib would be a quick workaround for this. But again, if your provider's setup does allow for leaks such as these, I would be more concerned about their security than yours.
You can have php grab your DB password from a text file stored outside of the public webspace (using fopen), but I personally don't see any real reason for doing this.
Best of luck!
Eoghan
The best pratice is to use PHP PDO instead of the old mysql API.
Take a look: http://php.net/manual/en/ref.pdo-mysql.connection.php
Also, here's an interesting article: http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
I am building some new additions to an existing WebApp. The old code was written using mysql functions. Changing the entire application to use PDO would be a VERY man-hour-intense thing to do. However, for all new code, I'd like to begin using PDO.
Are there any concerns I need to be aware of for using PDO within an existing application that does NOT use PDO to interface with the database? It's no problem to connect to the DB using both/either of these options at the same time when a page is loaded, correct?
While I'm at it - I am interested to know how big the need is to close a PDO connection after a page loads - or is it fine to leave the connection open?
Thanks all.
There's no need to close any type of database connection when a page finishes loading - PHP always does this for you (unless you make the mistake of enabling persistent connections).
However, if you use PDO AND mysql_ in the same page, connecting to the same database, it will consume twice as many connections (while the page is executing) on the server. This may or may not be a problem.
Personally I would recommend that you remain consistent within the application if you don't want to refactor it to use PDO throughout.
I code a simple php/mysql web page, that there is page1.php, page2.php and so on. Because I make use of the database on every page (or at least the 90% of them) I place on the top of them the standard
mysql_connect("localhost"," "," ");
mysql_select_db(" ");
.
.
mysql_close();
with my queries.
My question is do I really need to connect to the database on each page or is there any way to avoid this and still stay connected? Some of the pages are linked to the others and I can make use of SESSIONS to post some variables, but my question goes to something more globalized.
The web works in a disconnected state by nature. Meaning that you have no idea if the client is going to come back for a second request or not.
Regardless you absolutely want to connect/disconnect from the database on every single page. This is the only way to ensure you aren't leaking connections and the site can stay responsive.
Most systems have built in ways to handle connection pooling which makes the act of requesting a new connection very very fast and therefore something you don't have to worry about.
You can use mysql_pconnect for a persistent connection, although its not going to help you that much and it can be a big pain to do properly. Its almost just better to connect on every page, especially if the database server is running on the same machine as the php server.
Try using
mysql_pconnect()
From PHP.net
"acts very much like mysql_connect() with two major differences.
First, when connecting, the function would first try to find a (persistent) link that's already open with the same host, username and password. If one is found, an identifier for it will be returned instead of opening a new connection.
Second, the connection to the SQL server will not be closed when the execution of the script ends. Instead, the link will remain open for future use (mysql_close() will not close links established by mysql_pconnect())."
If you just want to make it so that you don't have to hard code it into the top of every file write the connection code in a file then use require /path/to/file/name.php and it will establish it everytime Note: it might be include and not require.