Problemy z mysql_real_escape_string
"…
Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user ‘user’@'localhost’ (using password: NO) in /home/www/…
Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in /home/www/…
…"
Jeżeli powyższy komunikat nie jest Ci obcy, prawdopodobnie napotkałeś na problem jaki mieliśmy przy jednym z wcześniejszych projektów.
Jakiś czas temu budowaliśmy spory serwis dla jednego z klientów. Początkowo strona powstawała na serwerze lokalnym XAMPP , następnie całość została wrzucona na serwer zewnętrzny jednej z firm hostingowych, aby klient miał możliwość przetestowania. Strona sprawdzona, zatwierdzona. Niestety po zainstalowaniu serwisu na serwerze klienta, naszym oczom ukazał się powyższy komunikat o błędzie dostępu do bazy danych.
Wszystkie dane, host bazy danych, login, hasło itp. sprawdzone kilka razy – wszystko się zgadzało. Po kilku niespokojnych godzinach okazało się, że problemem były różnice w konfiguracji serwera klienta, a mianowicie:
na niektórych serwerach użycie mysql_real_escape_string wymaga wcześniejszego połączenia z bazą danych.
Przypuśćmy, że mamy formularz dodający adresy e-mail do newsletter’a i chcemy zapisać podany adres w bazie danych. Jeżeli mamy większą aplikację skorzystamy z funkcji obsługującej operacje na bazie danych. Uproszczony kod będzie wyglądał mniej więcej tak:
<?php
//...
$email = $_ POST['email'];
$email = mysql_real_escape_string($email);
$query = "INSERT INTO tabela VALUES (null, '$email');";
if (db_query($query)) {
echo 'Adres dodany';
} else {
echo 'Nie udało się dodać adresu';
}
//...
function db_query($query) {
$connection = mysql_connect($db_host, $db_user, $db_passw);
mysql_select_db($db_name, $connection);
if(mysql_query($query)) {
return true;
} else {
return false;
}
mysql_close($connection);
}
?>
Oczywiście w omawianym przez nas przypadku operacja zakończy się błędem:
"…
Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user ‘user’@'localhost’ (using password: NO) in /home/www/…
Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in /home/www/…
…"
W tej sytuacji rozwiązaniem może być zastosowanie funkcji odpowiedzialnej za otwarcie połączenia, następnie wykonać zapytanie i zamknąć połączenie.
Przykładowy kod mógłby wyglądać następująco:
<?php
//...
if ($connection = db_connect()) {// łączymy się z bazą danych
// jeżeli istnieje połączenie możemy teraz podstawić nasze zmienne i zastosować mysql_real_escape_string
$email = mysql_real_escape_string($_ POST['email']);
$query = "INSERT INTO tabela VALUES (null, '$email');";
mysql_query($query);
mysql_close($connection);
} else {
echo 'Nie udało się połączyć z bazą danych!';
}
//
//...
//
function db_connect() {
$connection = mysql_connect('host_bazy', 'uzytkownik_bazy', 'haslo_dostepu');
mysql_select_db('nazwa_bazy', $connection);
return $connection;
}
//...
?>
Powyższe rozwiązanie powinno zlikwidować już nasz błąd, ale przy każdej operacji na bazie danych musimy teraz dodawać sporo kodu. Całość robi się dłuższa i mniej czytelna. W przypadku naszego zlecenia idealnym rozwiązaniem było zastosowanie prostej klasy obsługującej bazę danych.


