The note from angelo [at] mandato <dot> com is a good way to reuse the msyql connection, like mysql connection pooling.
However, you need to remove the $g_link = false; in the file. Other wise, everytime you include this file, the mysql connection is set to false, and you have to call the mysql_connect again to connect to the sql server, even though you may have already have live mysql connection ready for use.
<?php
//need to remove this line to resue the connection resource
$g_link = false;
function GetMyConnection()
{
global $g_link;
if( $g_link )
return $g_link;
$g_link = mysql_connect( 'localhost', 'dbuser', 'dbpass') or die('Could not connect to mysql server.' );
mysql_select_db('wordpress', $g_link) or die('Could not select database.');
return $g_link;
}
function CleanUpDB()
{
global $g_link;
if( $g_link != false )
mysql_close($g_link);
$g_link = false;
}
?>
mysql_connect
(PHP 4, PHP 5, PECL mysql:1.0)
mysql_connect — Ouvre une connexion à un serveur MySQL
Description
Ouvre ou réutilise une connexion à un serveur MySQL.
Liste de paramètres
- server
-
Le serveur MySQL. Il peut aussi inclure le numéro de port. C'est-à-dire "hostname:port" ou le chemin vers le socket local, c'est-à-dire ":/path/to/socket" pour localhost.
Si la directive PHP mysql.default_host n'est pas définie (défaut), alors la valeur par défaut est "localhost:3306". En safe mode SQL, ce paramètre est ignoré et la valeur "localhost:3306" est toujours utilisée.
- username
-
Le nom d'utilisateur. La valeur par défaut est définie par l'option mysql.default_user. En safe mode SQL, ce paramètre est ignoré et le nom de l'utilisateur propriétaire du processus serveur est utilisé.
- password
-
Le mot de passe. La valeur par défaut est définie par l'option mysql.default_password. En safe mode SQL, ce paramètre est ignoré et un mot de passe vide est utilisé.
- new_link
-
Si un deuxième appel est fait à mysql_connect() avec les mêmes arguments, aucune nouvelle connexion ne sera établie, mais plutôt, l'identifiant de la connexion de la connexion déjà ouverte sera retourné. Le paramètre new_link modifie ce comportement et permet à mysql_connect() de toujours ouvrir une nouvelle connexion, même si mysql_connect() a été appelée avant avec les mêmes paramètres. En safe mode SQL, ce paramètre est ignoré.
- client_flags
-
Le paramètre client_flags peut être une combinaison des constantes suivantes : 128 (active le gestionnaire LOAD DATA LOCAL), MYSQL_CLIENT_SSL, MYSQL_CLIENT_COMPRESS, MYSQL_CLIENT_IGNORE_SPACE ou MYSQL_CLIENT_INTERACTIVE. Lisez la section à propos de Constantes pré-définies pour plus d'informations. En safe mode SQL, ce paramètre est ignoré.
Valeurs de retour
Retourne l'identifiant de connexion MySQL en cas de succès ou FALSE en cas d'échec.
Historique
| Version | Description |
|---|---|
| 4.3.0 | Ajout du paramètre client_flags . |
| 4.2.0 | Ajout du paramètre new_link . |
| 3.0.10 | Ajout du support pour ":/path/to/socket" avec server . |
| 3.0.0 | Ajout du support pour ":port" avec server . |
Exemples
Exemple #1 Exemple avec mysql_connect()
<?php
$link = mysql_connect("localhost", "mysql_user", "mysql_password")
or die("Impossible de se connecter : " . mysql_error());
echo 'Connexion réussie';
mysql_close($link);
?>
Exemple #2 Exemple avec mysql_connect() en utilisant la syntaxe hostname:port
<?php
// on se connecte à example.com et au port 3307
$link = mysql_connect('example.com:3307', 'mysql_user', 'mysql_password');
if (!$link) {
die('Connexion impossible : ' . mysql_error());
}
echo 'Connecté correctement';
mysql_close($link);
// on se connect à localhost au port 3307
$link = mysql_connect('127.0.0.1:3307', 'mysql_user', 'mysql_password');
if (!$link) {
die('Connexion impossible : ' . mysql_error());
}
echo 'Connecté correctement';
mysql_close($link);
?>
Exemple #3 Exemple avec mysql_connect() en utilisant la syntaxe ":/path/to/socket"
<?php
// on se connect à localhost et à l'interface de connexion, par exemple /tmp/mysql.sock
//variante 1 : oublie de localhost
$link = mysql_connect(':/tmp/mysql', 'mysql_user', 'mysql_password');
if (!$link) {
die('Connexion impossible : ' . mysql_error());
}
echo 'Connecté correctement';
mysql_close($link);
// variante 2 : avec localhost
$link = mysql_connect('localhost:/tmp/mysql.sock', 'mysql_user', 'mysql_password');
if (!$link) {
die('Connexion impossible : ' . mysql_error());
}
echo 'Connecté correctement';
mysql_close($link);
?>
Notes
Note: Toutes les fois que vous spécifiez "localhost" ou "localhost:port" en tant que serveur, le bibliothèque client MySQL surchargera cela et essaiera de se connecter à un socket local (nommé pipe sous Windows). Si vous souhaitez utiliser TCP/IP, utilisez "127.0.0.1" au lieu de "localhost". Si la bibliothèque client MySQL essaie de se connecter au mauvais socket local, vous devriez spécifier le chemin d'accès correct à Configuration à l'exécution dans votre configurations PHP et laisser le champ du serveur vide.
Note: La connexion au serveur sera fermée aussitôt que l'exécution du script se termine, à moins qu'elle soit fermée avant en appelant explicitement mysql_close().
Note: Vous pouvez supprimer les messages d'erreur en cas d'échec en faisant précéder le nom de la fonction par @.
Note: L'erreur "Can't create TCP/IP socket (10106)" signifie habituellement que la directive de configuration variables_order ne contient pas le caractère E. Sous Windows, si la variable d'environnement n'est pas copiée, la variable d'environnement SYSTEMROOT ne sera pas disponible et PHP aura des problèmes pour charger Winsock.
mysql_connect
08-Jun-2008 08:56
03-May-2008 09:17
Hiding the MySQL password is a big deal on multi-user machines.
With Lighttpd you can store the passwords in the server-config and make that file readable by root only.
This is the way (make sure you enable mod_setenv):
# Security through setenv
$HTTP["url"] =~ "^/~user/base-dir/" {
setenv.add-environment = (
"MYSQL_USERNAME" => "username",
"MYSQL_PASSWORD" => "password"
)
}
Your PHP file should then read the username/password as follows:
<?php
$username = getenv('MYSQL_USERNAME');
$password = getenv('MYSQL_PASSWORD');
?>
Mind that additional 'false-checking' is good practice.
25-Mar-2008 11:59
If you are trying to open multiple, separate MySQL connections with the same MySQL user, password, and hostname, you must set $new_link = TRUE to prevent mysql_connect from using an existing connection.
For example, you are opening two separate connections to two different databases (but on the same host, and with the same user and password):
$db1 = mysql_connect($dbhost, $dbuser, $dbpass);
$rv = mysql_select_db($dbname1, $db1);
$db2 = mysql_connect($dbhost, $dbuser, $dbpass);
$rv = mysql_select_db($dbname2, $db2);
At this point, both $db1 and $db2 will have selected the database named by $dbname2.
The workaround is to require that the second MySQL connection is new:
$db1 = mysql_connect($dbhost, $dbuser, $dbpass);
$rv = mysql_select_db($dbname1, $db1);
$db2 = mysql_connect($dbhost, $dbuser, $dbpass, TRUE);
$rv = mysql_select_db($dbname2, $db2);
Now, $db1 should have selected $dbname1, and $db2 should have selected $dbname2.
This has been documented on the mysql_select_db page as well.
Note: This occurs only when the server, username, and password parameters are identical for each mysql_connect statement.
03-Mar-2008 12:15
Recently, I saw an obscure problem where I could connect to MySQL from the PHP via Apache and MySQL via the MySQL console, and could not connect via the PHP-CLI. This was in Windows (XP). I usually use MySQLi extension, but also tried MySQL, and both refused to work.
I restarted the service multiple times, and the PHP-CLI still would not connect.
This eventually cleared up.
I made sure to stop the service. Then, I downloaded a zipped binary-package from dev.mysql.com and started the server a few times from the commandline (mysqld/mysqld-nt, where mysqld-nt is tuned specifically for Windows) and stopped it ("mysqladmin shutdown"). I was then able to successfully connect from the PHP-CLI ("php -r "mysql_connect('localhost', 'root', ''); ").
Making sure it was stopped, I started the regular server from the commandline, and that was then successful. I then stopped it and started it via the Services panel, and everything still worked.
I'm assuming that when the service was restarted initially, there was a component that had died and refused to be shutdown even though the service appeared to be stopped, but shutting it down via mysqladmin killed everything entirely.
11-Feb-2008 11:24
Looks like I learned this the hard way:
<?
//establish connection to master db server
mysql_connect (DB_HOST, DB_USER, DB_PASSWORD);
mysql_select_db (DB_NAME);
//establish connection to read-only slave cluster
$objMySQL_Read = mysql_connect (SLAVE_DB_HOST, SLAVE_DB_USER, SLAVE_DB_PASSWORD);
mysql_select_db (DB_NAME, $objMySQL_Read);
$strSQL = "SELECT col1,col2 FROM " . DB_NAME . "." . "tbl1 WHERE 1=1";
$objRS = mysql_query ($strSQL, $objMySQL_Read); //returns data from slaves
$strSQL = "INSERT INTO " . DB_NAME . "." . "tbl1 (col1,col2) VALUES (val1,val2)";
mysql_query ($strSQL);
//expected behavior, to insert the last statement into the master db, since it doesn't reference the read-only resource explicitly. instead, it inserts the record into the last connection, even though it shouldn't, since the last connection is not a global/anonymous connection like the first one, it's $objMySQL_Read.
//you'll get out of sync db's across your cluster unless you explicitly define all connection resources
?>
24-Dec-2007 03:32
The too many connections issue can be due to several problems.
1. you are using pconnect. This can tie up many connections and is not really needed for MySQL as new connections are really fast.
2. Apache children are hanging around for too long - combine this with pconnect and you have recipe for disaster.
Suggestions: reduce the amount of time apache child processes stay connected to the client and how many connections before they are killed off. And don't use pconnect.
20-Oct-2007 10:51
Sometimes, I want that MySQL service start automatically when my app need it. This is specially true if you work in a development PC and/or in an small intranet environment.
You can do something like this: if the mysql_connect() function returns FALSE, try to force the initialization of the MySQL service!
For example, under Windows:
<?php
$link = @mysql_connect($server,$user,$pass);
if (empty($link)){
@exec("%SystemRoot%\\system32\\net.exe start mysql");
sleep(5);
$link = @mysql_connect($servidor,$usuario,$clave);
}
?>
In Linux of course you can try "/etc/init.d/mysqld start" but you will need special permissions.
Regards.
02-Oct-2007 06:20
The use of mysql connections can become tricky with objects. I am using mysql_connect() in a database class I wrote and the class destructor calls mysql_close. Because I have several of these database objects, mysql_connect reuses existing connections. This is fine except when the script reaches the end of execution and PHP's garabage collection calls all the objects' __destruct() functions. mysql_close() throws a warning that the connection is invalid, in my case for one object. This is happening with objects which use an existing connection, as the connection has already been closed. I solved the problem by forcing mysql_connect() to create a new connection each time. This is not efficient but is sufficient for my purposes for now.
I wouldn't say this is a bug per-se, but it's something to look out for. I imagine using mysqli is the ultimate solution...
13-Aug-2007 09:11
All constants from MySQL source:
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
#define CLIENT_LONG_FLAG 4 /* Get all column flags */
#define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */
#define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */
#define CLIENT_COMPRESS 32 /* Can use compression protocol */
#define CLIENT_ODBC 64 /* Odbc client */
#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */
#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */
#define CLIENT_PROTOCOL_41 512 /* New 4.1 protocol */
#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */
#define CLIENT_SSL 2048 /* Switch to SSL after handshake */
#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */
#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */
#define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */
#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */
#define CLIENT_MULTI_STATEMENTS 65536 /* Enable/disable multi-stmt support */
#define CLIENT_MULTI_RESULTS 131072 /* Enable/disable multi-results */
#define CLIENT_REMEMBER_OPTIONS (((ulong) 1) << 31)
08-Apr-2007 06:05
if between first and second call with same arguments there was another call with another argument, initial connection link is not reused, but new connection is created instead, regardless of new_link argument.
for example, here only one single link will be opened and then reused:
<?php
$link1 = mysql_connect("localhost");
$link2 = mysql_connect("localhost");
?>
and here _three_ separate links will be opened:
<?php
$link1 = mysql_connect("localhost");
$link3 = mysql_connect("127.0.0.1");
$link2 = mysql_connect("localhost");
?>
so if you wanted to switch between connections just by call to mysql_connect, and rely on its internal link caching, you can be wasting your database connections.
19-Mar-2007 02:07
The post from 'Graham_Rule at ed dot ac dot uk' should include the following WARNING:
WARING: THE VALUES OF THESE DIRECTIVES WILL BE EXPOSED IF ANY OF THE CODE INCLUDES THE phpinfo() FUNCTION.
The phpinfo() function will print these values clear as day. I highly suggest against this method of storing MySQL authentication information.
I recommend creating connect and cleanup functions in a separate include file. If security is a concern, locate the include file outside of your web root folder.
<?php
$g_link = false;
function GetMyConnection()
{
global $g_link;
if( $g_link )
return $g_link;
$g_link = mysql_connect( 'host.name', 'user', 'password') or die('Could not connect to server.' );
mysql_select_db('database_name', $g_link) or die('Could not select database.');
return $g_link;
}
function CleanUpDB()
{
global $g_link;
if( $g_link != false )
mysql_close($g_link);
$g_link = false;
}
?>
Simply include your connnection.php file in your script and anywhere you use the mysql_query() function include a call to the GetMyConnection() function.
<?php
$res = mysql_query("SELECT ...", GetMyConnection() );
?>
12-Dec-2006 08:42
In case anyone else is getting "Client does not support authentication protocol requested by server; consider upgrading MySQL client" error. The problem is the new password hashing method used by MySQL >= 4.1 mentioned below.
Either update your PHP to v5 where the new password hashing is supported or use old_password() in MySQL 4.1.
FROM: http://www.digitalpeer.com/id/mysql
UPDATE mysql.user SET password=old_password("youroldhashpassword") WHERE user ='youruserid' and host ='yourhost'
then do
FLUSH PRIVILEGES
10-Nov-2006 01:59
How to get at multiple MySQL databases from PHP while continuing to hide the user credentials in Apache configuration files.
(This builds on my solution to the problem of hiding such credentials that I posted in May 2003 at http://uk2.php.net/manual/en/function.mysql-connect.php#32035)
<Directory /var/www/html/multidatabase>
php_value mysql.default_user "username1 username2"
php_value mysql.default_password "secret private"
php_value mysql.default_host "localhost server.example.com"
</Directory>
Note that the quotes are necessary to prevent the parser complaining about seeing too many parameters for php_value.
Given this setup in Apache, our script can fetch the composite value
$hostnames = @ini_get('mysql.default_host'); Split it into its component parts
$hostnames = preg_split("/[\s]+/", $hostnames); Then use the values in this array as if we had hard-coded:
$hostnames[0] = "localhost";
$hostnames[1] = "server.example.com"
Similar code may be written to fetch the usernames and passwords.
(One 'gotcha' with the mysql_error() function is that it will not give a sensible error report if there is a failure to open a second or subsequent connection. It uses the last successfully opened connection as the basis for its message!)
10-Nov-2006 01:43
The addition of entries to httpd.conf to stop .inc files being served by Apache is certainly useful and to be recommended.
But it doesn't change the fact that these files have to be readable by Apache so that the PHP processor can get at them.
As long as your don't have multiple, possibly untrusted, users on your machine then that's OK. But when you are running a large multi-user service with thousands of users its always possible that one of them will look at your .inc files and take a note of the passwords you have in them. They could even copy them into their own scripts and modify your databases!
Even if local users are trusted, there is always the possibility of a rogue script (PHP or some nastier language) being installed by an ignorant user. That script might then read your .inc files (whether or not they are in the web publishing tree) and expose your password.
09-Nov-2006 07:43
If you prefer to use a hostname instead of an ip on your connection string in a script (to be able to change the ip at will), but don't want the overhead of dns lookups, just add it to your /etc/hosts file (in windows: %WINDIR%/system32/drivers/etc/hosts).
For example, add the following to your hosts file (changing the bogus ip to your server's real ip):
123.123.123.123 mysqlserver1
Note: On linux, make sure you have "order: hosts,bind" on your /etc/host.conf file.
On a script, make the mysql connection like so:
<?
$sid = mysql_connect ("mysqlserver1", "user", "pass");
?>
Note: this sample is in php, but it can be any other programming language (just type "ping mysqlserver1" on a prompt, on your server)
And there you have it! If your server ever gets assigned a different ip, just update the hosts file with the new one (every script will work as-is, even if under different hostnames).
31-May-2006 08:42
Ever wonder what "default username" is?
<?php
$link = mysql_connect() or die(mysql_error());
$result = mysql_query("SELECT SESSION_USER(), CURRENT_USER();");
$row = mysql_fetch_row($result);
echo "SESSION USER: ", $row[0], "<br>\n";
echo "CURRENT USER: ", $row[1], "<br>\n";
?>
Both are ODBC@localhost in my win2k install, so my advice for windows is:
- create a MySQL user named ODBC with no password
- add localhost to ODBC user [right-click ODBC]
- set schema previleges to ODBC@localhost
- use mysql_connect() with no parms, or do not use ;)
This turns to work also with odbc_connect:
odbc_connect("myDSN", "", "")
09-May-2006 10:26
That's an interesting discovery. I don't think it should be this way, but I think it's more a firefox/browser bug (at least, if you see it as a bug) than a fault in mysql/php.
What happens if you load the pages in two different browser screens instead of two tabs?
08-May-2006 09:21
PHP (5.1.2) stores connections according to script name and remote host, apparently. If the same script is requested by the same browser in two different tabs (Firefox for this test) and requests a non-persistent connection using the same user and password, the connection will be shared.
Ran into this while testing a script for concurrent usage using "LOCK TABLES" queries... and found that one tab's script was blocking until the other finished. No blocking occurred when different machines loaded the same script at the same time. Very interesting.
connect to mysql via named pipe under windows :
in my.ini, add this:
[mysqld]
enable-named-pipe
then connect to the server, then connect to mysql using
mysql_connect('.')
27-Oct-2004 01:05
A description about the problem with the password hashing and how to adress them can be found at http://dev.mysql.com/doc/mysql/en/Password_hashing.html
23-Aug-2004 02:10
In MySQL4.1 and later, the default password hashing format has changed making it incompatible with 3.x clients.
I found out mysql_connect() works on server versions >= 4.1 when your MySQL user password is blank because password authentication isn't done in that case, otherwise you need to use another connection method (e.g. mysqli).
Also if you are using old MySQL tables on a new server (i.e. the passwords are stored in the old format), then the server will use the old auth method automatically and this function should work in all cases.
Hopefully this will help someone, it had me confused for a while because some of the users on my 4.1 server could connect and some couldn't.
31-Oct-2003 02:22
to use load data local infile function from mysql (at mysql 4.0.16, php 4.3.3), set fifth parameter of mysql_connect() to CLIENT_LOCAL_FILES(128), which based on MYSQL C API ( also mysql server support load file, check by "show variables like 'local_infile' ")
Thank 'phpweb at eden2 dot com' to point this out
27-Jun-2003 11:55
client_flags can be things other than MYSQL_CLIENT_COMPRESS, MYSQL_CLIENT_IGNORE_SPACE and MYSQL_CLIENT_INTERACTIVE.
I presume that mysql_connect() just passes through to the C MySQL API, which provides these constants:
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
#define CLIENT_LONG_FLAG 4 /* Get all column flags */
#define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */
#define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */
#define CLIENT_COMPRESS 32 /* Can use compression protocol */
#define CLIENT_ODBC 64 /* Odbc client */
#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */
#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */
#define CLIENT_CHANGE_USER 512 /* Support the mysql_change_user() */
#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */
#define CLIENT_SSL 2048 /* Switch to SSL after handshake */
#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */
#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */
Not all of these may work or be meaningful, but CLIENT_FOUND_ROWS does, at least.
14-May-2003 08:43
Another solution to the security problems of putting usernames and passwords into scripts. I haven't found this documented anywhere else so thought I'd suggest it for the online documentation. ........
Don't put passwords for mysql into scripts which may be read by any user on the machine. Instead put them into an Apache configuration file and make sure that it is not world-readable. (Apache reads its main config files as root.)
For example, add this to your httpd.conf (and chmod it to 600 or 660) then tell your apache to reload itself (apachectl graceful).
<Directory /var/www/html/mydatabase>
php_value mysql.default_user fred
php_value mysql.default_password secret
php_value mysql.default_host server.example.com
</Directory>
Then all you need in your PHP code is
$handle = mysql_connect() or die(mysql_error());
The passwords etc will only be picked up by scripts running in the named directory (or a sub-directory). The same may be done for virtualhosts etc.
If you don't want to keep reloading your Apache server then you ay test things putting the php_value directives into a (world readable) .htaccess file. (Clearly not for production use.)
If you need to debug the values that are being supplied (or not) then use this snippet:
@syslog(LOG_DEBUG, "Using user=".ini_get("mysql.default_user").
" pass=".ini_get("mysql.default_password").
" host=".ini_get("mysql.default_host"));
(This assumes that you are not running in 'safe_mode' and that you are on a unix of some sort.)
11-Mar-2003 10:40
Just in case you didn't know. You can use mysql_connect in a function to connect to a database and the connection is a super-global... meaning you can use mysql_query in other functions or in no function at all and PHP will use the connection that you opened. This is a handy bit of knowledge that helps if you have a large site with lots of scripts. If you create one function to connect to a db, and call that function in all your scripts, it makes for easier code maintenance since you only have to update one line of code to change your mysql connection instead of updating all your scripts individually.
