PHP PDO MySQL Connection Refused: 8 Neden ve Kesin Çözüm

Google News Google News Flipboard Flipboard Sesli oku Yazıyı beğen Favorilere Ekle 0 Yorumlar
Daha fazla

PHP PDO MySQL Connection Refused: 1. Connection Refused Hatası Nedir?

PHP PDO MySQL Connection Refused
PHP PDO MySQL Connection Refused

PHP PDO connection refused hatası, PHP Data Objects (PDO) eklentisinin MySQL veritabanına TCP bağlantısı kuramadığında fırlattığı istisnadır. Tam hata metni genelde şu şekildedir:

SQLSTATE[HY000] [2002] Connection refused
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed
Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002]

Bu hata, sunucunun MySQL portuna (varsayılan 3306) erişemediği anlamına gelir. Ancak “refused” kelimesi, sunucunun erişilemez olmasından farklı bir durumu işaret eder. Refused, hedef portta dinleyen bir servis olduğu ancak bağlantıyı reddettiği anlamına gelir. Bu genellikle iki şeyden kaynaklanır: ya MySQL servisi çalışmıyordur, ya da güvenlik duvarı bağlantıyı engelliyordur.

Connection refused hatası ile connection timed out hatası farklı sorunlardır. Timed out, hedef sunucuya hiç ulaşılamadığını; refused ise ulaşıldığını ancak bağlantı kurulamadığını gösterir. Bu ayrım, sorunu gidermek için doğru yöne bakmanızı sağlar.

2. PHP PDO MySQL Connection Refused Hatasının 8 Nedeni

2. PHP PDO MySQL Connection Refused Hatasının 8 Nedeni
2. PHP PDO MySQL Connection Refused Hatasının 8 Nedeni

Aşağıdaki tablo, bu hatanın saha gözlemlerine dayalı en sık karşılaşılan nedenlerini ve her birinin tipik belirtisini özetliyor. Hangi nedene yakın olduğunuzu tespit edip ilgili bölüme atlayabilirsiniz.

# Neden Tipik Belirti Çözüm Zorluk
1 MySQL servisi çalışmıyor service mysql status → inactive Kolay
2 Yanlış port (3306 dışında) Port 3307, 3308 gibi özel port Kolay
3 Bind-address = 127.0.0.1 Uzak bağlantı reddedilir Orta
4 Firewall (UFW, iptables) Local OK, remote failed Orta
5 Yanlış host (localhost vs 127.0.0.1) Unix socket vs TCP farkı Kolay
6 MySQL kullanıcı yetkisi eksik “Access denied” hatası Kolay
7 Docker / konteyner ağ ayarı localhost yerine service name Zor
8 PHP PDO MySQL eklentisi yüklü değil “could not find driver” hatası Kolay

Şimdi bu nedenlerin her birini ve kesin çözüm yollarını detaylı olarak inceleyelim.

3. MySQL Servisini Kontrol Edin ve Başlatın

Connection refused hatasının birinci ve en yaygın nedeni, MySQL servisinin çalışmamasıdır. Özellikle paylaşımlı hosting’lerde veya yeniden başlatılan sunucularda MySQL servisi durmuş olabilir. Linux tabanlı sistemlerde servis durumunu kontrol etmek için şu komutları kullanın:

# Sistemd
sudo systemctl status mysql
sudo systemctl start mysql
sudo systemctl enable mysql

# SysVinit
sudo service mysql status
sudo service mysql start

# macOS
brew services list
brew services start mysql

Eğer servis başlatıldıktan sonra bağlantı hatası devam ediyorsa, MySQL log dosyalarını inceleyin. Bu nedenle log analizi kritik önem taşır. Genellikle /var/log/mysql/error.log veya /var/log/mysqld.log yolunda bulunur. Log’da “Permission denied”, “port already in use” veya “address already in use” gibi mesajlar varsa, farklı bir sorunla karşı karşıyasınız demektir.

MySQL’in hangi portta dinlediğini kontrol etmek için netstat veya ss komutunu kullanabilirsiniz:

sudo netstat -tlnp | grep mysql
sudo ss -tlnp | grep 3306

Eğer 3306 portu listede yoksa, MySQL farklı bir portta dinliyor olabilir veya hiç başlamamış olabilir. my.cnf dosyasında [mysqld] bölümü altındaki port parametresini kontrol edin.

4. Port Numarasını ve Bağlantı Adresini Doğrulayın

4. Port Numarasını ve Bağlantı Adresini Doğrulayın
4. Port Numarasını ve Bağlantı Adresini Doğrulayın

PHP PDO bağlantı cümleciğinde (DSN) belirttiğiniz port numarası, MySQL’in gerçekten dinlediği port ile eşleşmelidir. Varsayılan port 3306’dır, ancak bazı ortamlarda farklı portlar kullanılır. Örneğin, Docker konteynerlerinde veya birden fazla MySQL instance çalıştırılan sistemlerde port çakışması olabilir.

// Yanlış — port belirtilmemiş
$dsn = "mysql:host=localhost;dbname=ozgurbayram";

// Doğru — port belirtilmiş
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=ozgurbayram;charset=utf8mb4";

