Berk Akademi
Birebir ders başvurusu Ücretsiz ön görüşme Ana Sayfa

PHP "PDOException: SQLSTATE[HY000] [1045] Access denied for user" Hatası Nasıl Çözülür?

php-pdoexception-sqlstate-hy000-1045-access-denied-for-user-hatasi-nasil-cozulur
Bu yazıda neler var?
  1. 1045 hatası bağlantının hangi aşamasında oluşur?
  2. PDO DSN ve kimlik bilgileri nasıl kontrol edilir?
  3. localhost ile 127.0.0.1 farkı teşhiste nasıl kullanılır?
  4. Kod, bağlantı ayarı ve kullanıcı yetkisi nasıl sırayla elenir?

PHP PDOException 1045 hatası, uygulamanın MySQL sunucusuna ulaştığı hâlde sunucunun gönderilen kullanıcı bilgilerini veya hesabın bağlantı erişimini kabul etmemesiyle oluşur. Çözüm için önce PDO DSN'sindeki host, port ve veritabanı adını, ardından PDO'ya ayrı verilen kullanıcı adı ile parolayı kontrol etmelisin.

1045 hatası bağlantının hangi aşamasında oluşur?

1045 hatası bağlantının hangi aşamasında oluşur?

PDO bağlantısı kurulurken PHP önce DSN ile belirtilen MySQL sunucusuna bağlanır, ardından kullanıcı hesabını doğrular. PDO::__construct() çağrısı sırasında sunucu bağlantıyı kabul etmez veya gönderilen kullanıcı adı ile parolayı geçerli bulmazsa, henüz SELECT, INSERT ya da başka bir SQL sorgusu çalışmadan PDOException oluşur. Bu nedenle 1045, sorgu yazımından önce ortaya çıkan bir bağlantı kimlik doğrulama hatasıdır.

MySQL hata referansında 1045 kodu, ER_ACCESS_DENIED_ERROR olarak tanımlanır ve kullanıcı ile bağlantının geldiği kaynak için erişimin reddedildiğini belirtir. Bu yüzden sorunun kaynağı PHP kodunun yanlış kullanıcı adı veya parola göndermesi, DSN'nin beklenenden farklı bir sunucuya yönelmesi ya da MySQL hesabının o bağlantı kaynağı için kabul edilmemesi olabilir.

1045 kodu, veritabanıyla ilgili her erişim sorununu ifade etmez. Veritabanına erişimin reddedilmesi 1044, veritabanının bulunamaması 1049, tablo veya komut yetkisinin bulunmaması ise farklı hata kodlarıyla gösterilir. Uygulama bağlantıyı kurduktan sonra bir sorguda hata veriyorsa, 1045 yerine sorgunun kendi hata kodunu ve ilgili veritabanı yetkilerini incelemelisin.

PDO DSN ve kimlik bilgileri nasıl kontrol edilir?

İlk olarak DSN içindeki alanları tek tek kontrol et. mysql: sürücü önekidir. host MySQL sunucusunun adresini, port sunucunun dinlediği bağlantı noktasını, dbname bağlantıdan sonra kullanılacak veritabanını, charset ise istemci bağlantısında kullanılacak karakter kümesini belirtir. Kullanıcı adı ve parola ise DSN metninden ayrı olarak new PDO() çağrısının ikinci ve üçüncü parametrelerinde verilebilir.

Aşağıdaki örnekte kimlik bilgileri ortam değişkenlerinden alınır. Kodun içinde gerçek bir parola bulunmaz:

<?php
$host = getenv('DB_HOST') ?: '127.0.0.1';
$port = getenv('DB_PORT') ?: '3306';
$dbname = getenv('DB_NAME') ?: 'uygulama_db';
$user = getenv('DB_USER') ?: 'uygulama_kullanici';

$password = getenv('DB_PASSWORD');
$password = $password === false ? '' : $password;

$dsn = "mysql:host={$host};port={$port};dbname={$dbname};charset=utf8mb4";

try {
    $pdo = new PDO($dsn, $user, $password, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    ]);

    echo 'Veritabanı bağlantısı kuruldu.';
} catch (PDOException $e) {
    echo 'Bağlantı kurulamadı.';
}
?>

Ortam değişkenleri doğru değerleri taşıdığında beklenen çıktı Veritabanı bağlantısı kuruldu. olur. Bu örnekte özellikle DB_USER veya DB_PASSWORD değişkenlerinin uygulamanın çalıştığı ortamda gerçekten tanımlı olup olmadığını kontrol etmelisin. Değişkenin boş gelmesi, PHP kodunda doğru görünen bir bağlantının MySQL sunucusuna eksik kimlik bilgileri göndermesine neden olabilir.

Parolayı PHP içinde geçici olarak temsil etmen gerekiyorsa, tek tırnaklı dizelerde tek tırnak karakteri ', ters eğik çizgi ise \ biçiminde yazılır:

$temsiliParola = 'tek'tırnak ve ters eğik çizgi: \';

