1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
|
<?php
/***************************************************************************************************************
* FR V1.0
* CREATED BY & POWER BY DENAYER JOEL & DGSI SPRL - 15/02/2009
* FONCTIONS CREE POUR LA CONNECTION AUX BASES DE DONNEES MULTISERVER (REPLICATION)
* OPTIMISE DE FACON PROPRE LES DEMANDES DE CONNEXIONS AUX SERVEURS SLAVE & MASTER
* EST UTILISE SUR DES SERVEURS EN PRODUCTION SUR LESQUELLES IL Y A ENORMEMENT DE REQUETES
* Bien que Mysql ferme de lui-même la connection quand il à fini son traitement il est parfois utile de fermer
* obligatoirement la connection pour une autre requete, surtout dans le cas ou on a un ou plusieurs serveur SLAVE
* pour la répartition des charges.
*
* Merci de laisser cette anotation si vous utilisé ce script
* Pour nous remercier vous pouvez faire un lien vers un de nos sites (www.bottin.be).
* Si vous modifié ou utilisé ce script ou que vous avez améliorer/optimiser certaines requêtes, merci de nous en faire part.
* (bottin.be@gmail.com)
* Ce script est en license libre.
*******************************************************************************************************************/
/*
//fonction de connection a la base de données
*/
function connection_BD($db_serverMasterOrSlave=false)
{
/**************************************************************************************************
!!! Les mises à jour se font toujours sur le Maître.
Si $db_serverMasterOrSlave n'est pas signalé, on choisi le Maître par défaut.
On adapte la connection en fonction du maitre ou de l'esclave
***************************************************************************************************/
/*
//On reprend les variables du fichier de configuration (LoginAndPass)
NE MODIFIER PAS CE SCRIPT SI VOUS NE SAVEZ PAS CE QUE VOUS FAITE
*/
global $db_server, $db_user_login, $db_user_pass, $db_name, $LoginMysqlSlave, $PasswordMysqlSlave, $VosIpDeConnection;
if($db_serverMasterOrSlave != false)
{
/* Si != FALSE on choisi le groupe SLAVE */
$ChoiceIpServer = ChoiceIpSelect($db_serverMasterOrSlave);
/*
Choix des login de connection MASTER OR SLAVE
dans le cas ou on ajoute le MASTER dans le groupe SLAVE
*/
if( $ChoiceIpServer != $db_server )
{
/*
//on n'est pas sur le MASTER
//on choisi les login et pass du slave
*/
$db_user_login2 = $LoginMysqlSlave;
$db_user_pass2 = $PasswordMysqlSlave;
}
else
{
/*
//on est sur le MASTER
//on choisi les login et pass du MASTER
*/
$db_user_login2 = $db_user_login;
$db_user_pass2 = $db_user_pass;
}
/* tester si le SLAVE repond à la demande */
$CheckIpConnectionMysql = CheckIpConnectionMysql($ChoiceIpServer,$db_user_login2,$db_user_pass2);
if($CheckIpConnectionMysql==false)
{
/*
//on n'a pas de réponse du serveur
//on choisi la MASTER par défaut (même si c'est lui qui ne répond pas)
*/
$connect_serveur = @mysql_connect($db_server, $db_user_login, $db_user_pass, MYSQL_CLIENT_COMPRESS);
/*
//enregistrement du logs (vous pouvez désactiver cette option quand vous avez fini vos tests à partir de LoginAndPass.)
*/
RecMysqlConnection("ECHEC DE CONNECTION AU SLAVE... \n-->SERVER MASTER: ".$db_server." DATABASE:".$db_name." ");
}
else
{
$connect_serveur = $CheckIpConnectionMysql;
/*
//enregistrement du logs (vous pouvez désactiver cette option quand vous avez fini vos tests à partir de LoginAndPass.)
*/
RecMysqlConnection('SERVER SLAVE: '.$ChoiceIpServer.' DATABASE:'.$db_name.' ');
}
}
else
{
/*
//MAITRE POUR LES UPDATE & INSERT
*/
$connect_serveur = @mysql_connect($db_server, $db_user_login, $db_user_pass, MYSQL_CLIENT_COMPRESS);
/*
//enregistrement du logs (vous pouvez désactiver cette option quand vous avez fini vos tests à partir de LoginAndPass.)
*/
RecMysqlConnection('SERVER MASTER: '.$db_server.' DATABASE:'.$db_name.' ');
}
$connect_bdd = mysql_select_db($db_name, $connect_serveur); /* connection à la base de donnée*/
if(!$connect_serveur || !$connect_bdd)
{
/* Si la connection au serveur ou à la base échoue malgré tout */
$page = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$messErrSqlA = 'ERROR CONNECTION BD: '.$db_server.'.<br />';
$messErrSqlA .= 'fonctions_connection_bd.php.<br />';
$messErrSqlA .= 'Url:'.$page.'<br /><br />';
/*
//message visible sur la page en production MAIS réservé au webmaster
*/
$pos = strpos($VosIpDeConnection, $_SERVER['REMOTE_ADDR']);
if($pos !== false)
{
echo '<hr /><br /><br />'.$messErrSqlA.'<br /><br /><hr />';
}
/* prevennir le webmaster */
emailErr($messErrSqlA.mysql_errno().' : '.mysqlErr().'<hr />'.mysql_error()); /* envoi d'un e-mail à l'admin pour lui signaler l'erreur SQL */
/* message d'erreur pour le VISITEUR (lui il ne verra que cela) */
echo "
Le serveur n'est momentanément pas en mesure de vous afficher cette page.<br />
Essayez de recharger la page pour résoudre le problème.<br />
Sinon, veuillez patienter quelques secondes/minutes, notre service technique à été prévenu de cette anomalie.<br />
";
exit;
}
/*
et pour finir on retourne le résultat final qui sera traité dans send_sql
ou comme tel si vous passer directement par mysql_query
*/
return $connect_serveur;
}
function send_sql($SQL_requete,$SQL_desc=false)
{
/*
// requête SQL, description de la requête
// Cette fonction vous permet de traiter les requêtes mysql_query sans avoir besoin de savoir si il faut ouvrir une connection ou pas.
// elle prend en compte également la réplication mysql (si vous utilisé celle-ci).
// la requete est dirigée sur le bon serveur (tout ce qui n'est pas un SELECT sera traité par le serveur MASTER).
*/
global $db_server, $IpMysqlSlave, $VosIpDeConnection;
/*
//les globals sont définie dans le fichier LoginAndPass
//$db_server == adresse IP du serveur LOCAL, ca peut être localhost mais JAMAIS celui du MASTER (base de données répliquée)
//$IpMysqlSlave == adresse IP du ou des serveurs SLAVE séparée par un ";" (voir config fichier LoginAndPass)
//test la connection mysql
*/
if (!@mysql_ping())
{
/*
//Aucune connexion n'est ouverte;
//Ouverture d'une connexion...";
*/
$Operation = disp_xwords($SQL_requete,1);/* check type de requete */
if($SQL_desc=='MASTER')
{
/*
//si MASTER est renseigné dans $SQL_desc, on oblige MASTER à la connection
//c'est utile dans la cas ou vous devriez absolument avoir la requête du MASTER
//par exemple pour des sessions de temps
*/
connection_BD();
}
else
{
if($Operation == 'SELECT')
{
/*
//on peut choisir le groupe SLAVE
*/
connection_BD($IpMysqlSlave);
}
else
{
/*
//toujours choisir le MASTER
*/
connection_BD();
}
}
}
else
{
$RecupConnect = RecupIp(mysql_get_host_info());
/*
//Une connexion était déjà ouverte
//Vérifier si on est sur le bon serveur en fonction de la requête.
*/
$Operation = disp_xwords($SQL_requete,1);
/*
//il faut savoir si la connection était MASTER ou SLAVE
*/
if($RecupConnect==$db_server)
{
/*
//on est sur master
*/
$Master = true;
}
else
{
$Master = false;
/*
//on est sur le groupe SLAVE
*/
}
if($Operation == 'SELECT')
{
/*
//on doit choisir le groupe SLAVE
*/
if($Master==true)
{
/*
//on ferme la connection et on se reconnecte au SLAVE sauf si on nous indique le contraire
*/
if($SQL_desc!='MASTER')
{
mysql_close();
connection_BD($IpMysqlSlave);
}
}
/* sinon on est déjà connecté */
}
else
{
/*
//toujours choisir le MASTER
*/
if($Master==false)
{
/*
//on ferme la connection et on se reconnecte au MASTER
*/
mysql_close();
connection_BD();/* non defini == MASTER */
}
}
}
/*
//envoi la requete au serveur SQL
*/
$SQL_result = mysql_query($SQL_requete);
/*
//enregistrement des logs (à desactiver si vous en avez plus besoin)
*/
RecMysqlConnection("SQL: ".$SQL_requete." DESC:".$SQL_desc." \n");
if(!$SQL_result)
{
/*
// si la requête a échouée on previent le webmaster
*/
$page = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$messErrSqlA = 'ERROR SEND_SQL BD:<br />';
$messErrSqlA .= '<br />Page en cause: '.$page.'';
$messErrSqlA .= '<br />SQL_result '.$SQL_result.'';
$messErrSqlA .= '<br />SQL_requete: '.$SQL_requete.'';
$messErrSqlA .= '<br />SQL_desc: '.$SQL_desc.'<br />';
$messErrSqlA .= 'Code erreur:<br/><br />';
/*
envoi d'un e-mail à l'admin pour lui signaler l'erreur SQL
*/
emailErr($messErrSqlA .'<br />'. mysqlErr() . ' ' . mysql_errno() . ' : <br />');
/*
enregistrement dans les logs
*/
RecMysqlConnection("ERROR SQL: ".$SQL_requete." DESC:".$SQL_desc." \n ".mysql_errno()."\n".mysqlErr()."\n");
$pos = strpos($VosIpDeConnection, $_SERVER['REMOTE_ADDR']);
if($pos !== false)
{
/*
//message pour la page en production réservé au webmaster en fonction de ses IP
*/
echo '<hr /><br /><br />'.$messErrSqlA.'<br /><br /><hr />';
}
/*
//message d'erreur pour le client
*/
echo"
Le serveur n'est momentanément pas en mesure de traiter votre requête.<br />
Essayez de recharger la page pour résoudre le problème.<br />
Sinon, veuillez patienter quelques secondes/minutes, notre service technique à été prévennu de cette anomalie.<br />
";
exit(); /* on sort en cas d'erreur */
}
/*
//sortie des resultats de la requete
*/
return $SQL_result;
}
function mysqlErr()
{
/*
//fonction utile pour avoir les erreurs en francais par e-mails
*/
$partie = explode('\'', mysql_error() ); /* On découpe le message d'erreur retourné par mysql_error() */
switch (mysql_errno() )
{
/*
// On cherche quel N° d'erreur SQL à été retouné
*/
case 1040 : /* Too many connections */
return 'Trop de connections simultanées. Merci de revenir dans quelques minutes ou de recharger la page';
break;
case 1044 : /* Access denied for user: 'login' to database 'nombase' */
return 'La base de données "'.$partie[3].'" n\'a pas été trouvée.';
break;
case 1045 : /* Access denied for user: 'login' (Using password: YES) */
return 'L\'utilisateur désigné "'.$partie[1].'" n\'a pas été trouvé.';
break;
case 1046 : /* No Database Selected */
return 'Aucune base de données n\'a été sélectionnée.</p>';
break;
case 1052 : /* Column: 'champ' in where clause is ambiguous */
return 'La clause WHERE est ambiguë pour la colonne '.$partie[1].'.';
break;
case 1053 : /* Server shutdown in progress */
return 'Le serveur SQL a été arrêté. Essayez de recharger la page ou revenez dans quelques minutes.';
break;
case 1054 :
switch ($partie[3])
{ /* On cherche quelle chaine est retournée par $morceau[3] */
case 'field list' : /* Unknown column 'nomChamp' in 'field list' */
return 'Le champ "'.$partie[1].'" précisé dans la liste des champs n\'a pas été trouvé.';
break;
case 'where clause' : /* Unknown column 'nomChamp' in 'where clause' */
return 'Le champ "'.$partie[1].'" précisé dans la clause WHERE n\'a pas été trouvé.';
break;
default :
return mysql_error();
}
break;
case 1064 : /* You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'requete' */
return 'Une erreur de syntaxe SQL se trouve dans la requête ('.$partie[1].')<br />';
break;
case 1065 : /* Query was empty */
return 'Aucune requête SQL n\'à été trouvée.<br />';
break;
case 1109 : /* Unknown table 'nom_table' in where clause */
case 1146 :
return 'La table "'.$partie[1].'" n\'a pas été trouvée dans la clause WHERE.';
break;
case 2002 : /* Can't connect to local MySQL server through socket 'chemnin d'accès' (2) */
return 'Échec lors de la connection au serveur SQL.';
break;
case 2005 : /* Unknown MySQL Server Host 'serveur' (2) */
return 'Le serveur SQL "'.$partie[1].'" n\'a pas été trouvé.';
break;
case 2013 : /* Lost connection to MySQL server during query */
return 'La connection au serveur SQL a été perdue lors de la requête. Essayez de recharger la page pour résoudre le problème.';
break;
default :
return mysql_error();
}
}
/******************************************/
/* ENVOI DE MAIL BASIC AU WEBMASTER */
/******************************************/
function emailErr($messErr)
{
/*
// envoi du mail au webmaster
*/
global $EmailWebmaster; /* defini dans le fichier LoginAndPAss */
$subject = $_SERVER['HTTP_HOST'].' Erreur SQL '.mysql_errno();
$message = $messErr;
$domaines = str_replace('www.','',$_SERVER['HTTP_HOST']);
$expediteur = 'NoReply@'.$domaines; /* L'email de l'expéditeur. */
$retour = $EmailWebmaster;/* e-mail de retour */
$message = str_replace('<br />', "\n", $message);/* message traité pour les sauts de ligne */
$to = $EmailWebmaster;/* e-mail du destinataire */
$headers = 'From: '.$expediteur."\r\n".'Reply-To: '.$retour."\r\n"; /* en-tête de l'e-mail */
mail($to, $subject, $message, $headers); /* envoi d'un e-mail à l'administrateur */
}
function ChoiceIpSelect($source)
{
/*
// repartit la charge des SELECT de facon aleatoire entre les serveurs
// y compris pour le maître si il est inclus dans le groupe SLAVE
*/
$ListIp = explode(';',$source);
$totalIpSelect = count($ListIp);
if($totalIpSelect==0)
{
return $source;
}
else
{
$i = mt_rand(0, $totalIpSelect-1);
return $ListIp[$i];
}
}
function CheckIpConnectionMysql($IpServer,$LoginServer,$PasswordServer)
{
/*
//test de connection au serveur Mysql
*/
$Check = @mysql_connect($IpServer,$LoginServer,$PasswordServer,MYSQL_CLIENT_COMPRESS);
if($Check!='')
{
return $Check;
}
else
{
return false;
}
}
function RecMysqlConnection($source)
{
/*
//enregistrement des logs
*/
global $LogsActivate,$RepertoireLogs;
if($LogsActivate==1)
{
$dateMysql = date("d-m-Y");
$heureMysql = date("H:i:s");
$DateFichier = date('d-m-Y');
$Fichier = $RepertoireLogs."Mysql_".$DateFichier."_test.log";
$inF_com = fopen($Fichier,"a+");
fwrite($inF_com,$DateFichier."/".$heureMysql.":".$source." \n");
fclose($inF_com);
}
}
function RecupIp($source)
{
/*
//recupère IP du serveur Mysql en cour d'utilisation
*/
$ereg='#(.*?) via (.*?)#';
preg_match($ereg,$source,$matche);
return $matche[1];
}
function disp_xwords($MyString,$xwords)
{
/*
//Recupère le premier mots d'une chaine
//nous sert pour savoir si on a un SELECT comme premier mot
*/
$NewString='';
$StringTab=explode(" ",$MyString);
for($i=0;$i<$xwords;$i++)
{
$NewString.= $StringTab[$i];
}
return trim(strtoupper ($NewString));
}
/*
traitement de toutes les autres erreurs de script
*/
ini_set('log_errors', 1) ;
$DateLogs=date('m-d-Y');
ini_set('error_log', $RepertoireLogs.'http_php_'.$DateLogs.'.log') ;
$pose = strpos($VosIpDeConnection, $_SERVER['REMOTE_ADDR']);
if($pose !== false)
{
ini_set('display_errors', 1);
ini_set('error_reporting', E_ALL);
}
else
{
error_reporting (0);/* on n'affiche rien pour le visiteur */
}
/*
Fin du fichier connection_bdd
*/
?> |
Partager