try {
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo "Bağlantı hatası: " . $e->getMessage();
}

Burada dikkat edilmesi gereken kritik nokta, localhost ile 127.0.0.1 arasındaki farktır. Localhost Unix socket kullanırken, 127.0.0.1 TCP bağlantısı kurar. Bu nedenle PHP, MySQL ile bağlantı kurarken bazı durumlarda Unix socket yolunu bulamayabilir. Bu durumda host parametresini açıkça 127.0.0.1 yaparak TCP bağlantısına zorlayabilirsiniz.

5. MySQL Bind-Address Ayarını Düzenleyin

MySQL varsayılan olarak yalnızca 127.0.0.1 (localhost) üzerinden gelen bağlantılara izin verir. Eğer uzak bir sunucudan veya Docker konteynerinden bağlanmaya çalışıyorsanız, MySQL’in tüm IP adreslerinden bağlantı kabul etmesi gerekir. Bu ayar my.cnf veya my.ini dosyasında bulunur:

[mysqld]
bind-address = 0.0.0.0
# veya
bind-address = *

Değişiklikten sonra MySQL servisini yeniden başlatın. Ancak burada önemli bir güvenlik uyarısı var: bind-address = 0.0.0.0 yaptığınızda MySQL’iniz tüm ağa açılır. Bu nedenle üretim ortamında mutlaka firewall ile hangi IP’lerin erişebileceğini sınırlandırın.

Eğer sadece belirli IP’lerin bağlanmasını istiyorsanız, MySQL kullanıcısına host kısıtlaması ekleyebilirsiniz:

CREATE USER 'uygulama'@'192.168.1.100' IDENTIFIED BY 'guclu_sifre';
GRANT ALL PRIVILEGES ON uygulama_db.* TO 'uygulama'@'192.168.1.100';
FLUSH PRIVILEGES;

6. Firewall ve SELinux Kurallarını Kontrol Edin

Linux sunucularda UFW, iptables veya firewalld gibi güvenlik duvarları MySQL portunu engelleyebilir. UFW kullanıyorsanız:

# Durum kontrol
sudo ufw status

# MySQL portuna izin ver
sudo ufw allow 3306/tcp
sudo ufw reload

CentOS/RHEL tabanlı sistemlerde firewalld kullanılır:

sudo firewall-cmd --permanent --add-port=3306/tcp
sudo firewall-cmd --reload

SELinux aktifse (özellikle CentOS, RHEL, Fedora’da), MySQL portuna ağ erişimini açıkça izin vermeniz gerekir:

sudo setsebool -P mysql_connect_any 1
sudo semanage port -a -t mysqld_port_t -p tcp 3306

Bu adımları uyguladıktan sonra PHP uygulamanızdan tekrar bağlantı kurmayı deneyin. Eğer hâlâ “connection refused” alıyorsanız, bir sonraki adıma geçin.

7. Docker ve Konteyner Ağ Ayarları

Docker veya Docker Compose kullanan projelerde, PHP konteynerinden MySQL konteynerine bağlanırken connection refused hatası çok yaygındır. Bunun nedeni, konteyner içindeki localhost‘un kendi konteynerini ifade etmesidir. MySQL servisine localhost yerine docker-compose service adı ile bağlanmanız gerekir.

# docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    ports:
      - "8080:80"
    depends_on:
      - db
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root_pass
      MYSQL_DATABASE: uygulama_db
    ports:
      - "3306:3306"

PHP tarafındaki bağlantı:

// Yanlış — localhost, app konteynerine işaret eder
$dsn = "mysql:host=localhost;dbname=uygulama_db";

// Doğru — service adı kullanılmalı
$dsn = "mysql:host=db;port=3306;dbname=uygulama_db;charset=utf8mb4";

Docker bridge ağında konteynerler birbirine service adı ile erişir. Aynı mantık Kubernetes, Docker Swarm ve ECS için de geçerlidir. Konteynerler arası iletişimde host adı olarak service adı kullanmayı alışkanlık haline getirin.

8. PHP PDO MySQL Eklentisinin Yüklü Olduğunu Doğrulayın

Bazen “connection refused” hatasının arkasında, PHP’de PDO MySQL sürücüsünün yüklü olmaması yatar. Bu durumda hata mesajı biraz farklı olur: “could not find driver”. Yine de bazı ortamlarda bu da “connection refused” olarak raporlanır.

php -m | grep -i pdo
# veya
php -m | grep -i mysql

Eğer pdo_mysql listede yoksa, eklentiyi yüklemeniz gerekir:

# Debian/Ubuntu
sudo apt install php-mysql
sudo systemctl restart apache2
# veya
sudo systemctl restart php8.2-fpm

# CentOS/RHEL
sudo yum install php-mysqlnd
sudo systemctl restart httpd

# macOS (Homebrew)
brew install php
# veya php.ini'de extension=pdo_mysql.so aktif et

Yükleme sonrası phpinfo() sayfası oluşturup “pdo_mysql” satırının göründüğünü doğrulayın. Eğer görünmüyorsa, PHP’nin doğru ini dosyasını yüklediğinden emin olun. Birden fazla PHP sürümü kurulu sistemlerde sürüm karışıklığı yaşanabilir.

9. İzleme ve Önleyici Tedbirler

PHP PDO MySQL connection refused hatasını canlı ortamda anında tespit etmek için izleme araçları kritik önem taşır. UptimeRobot veya Hetrixtools gibi servisler, siteniz MySQL’e bağlanamadığında SMS ve e-posta ile uyarı gönderebilir.

Ayrıca PHP tarafında basit bir sağlık kontrolü (health check) endpoint’i oluşturun:

// /health.php
<?php
header('Content-Type: application/json');
try {
    $pdo = new PDO(
        "mysql:host=127.0.0.1;port=3306;dbname=ozgurbayram",
        "db_user",
        "db_pass",
        [PDO::ATTR_TIMEOUT => 3]
    );
    $stmt = $pdo->query("SELECT 1");
    echo json_encode(['status' => 'ok', 'db' => 'reachable']);
} catch (PDOException $e) {
    http_response_code(503);
    echo json_encode(['status' => 'down', 'error' => $e->getMessage()]);
}

Bu endpoint’i UptimeRobot‘a 5 dakikada bir ping attırın. Bağlantı kesildiği anda bildirim alırsınız. WordPress kullanıyorsanız Health Check & Troubleshooting eklentisi de veritabanı bağlantı durumunu arka planda test eder.

Sık Sorulan Sorular

PHP PDO connection refused hatası neden oluşur?

En yaygın neden MySQL servisinin çalışmamasıdır. Bunu yanlış port, bind-address kısıtlaması, firewall engeli veya Docker ağ yapılandırması izler. systemctl status mysql ile servis durumunu kontrol ederek başlayın.

Connection refused ile connection timed out farkı nedir?

Connection refused, hedef portta servis var ancak bağlantıyı kabul etmiyor demektir. Connection timed out ise hedef sunucuya hiç ulaşılamıyor anlamına gelir. Refused hata kodu 2002, timed out ise 2003 olarak raporlanır.

Localhost yerine 127.0.0.1 kullanmak fark yaratır mı?

Evet. Localhost Unix socket kullanır, 127.0.0.1 ise TCP bağlantısı kurar. Bazı PHP kurulumlarında Unix socket yolu yanlış tanımlanmış olabilir. 127.0.0.1 yazarak sorunu bypass edebilirsiniz.

MySQL portu 3306 dışında bir değer olabilir mi?

Evet. Docker konteynerlerinde port çakışmasını önlemek için 3307, 3308 gibi farklı portlar kullanılabilir. my.cnf‘deki port parametresini ve PHP DSN’deki port= değerini kontrol edin.

Docker’da PHP’den MySQL’e bağlanırken hangi host kullanılır?

Docker Compose’da service adı (örn. “db”) kullanılır. Localhost, PHP konteynerinin kendisini ifade eder. K8s, ECS ve Swarm’da da aynı mantık geçerlidir: konteyner DNS adı.

PDO exception loglamayı nasıl yaparım?

Try-catch içinde error_log($e->getMessage()) çağırın. Monolog veya Sentry gibi araçlarla merkezi log toplama da yapabilirsiniz. Her hatayı stack trace ile birlikte kaydedin.

PHP PDO MySQL Connection Refused için SEO kontrol listesi

PHP PDO MySQL Connection Refused konusunu uygularken önce mevcut durumu kontrol edin, küçük bir test yapın ve sonucu canlı ekranda doğrulayın. İlgili rehberler için PHP PDO MySQL Hostinger ve PHP PDO MySQL CMS mimarisi yazılarını inceleyebilirsiniz. Resmi kaynak olarak PHP PDO dokümantasyonu sayfasını da kontrol edin.

Sonuç

PHP PDO MySQL connection refused hatası ilk bakışta korkutucu görünse de, sistematik bir yaklaşımla dakikalar içinde çözülür. Bu rehberde ele aldığımız 8 neden — servis durumu, port, bind-address, firewall, host adı, kullanıcı yetkisi, Docker ağı ve PHP eklentisi — sahada en sık karşılaşılan vakaları kapsar.

Kalıcı çözüm için şu 4 adımı uygulayın:

  • Servis kontrolü: MySQL çalışıyor mu, doğru portta mı dinliyor?
  • DSN doğrulama: PHP bağlantı cümleciğindeki host, port ve charset doğru mu?
  • Ağ izinleri: Firewall ve bind-address ayarları uzak bağlantıya izin veriyor mu?
  • Sağlık kontrolü: Canlı izleme ve health check endpoint’i kurun.

Bu makaleyi faydalı bulduysanız, PHP PDO MySQL bağlantı sorunlarınızı aşağıya yorum olarak bırakın — birlikte çözelim. WordPress’te veritabanı bağlantı hatası yaşıyorsanız, ilgili rehberimize de göz atmanızı öneririm. Paylaşımlı hosting ortamında Hostinger’a PHP PDO projesi yükleme rehberimiz de ilginizi çekebilir.

Yazar Hakkında

Benzer Yazılar

Bir Cevap Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir.

0/30 karakter