Bu örnek yalnızca PHP dizesinin sözdizimini gösterir. Parolayı DSN metnine yerleştirmek yerine new PDO($dsn, $user, $password, ...) çağrısında ayrı parametre olarak kullan. Böylece DSN, sunucu ve veritabanı bağlantı bilgilerini taşırken kimlik bilgileri ayrı kalır.

localhost ile 127.0.0.1 farkı teşhiste nasıl kullanılır?

localhost ile 127.0.0.1 farkı teşhiste nasıl kullanılır?

1045 hatasında sunucuya ulaşılır, fakat sunucu bağlantıyı kullanıcı bilgilerinin doğrulanamaması veya hesabın bağlantı yaptığı host için yetkilendirilmemesi nedeniyle reddeder. Veritabanı ve tablo işlemlerine ait yetkiler ise bağlantı kurulduktan sonra denetlenen ayrı bir katmandır.

localhost ve 127.0.0.1 yerel makineyi hedefleyebilir, ancak aynı bağlantı yolunu kullanmak zorunda değildir. Unix tabanlı ortamlarda PDO_MYSQL için localhost Unix domain socket kullanımına yönlenebilir. 127.0.0.1 ise yerel IPv4 adresi üzerinden TCP/IP bağlantısını sınamak için tercih edilir. Davranış, işletim sistemi, PDO_MYSQL sürücüsü ve varsayılan ayarlara bağlıdır. PHP PDO_MYSQL DSN belgelerinde host, port ve unix_socket ayrı bağlantı parametreleri olarak tanımlanır.

Diğer değerleri sabit tutarak yalnızca host değerini karşılaştır:

mysql:host=localhost;port=3306;dbname=school_project
mysql:host=127.0.0.1;port=3306;dbname=school_project

Bir seçenek çalışırken diğeri çalışmıyorsa socket, TCP yolu, port veya ulaşılan MySQL sunucusu değişiyor olabilir. Socket bağlantısında port değeri TCP bağlantısındaki gibi kullanılmayabilir. Ayrıca 'php_app'@'localhost' ile 'php_app'@'127.0.0.1' MySQL açısından farklı hesap tanımları olabilir. Bu yüzden host, port ve hesabın host eşleşmesini birlikte kontrol et. Host değerini değiştirmek tek başına evrensel bir çözüm değildir.

Kod, bağlantı ayarı ve kullanıcı yetkisi nasıl sırayla elenir?

Üç katmanı aynı anda değiştirmek yerine aşağıdaki sırayı izle. MySQL bağlantı doğrulama belgeleri, kullanıcı ve host eşleşmesiyle kimlik doğrulamayı, bağlantı sonrasındaki veritabanı yetkilerinden ayrı ele alır.

  1. PHP kodunu ve ortam değişkenlerini denetle: Kodun beklenen değişkenleri gerçekten okuyup okumadığını, parola değerini yazdırmadan kontrol et.
<?php
$keys = ['DB_HOST', 'DB_PORT', 'DB_NAME', 'DB_USER', 'DB_PASSWORD'];

foreach ($keys as $key) {
    $value = getenv($key);
    $hasValue = $value !== false && $value !== '';
    $shown = $key === 'DB_PASSWORD'
        ? ($hasValue ? '[tanımlı]' : '[eksik]')
        : ($hasValue ? $value : '[eksik]');

    echo $key . '=' . $shown . PHP_EOL;
}

Örnek çıktı DB_HOST=127.0.0.1, DB_PORT=3306, DB_NAME=school_project, DB_USER=php_app ve DB_PASSWORD=[tanımlı] şeklinde olabilir. Bir değer eksik ya da beklenenden farklıysa önce kod ve ortam değişkenleri katmanına dön.

  1. DSN değerlerini karşılaştır: host, port, dbname ve charset değerlerini kullandığın MySQL sunucusunun ayarlarıyla karşılaştır. Host değişimi hata sonucunu değiştiriyorsa socket ve TCP ayrımını yeniden incele. Değerler doğru olduğu hâlde hata sürüyorsa üçüncü adıma geç.
  2. Kullanıcı, parola ve hesap erişimini kontrol et: Kullanıcı adının ve parolanın doğru kaynaktan geldiğini, başında veya sonunda görünmeyen boşluk bulunmadığını denetle. Ardından MySQL hesabının bağlantının geldiği host ile eşleştiğini ve ilgili veritabanına gerekli erişime sahip olduğunu uygun yetkisi bulunan veritabanı yöneticisiyle değerlendirin. Bağlantı kuruluyor, ancak sorgu reddediliyorsa sorun kimlik bilgilerinden çok veritabanı veya nesne yetkileri katmanında olabilir. Geniş kapsamlı yetki vermek yerine yalnızca gereken erişimi değerlendirin.

Bu sırayı korumak, 1045 hatasını rastgele parola değiştirerek değil, önce bağlantı yolunu, sonra ayarları ve en son hesap eşleşmesini ayırarak teşhis etmeyi sağlar.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara