Karakter Sorunlarını Çözmek İçin Özel PHP SQL Yönetim Aracı Kodlama
Veritabanı yönetimi söz konusu olduğunda phpMyAdmin yıllardır sektör standardı olarak kullanılmaktadır. Ancak, özellikle utf8mb4 karakter seti geçişlerinde, emoji kayıtlarında (Örn: #1366 Incorrect string value hatası) veya karmaşık SQL yığınlarını içe aktarırken phpMyAdmin'in kendi iç konfigürasyonları sürece müdahale edebilir. Siz veritabanınızı ve tablolarınızı kusursuz bir şekilde utf8mb4 olarak ayarlasanız bile, aracı programın bağlantı protokolü veriyi bozabilir. Bu tür durumlarda sorunun kaynağını tam olarak izole etmek için kendi yazacağımız saf ve hafif bir PHP betiğini kullanmak en güvenilir (bypass) yöntemdir.
Bu makalede, sisteminizde hali hazırda bulunan config.php dosyasındaki veritabanı değişkenlerini otomatik olarak içeri alan, dışarıdan erişimi engellemek için şifre ile korunan ve sonuçları modern bir arayüzle sunan kendi mini veritabanı yönetim aracımızı adım adım kodlayacağız.
Eğer bu adımları güvenli bir ortamda test edecek bir veritabanınız yoksa, MySQLHost.com.tr üzerinden kredi kartı gerektirmeden saniyeler içinde 500 MB ücretsiz uzak bağlantılı (Remote SQL) MySQL veritabanınızı oluşturabilirsiniz.
Ücretsiz MySQL Veritabanınızı Oluşturun ve Testlere Hemen Başlayın
1. Kendi SQL Aracımızı Neden Kullanmalıyız?
Geliştiricilerin kendi SQL yürütme (execution) betiklerini yazmalarının başlıca sebepleri şunlardır:
- Sıfır Aracı (Zero Middleware): Veriniz, tarayıcınızdan doğrudan kendi PHP sunucunuza ve oradan direkt veritabanınıza gider. Arada ekstra bir yazılım katmanı olmadığı için verinin yapısı (encoding) korunur.
- Doğrudan Ortam Testi: Sitenizin kök dizinindeki
config.phpdosyasını dahil ettiğimiz için, yazdığınız bu araç web sitenizin PHP ortamıyla %100 aynı şartlarda çalışır. Böylece sitedeki bir sorunun koddan mı yoksa sunucudan mı kaynaklandığını anında tespit edersiniz. - Hız ve Performans: Yüzlerce megabaytlık büyük SQL dosyalarını (dump) yüklerken veya ağır sorgular çalıştırırken phpMyAdmin sıklıkla zaman aşımına (timeout) uğrar. Kendi aracınızda bu limitlere takılmazsınız.
2. Güvenlik ve Mimari Yaklaşım
Bu aracı sunucumuzda barındıracağımız için güvenlik en büyük önceliğimizdir. Herhangi bir veritabanı yetkilendirmesi gerektirmeden, aracın en üstüne sadece bizim bildiğimiz statik bir şifre tanımlayacağız. Kullanıcı oturumları (Session) kullanarak, doğru şifre girilmeden hiç kimsenin SQL ekranını görmemesini sağlayacağız.
Kullanıcı arayüzünü temiz ve okunaklı tutmak için de modern ve hafif bir yapı olan Bootstrap 5 kütüphanesini dışarıdan (CDN ile) projeye dahil edeceğiz.
3. PHP PDO Bağlantı Mantığının Kurulması
Sistemin kalbini PDO bağlantımız oluşturuyor. Ana sisteminizin kök dizininde bulunan ve $db_host, $db_name, $db_user, $db_pass değişkenlerini barındıran config dosyanızı araca çektikten sonra, bağlantıyı doğrudan utf8mb4 zorlamasıyla başlatıyoruz. Aşağıdaki kod dizesi bu işin kilit noktasıdır:
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass);
4. Özel SQL Yürütücü (Executor) Aracının Tam Kodları
Aşağıdaki tüm kodları kopyalayın, sunucunuzun kök dizininde (config.php ile aynı dizinde) örneğin sql_arac.php adında yeni bir dosya oluşturup içine yapıştırın. Belirlediğimiz statik giriş şifresi 102030Xx-- olarak ayarlanmıştır.
<?php
session_start();
/**
* ÖZEL SQL YÖNETİM VE HATA AYIKLAMA ARACI
* Bu araç phpMyAdmin'i devre dışı bırakarak doğrudan veritabanı ile konuşmanızı sağlar.
*/
// 1. GÜVENLİK BÖLÜMÜ - Giriş Şifrenizi Buradan Değiştirebilirsiniz
$arac_sifresi = '102030Xx--';
// Şifre kontrol işlemi
if (isset($_POST['login_pass'])) {
if ($_POST['login_pass'] === $arac_sifresi) {
$_SESSION['sql_admin_auth'] = true;
} else {
$login_error = 'Hatalı şifre girdiniz! Lütfen tekrar deneyin.';
}
}
// Çıkış (Logout) işlemi
if (isset($_GET['logout'])) {
session_destroy();
header("Location: " . $_SERVER['PHP_SELF']);
exit;
}
// HTML Başlangıcı ve Bootstrap 5 CDN Entegrasyonu
echo '<!DOCTYPE html><html lang="tr"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1">';
echo '<title>Gelişmiş SQL Yürütücü Aracı</title>';
echo '<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"></head><body class="bg-light">';
// Oturum Açılmamışsa Sadece Şifre Formunu Göster ve Kodu Durdur
if (!isset($_SESSION['sql_admin_auth']) || $_SESSION['sql_admin_auth'] !== true) {
echo '<div class="container mt-5"><div class="row justify-content-center"><div class="col-md-5"><div class="card shadow">';
echo '<div class="card-body p-5"><h4 class="card-title text-center mb-4">Yetkili Girişi</h4>';
if (isset($login_error)) {
echo '<div class="alert alert-danger">' . $login_error . '</div>';
}
echo '<form method="POST"><div class="mb-3"><label class="form-label">Güvenlik Şifresi:</label>';
echo '<input type="password" name="login_pass" class="form-control" placeholder="Şifreyi giriniz..." required></div>';
echo '<button class="btn btn-primary w-100" type="submit">Sisteme Bağlan</button></form>';
echo '</div></div></div></div></div></body></html>';
exit;
}
// 2. VERİTABANI BAĞLANTISI (Config Dahil Etme)
// Aracın bulunduğu dizindeki config.php dosyasını dahil ediyoruz
if (file_exists('config.php')) {
require_once 'config.php';
} else {
die('<div class="container mt-5"><div class="alert alert-danger"><h4>Kritik Hata!</h4>Sistemde <strong>config.php</strong> dosyası bulunamadı. Lütfen bu aracı config.php ile aynı klasöre koyduğunuzdan emin olun.</div></div>');
}
// PDO Bağlantısını başlat
try {
// config.php içerisindeki değişken adlarının standart olduğunu varsayıyoruz
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die('<div class="container mt-5"><div class="alert alert-danger"><h4>Bağlantı Başarısız</h4>Veritabanına ulaşılamıyor. Hata Detayı: ' . $e->getMessage() . '</div></div>');
}
// 3. SQL SORGUSUNU YAKALAMA VE ÇALIŞTIRMA MANTIĞI
$sistem_mesaji = '';
$sorgu_sonuclari = [];
if (isset($_POST['sql_query'])) {
$sql_metni = trim($_POST['sql_query']);
if (!empty($sql_metni)) {
try {
// Girilen sorgu SELECT veya SHOW ile başlıyorsa veri döndürür, fetch etmeliyiz
if (preg_match('/^s*(SELECT|SHOW|EXPLAIN|DESCRIBE)/i', $sql_metni)) {
$stmt = $pdo->query($sql_metni);
$sorgu_sonuclari = $stmt->fetchAll(PDO::FETCH_ASSOC);
$sistem_mesaji = '<div class="alert alert-success">Sorgu başarıyla çalıştırıldı. Sonuç tablosu aşağıdadır.</div>';
}
// INSERT, UPDATE, DELETE veya ALTER sorguları ise doğrudan yürüt
else {
$etkilenen_satir = $pdo->exec($sql_metni);
$sistem_mesaji = '<div class="alert alert-success">İşlem başarılı! Veritabanında <strong>' . $etkilenen_satir . '</strong> adet satır etkilendi.</div>';
}
} catch (PDOException $e) {
$sistem_mesaji = '<div class="alert alert-danger"><strong>SQL Hatası Alındı:</strong><br>' . htmlspecialchars($e->getMessage()) . '</div>';
}
}
}
?>
<!-- 4. KULLANICI ARAYÜZÜ (UI) TASARIMI -->
<div class="container mt-4">
<div class="d-flex justify-content-between align-items-center mb-4 pb-2 border-bottom">
<h2 class="text-primary">Saf PHP - Veritabanı Yürütme Aracı</h2>
<a href="?logout=1" class="btn btn-danger btn-sm">Güvenli Çıkış Yap</a>
</div>
<!-- Bildirim Mesajı Alanı -->
<?= $sistem_mesaji ?>
<!-- SQL Sorgu Formu -->
<div class="card shadow-sm mb-5">
<div class="card-header bg-dark text-white">Yeni SQL Sorgusu Çalıştır</div>
<div class="card-body">
<form method="POST">
<div class="mb-3">
<label class="form-label text-muted">Buraya emojili INSERT komutlarınızı, tablo güncellemelerinizi veya SELECT sorgularınızı yapıştırın. PDO utf8mb4 bağlantısı her türlü karakteri destekler.</label>
<textarea name="sql_query" class="form-control font-monospace" rows="8" placeholder="Örnek: INSERT INTO blog_posts (title, content) VALUES ('Test', 'Emoji 😊');" required></textarea>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-success btn-lg">Sorguyu Çalıştır (Execute)</button>
</div>
</form>
</div>
</div>
<!-- Sorgu Sonuçları Tablosu (Sadece SELECT/SHOW sorgularında render edilir) -->
<?php if (!empty($sorgu_sonuclari)): ?>
<div class="card shadow-sm mb-5">
<div class="card-header bg-primary text-white">Sorgu Sonuçları</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-bordered table-striped table-hover mb-0">
<thead class="table-light">
<tr>
<?php foreach (array_keys($sorgu_sonuclari[0]) as $kolon_adi): ?>
<th><?= htmlspecialchars($kolon_adi) ?></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php foreach ($sorgu_sonuclari as $satir): ?>
<tr>
<?php foreach ($satir as $deger): ?>
<td><?= htmlspecialchars((string)$deger) ?></td>
<?php endforeach; ?>
</tr>
</php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php endif; ?>
</div>
</body>
</html>
5. Güvenlik Uyarıları ve Aracı Kullanma Rehberi
Bu aracı sunucunuza yükledikten sonra tarayıcınızdan siteadiniz.com/sql_arac.php adresine giderek belirlediğiniz (102030Xx--) şifre ile giriş yapabilirsiniz. Çözmek istediğiniz problemi izole etmek için, phpMyAdmin üzerinde hata veren emojili (😊🚀) INSERT sorgularını veya metinleri doğrudan bu ekrandaki metin kutusuna yapıştırarak çalıştırın.
Geliştirdiğimiz bu PDO yapısı veri iletişimi sırasında charset=utf8mb4 zorlamasını native (yerel) seviyede yaptığı için, eğer tablolarınız da utf8mb4 ise #1366 hatası almanız teknik olarak olanaksızdır. Ancak bu aracın olağanüstü yetkilere sahip olduğunu unutmayın. Sorunlarınızı çözdükten ve testlerinizi tamamladıktan sonra bu dosyayı sunucunuzda tutmanız tavsiye edilmez. İşiniz bittiğinde dosyayı silin veya adını kimsenin tahmin edemeyeceği karmaşık bir harf dizisine (Örn: db_kontrol_8f7d6s.php) dönüştürün.
Kendi Altyapınızı Profesyonelce Yönetin: Ücretsiz MySQL Hesabınızı Şimdi Alın!