İçeriğe geç
CılgınYazılım

Arayüz ve Tablo Başlangıç

PHP PDO Ajax CRUD Örneği

DataTables, Bootstrap 5 ve modal pencerelerle çalışan, satır satır açıklamalı bir CRUD örneği. SQL enjeksiyonu, XSS ve dosya yükleme açıkları baştan kapatılmış.

  • PHP 8
  • PDO
  • MySQL
  • Ajax
  • DataTables
  • Bootstrap 5
php-pdo-ajax-crud/kunye.json
seviye
"Başlangıç"
dosya
36
satir
~27.829
boyut
"2.4 MB"
veritabani
"crud"
lisans
"MIT"
inceleme
155
begeni
2
yayin
""

Ekran görüntüleri 4 görsel

Bu örnek ne yapıyor?

  • Tam CRUD: listeleme, ekleme, düzenleme, silme ve görsel yükleme
  • Sunucu taraflı DataTables ile arama, sıralama ve sayfalama
  • Bootstrap 5 modalları: tek modal hem ekleme hem düzenleme için kullanılıyor
  • Sorgular hazırlanmış ifadelerle (prepared statement) çalışıyor — SQL enjeksiyonu kapalı
  • Çıktı kaçışlama ile XSS, içerikten tür doğrulama ile dosya yükleme açığı kapatılmış
  • Görseli olmayan kayıtlar için adın baş harfinden otomatik rozet üretiliyor
  • Kodun her satırı Türkçe açıklamalı; Composer, npm ve internet bağlantısı gerekmiyor

Nerede işe yarar?

  • PHP, Ajax ve DataTables üçlüsünü sıfırdan öğrenmek
  • Yeni bir projeye hazır ve güvenli bir CRUD iskeletiyle başlamak
  • Müşteri, personel veya ürün listesi gibi klasik yönetim ekranları
  • Var olan bir CRUD kodunu güvenlik açısından karşılaştırmak
  • Bootstrap 5 üzerine kurulu, tekrar kullanılabilir bir tasarım kalıbı edinmek

Gereksinimler

  • PHP 8.0+ (pdo_mysql, gd) · MySQL 5.7+ veya MariaDB 10.3+ · Apache/mod_rewrite

Nasıl kurulur?

  1. Proje dosyalarını web köküne kopyalayın (örn. XAMPP'ta htdocs veya kendi web sunucunuzun kök dizini)
  2. crud.sql dosyasını içe aktarın — tabloyu ve örnek kayıtları oluşturur
  3. system klasöründeki yapılandırma dosyasında veritabanı bilgilerini düzenleyin
  4. upload klasörüne yazma izni verin (kayıt görselleri buraya kaydedilir)
  5. Uygulamayı açın; listeye bir kayıt ekleyip modal üzerinden düzenlemeyi deneyin

Veritabanı şeması projedeki crud.sql dosyasında.

Nasıl çalışıyor?

Bu Proje Nedir?

"PHP CRUD örneği" diye aratınca çıkan sonuçların çoğu aynı üç hataya sahiptir: sorgular $_POST ile birleştirilir, ekrana basılan veri kaçışlanmaz, dosya yükleme uzantıya güvenir. Yeni başlayan biri bu kodu kopyalayıp öğrenir — ve yanlışı da öğrenmiş olur.

Bu proje o kısır döngüyü kırmak için var: aynı CRUD'u, aynı sadelikte, ama gerçekten güvenli yazılmış haliyle gösteriyor. Fark satır sayısında değil, satırların neden öyle yazıldığında. getimagesize() neden explode('.', $name)'den daha güvenli, EMULATE_PREPARES = false ne değiştiriyor, hash_equals() olmadan CSRF token'ı neden kırılabilir — bunların hepsi kod içindeki yorumlarda, olduğu yerde anlatılıyor. Ayrı bir kitap okumanız gerekmiyor; dosyayı açıp okumanız yeterli.

Kimler için uygun?

  • PHP + AJAX + DataTables üçlüsünü doğru öğrenmek isteyenler
  • Kendi projesine hazır ve güvenli bir CRUD iskeleti arayanlar
  • Bootstrap 5 üzerine kurulu, tekrar kullanılabilir bir tasarım kalıbı arayanlar
  • Bir CRUD'un ne kadar mobil dostu, erişilebilir ve bağımlılıksız olabileceğini merak edenler
Klonla, crud.sql'i içe aktar, çalıştır. Başka hiçbir kurulum adımı yok. Composer yok, npm yok, internet bağlantısı bile gerekmiyor — tüm kütüphaneler proje içinde. Hiç kurulum yapmadan denemek isterseniz Canlı Demo bölümüne göz atın.

Bu proje, Çılgın Yazılım Kütüphanesi altında yayınlanan açıklamalı, üretime hazır örneklerden biridir — aynı tasarım kalıbıyla hazırlanmış diğer örnekleri de orada bulabilirsiniz.


Neler Var?

Arayüz

  • Marka gradyanlı başlık ve modallar
  • Üç ayrı modal (detay / form / silme onayı)
  • Sağ üstte toast bildirimleri
  • Görsel canlı önizleme (yüklemeden önce)
  • Görselsiz kayıtlar için baş harf rozeti
  • Otomatik koyu tema (işletim sistemi ayarını izler)
  • Mobil için ayrıca inceltilmiş — dokunma hedefleri ≥40px, tablo yatay kaydırmaya zorlamaz, erişilebilir (ARIA etiketli)
  • Tamamı Türkçe — CDN'siz, çevrimdışı çalışır

Altyapı

  • Sunucu taraflı (server-side) DataTables
  • Tek AJAX uç noktası, action tabanlı yönlendirme
  • Çift katmanlı doğrulama (istemci + sunucu)
  • Alan bazlı hata mesajları (HTTP 422)
  • Otomatik dosya temizliği (yetim dosya bırakmaz)
  • Ortam değişkeni desteği
  • 50 hazır örnek kayıt
  • Kodun her satırı açıklamalı

Güvenlik: Neyi, Nasıl Kapattık?

İnternetteki benzer örneklerin çoğunda bulunan açıklar ve bu projede nasıl önlendikleri:

AçıkTipik hatalı kodBu projede
SQL Injection"SELECT FROM users WHERE id = '".$_POST['id']."'"Tüm sorgular prepared statement. EMULATE_PREPARES = false ile gerçek prepared statement zorunlu. Sıralama sütunu/yönü beyaz listeden geçer — order[0][column]=0;DROP TABLE users-- denemesi test edildi, etkisiz.
XSS$sub_array[] = $row["name"];Veritabanından gelen her değer e() (htmlspecialchars) ile kaçışlanır. Toast mesajları .text() ile yazılır, .html() ile değil.
CSRF(genelde hiç yok)Oturuma bağlı 32 baytlık token. ` etiketinden okunup her AJAX isteğine eklenir, hash_equals() ile sabit zamanlı doğrulanır. Token'sız istek → HTTP 419.
Kötü amaçlı dosya yükleme$ext = explode('.', $name)[1];Uzantıya güvenilmez: tür getimagesize() ile dosya içeriğinden tespit edilir. Yeni ad random_bytes() ile üretilir, uzantı MIME beyaz listesinden atanır. shell.php.png yükleme denemesi test edildi, reddedildi.
Yükleme klasöründe kod çalıştırma(korumasız klasör)*upload/.htaccess PHP motorunu kapatır ve çalıştırılabilir uzantılara erişimi engeller.
Path Traversalunlink("../upload/".$_POST['hidden_image'])Silinecek dosya adı istemciden değil veritabanından okunur, ayrıca basename() ile temizlenir.
Tip karmaşasıWHERE id = '$id'ID'ler filter_input(..., FILTER_VALIDATE_INT) ile doğrulanır.
Bilgi sızıntısıEkrana basılan MySQL hatalarıAPP_DEBUG = false iken hata detayı gizlenir, error_log()'a yazılır.
LIKE joker karakterleriLIKE '%$search%'Arama terimindeki %, _, \ kaçışlanır — kullanıcı % yazınca tüm tablo dönmez.
Kaynak tüketimiLIMIT $lengthSayfa boyutu 500 ile sınırlanır; length=999999` sunucuyu yormaz.

Yapılandırma

Tüm ayarlar system/config.php içinde, açıklamalarıyla birlikte:

SabitVarsayılanAçıklama
DB_HOST127.0.0.1Veritabanı sunucusu
DB_NAMEcrudVeritabanı adı
DB_USERrootKullanıcı adı
DB_PASS(boş)Parola
UPLOAD_MAX_BYTES2 MBMaksimum görsel boyutu
ALLOWED_IMAGE_TYPESjpg, png, gif, webpİzin verilen MIME türleri
NAME_MIN_LENGTH / NAME_MAX_LENGTH2 / 150Ad-soyad uzunluk sınırları
APP_DEBUGtrueCanlıda false yapın

Şifreyi koda yazmayın

Tüm DB_* sabitleri ortam değişkeniyle geçersiz kılınabilir. Böylece şifreniz GitHub'a düşmez:

# Linux / macOS
export DB_HOST=localhost DB_USER=uygulama DB_PASS='••••••••'

# Windows (PowerShell)
$env:DB_USER = "uygulama"; $env:DB_PASS = "••••••••"

Apache için .htaccess ya da httpd.conf içinde: SetEnv DB_PASS "guclu-sifre"


Çılgın Yazılım Tasarım Kalıbı

assets/css/cilginyazilim.css dosyası, bu projeye değil markaya aittir. Diğer örnek projelerde de aynı görsel dili kullanabilmek için ayrı bir dosya olarak tutulur.

Başka bir projede kullanmak

<!-- 1) Bootstrap'ten SONRA ekleyin -->
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/cilginyazilim.css">

<!-- 2) body'ye tema sınıfını verin -->
<body class="cy-app">

Hazır bileşenler

SınıfNe işe yarar
.cy-card / .cy-card__header / .cy-card__body / .cy-card__footerGradyan başlıklı ana kart
.cy-brand / .cy-brand__markLogo kutusu + başlık bloğu
.cy-btn + .cy-btn--primary \--onbrandMarka butonları
.cy-btn-icon + --view \--edit \--deleteTablo içi ikon butonları
.cy-tableMarka görünümlü tablo
.cy-avatar / .cy-avatar--initial / .cy-avatar--lgProfil görseli ve baş harf rozeti
.cy-badge + --glass \--softRozetler
.cy-modalGradyan başlıklı modal
.cy-detailEtiket/değer listesi (detay modalı)
.cy-toast + --success \--danger \--infoBildirim balonları

Renkleri değiştirmek

Tüm bileşenler CSS değişkenlerinden beslenir. Tek yeri değiştirmek yeter:

:root {
    --cy-brand-900: #061321;   /* Logodaki en koyu lacivert */
    --cy-brand-600: #0b5cb5;   /* Ana marka mavisi          */
    --cy-accent:    #0ea5e9;   /* Vurgu rengi               */
    --cy-gradient:  linear-gradient(135deg, #061321, #0b5cb5 45%, #0284c7);
}
Renk paleti cilginyazilim.com logosundan türetilmiştir: koyu lacivertten canlı maviye uzanan geçiş. Logo assets/images/logo.png içinde yer alır ve başlıkta beyaz yuvarlak bir zemine oturtulur.

Koyu tema

Kullanıcının işletim sistemi koyu temadaysa otomatik devreye girer. Zorlamak isterseniz:

<html data-cy-theme="dark">   <!-- veya "light" -->

Dosya Yapısı

.
├── index.php                      # Arayüz + tüm JavaScript mantığı
├── .env.example                   # Veritabanı bilgileri (isteğe bağlı) — .gitignore içinde
├── crud.sql                       # Veritabanı şeması + 50 örnek kayıt
├── README.md                      # Türkçe belgelendirme
├── README.en.md                   # İngilizce belgelendirme
├── LICENSE                        # MIT lisansı
├── .gitignore
│
├── docs/
│   └── screenshots/               # README'de kullanılan ekran görüntüleri
│
├── system/
│   ├── config.php                 # Ayarlar, oturum, PDO bağlantısı
│   ├── function.php               # Yardımcı fonksiyonlar
│   └── ajax.php                   # AJAX uç noktası / CRUD yönlendiricisi
│
├── assets/
│   ├── css/
│   │   ├── bootstrap.min.css
│   │   ├── dataTables.bootstrap5.min.css
│   │   ├── cilginyazilim.css      # ★ MARKA TASARIM KALIBI
│   │   └── style.css              # Sadece bu sayfaya özel eklemeler
│   └── js/
│       ├── jquery-3.7.0.js
│       ├── bootstrap.bundle.js
│       ├── jquery.dataTables.min.js
│       └── dataTables.bootstrap5.min.js
│
└── upload/
    ├── .htaccess                  # Klasörde kod çalıştırmayı engeller
    └── *.png                      # Örnek görseller

Yükleme sırası önemlidir:

CSS:  bootstrap → dataTables → cilginyazilim → style
JS:   jQuery → bootstrap.bundle → dataTables → dataTables.bootstrap5

Sıra bozulursa $ is not defined gibi hatalar alırsınız.


Nasıl Çalışıyor?

┌─────────────────────────────────────────────────────────────────────┐
│  TARAYICI  (index.php)                                              │
│                                                                      │
│  DataTables ──┐                                                      │
│  Form gönder ─┤                                                      │
│  Detay butonu ┼──► jQuery AJAX ──► POST { action, csrf_token, ... }  │
│  Sil butonu ──┘                              │                       │
└──────────────────────────────────────────────┼───────────────────────┘
                                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│  SUNUCU  (system/ajax.php)                                          │
│                                                                      │
│   1. POST mu?              → değilse 405                            │
│   2. require_csrf()        → geçersizse 419                         │
│   3. action'a göre dağıt:  list │ add │ edit │ fetch │ delete       │
│   4. validate_name()       → hatalıysa 422 + errors                 │
│   5. upload_image()        → içerikten tür doğrulama                │
│   6. PDO prepared query    → MySQL                                  │
│   7. json_response()       → tek noktadan JSON çıkışı               │
│                                                                      │
│   Tüm bunlar try/catch içinde: hiçbir hata çıplak PHP mesajı olarak │
│   sızmaz, hepsi düzgün JSON'a çevrilir.                             │
└─────────────────────────────────────────────────────────────────────┘

Sorumluluk dağılımı

DosyaGörevi
index.phpSadece sunum. CSRF token üretir, DataTables'ı kurar, modalları ve toast'ları yönetir. Veritabanına dokunmaz.
system/ajax.phpYönlendirici. action değerine göre işleyicilere dağıtır. Tüm güvenlik kontrolleri ve hata yakalama burada tek noktada.
system/function.phpSaf yardımcı fonksiyonlar. Veritabanına ihtiyaç duyanlar PDO'yu parametre olarak alır — her çağrıda yeni bağlantı açılmaz.
system/config.phpOturum, sabitler ve tek bir PDO örneği.

Öğrenirken dikkat çeken noktalar

Kod içindeki yorumlarda ayrıntısıyla anlatılan, yeni başlayanların sık takıldığı konular:

  • serverSide: true ne demek? — 50 kayıtta fark etmez ama 100.000 kayıtta tarayıcıya tüm veriyi göndermemenizi sağlar.
  • Event delegation — AJAX ile sonradan gelen butonlara neden $('.js-edit').click() çalışmaz, $('#user_data').on('click', '.js-edit', ...) neden çalışır.
  • EMULATE_PREPARES = false tuzağı — aynı isimli yer tutucu (:search) neden iki kez kullanılamaz, Invalid parameter number hatası nereden gelir.
  • contentType: false, processData: false — dosya yüklerken bu ikisi neden zorunlu.
  • Sütun adı neden bind edilemez — ve bu yüzden neden beyaz liste şart.

AJAX API Referansı

Tüm istekler POST ile system/ajax.php adresine yapılır ve geçerli bir csrf_token içermelidir. Yanıtlar application/json türündedir.

action=list — DataTables listeleme

İstek: draw, start, length, search[value], order[0][column], order[0][dir]

Yanıt:

{
  "draw": 1,
  "recordsTotal": 50,
  "recordsFiltered": 50,
  "data": [[50, "<img …>", "Ozan", "TOPAL", "<span…>23.02.2025 23:28</span>", "<div class=\"cy-actions\">…</div>"]]
}

Sıralanabilir sütunlar beyaz listeyle sınırlıdır: 0 → id, 2 → name, 3 → surname, 4 → tarih.
Foto (1) ve İşlemler (5) sütunları veritabanı sütunu olmadıkları için sıralanamaz.

action=add — Yeni kayıt

İstek: name, surname, image_user (opsiyonel, multipart/form-data)

Başarılı (200):

{ "success": true, "type": "success", "description": "Kayıt başarıyla eklendi.", "id": 51 }

Doğrulama hatası (422):
{
  "success": false,
  "type": "danger",
  "description": "Lütfen formdaki hataları düzeltin.",
  "errors": { "name": "Ad alanı boş bırakılamaz." }
}

errors nesnesinin anahtarları form alanlarının id'leriyle birebir aynıdır; JavaScript mesajı doğrudan ilgili alanın altına yazar.

action=edit — Güncelleme

İstek: user_id, name, surname, image_user (opsiyonel)

Yeni görsel gönderilmezse mevcut görsel korunur. Gönderilirse yenisi kaydedilir ve eski dosya diskten silinir.

action=fetch — Tek kayıt (detay + düzenleme)

İstek: id

{
  "success": true,
  "id": 1,
  "name": "Evren",
  "surname": "ÇILGIN",
  "image": "2090273627.png",
  "image_url": "upload/2090273627.png",
  "tarih": "06.01.2025 19:34"
}

Hazır HTML değil ham veri döner; ekranı JavaScript .text() ile doldurduğu için XSS riski oluşmaz.

action=delete — Silme

İstek: id

Kayıt ve ilişkili görsel dosyası birlikte silinir. Kayıt yoksa 404 döner.

HTTP durum kodları

KodAnlamı
200İşlem başarılı
400Geçersiz parametre (örn. hatalı ID)
404Kayıt bulunamadı
405POST dışı istek
419CSRF token geçersiz veya oturum düşmüş
422Form doğrulama hatası (errors alanı döner)
500Sunucu / veritabanı hatası

Veritabanı Şeması

CREATE TABLE `users` (
  `id`      INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name`    VARCHAR(150) NOT NULL,
  `surname` VARCHAR(150) NOT NULL,
  `image`   VARCHAR(191) NOT NULL DEFAULT '',   -- sadece dosya adı, tam yol değil
  `tarih`   TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_users_name`    (`name`),             -- arama ve sıralama için
  KEY `idx_users_surname` (`surname`),
  KEY `idx_users_tarih`   (`tarih`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
KararNeden
InnoDB (MyISAM değil)Transaction ve foreign key desteği, satır bazlı kilitleme
utf8mb4 (utf8mb3 değil)Türkçe karakterler + emoji; eski utf8 bazı karakterleri saklayamaz
İndekslerArama/sıralama yapılan sütunlar; tablo büyüdükçe fark katlanarak açılır
Sadece dosya adıKlasör yapısı değişirse veritabanına dokunmak gerekmez

Mevcut (eski) bir kurulumu veri kaybetmeden yükseltmek için crud.sql dosyasının sonundaki ALTER TABLE komutlarını kullanın.


Sık Sorulanlar

Bu kodu kendi projemde kullanabilir miyim?

Evet. MIT lisanslı — ticari projeler dahil serbestçe kullanabilir, değiştirebilir, dağıtabilirsiniz. Atıf zorunlu değil ama sevindirir.

Tabloya yeni bir sütun eklemek istiyorum, nereleri değiştirmeliyim?

Örnek: email sütunu eklemek için beş nokta:

  1. crud.sql → tabloya sütunu ekleyin
  2. index.php → forma input, `'e ekleyin
  3. system/function.php → find_user() içindeki SELECT listesine ekleyin
  4. system/ajax.php → handle_save() içinde doğrulama + INSERT/UPDATE, handle_list() içinde $data[] dizisine yeni hücre
  5. system/ajax.php → sütun eklediyseniz $sortableColumns` indekslerini kaydırmayı unutmayın

` sayısı ile $data[]` dizisinin uzunluğu aynı olmak zorundadır, aksi halde DataTables hata verir.

Görsel boyutu sınırını nasıl artırırım?

system/config.php içinde UPLOAD_MAX_BYTES değerini değiştirin. Ayrıca php.ini içindeki upload_max_filesize ve post_max_size değerlerini de artırın — PHP'nin limiti sizinkinden düşükse dosya sunucuya hiç ulaşmaz.

Neden hem istemcide hem sunucuda doğrulama var?

İstemci doğrulaması kullanıcı deneyimi içindir: kullanıcı sunucuya gitmeden anında geri bildirim alır. Ama JavaScript kapatılabilir veya istek doğrudan curl ile atılabilir. Bu yüzden gerçek koruma her zaman sunucudadır. İkisi birlikte kullanılır.

DataTables'ın serverSide: true ayarını kapatabilir miyim?

Kapatabilirsiniz ama o zaman tüm kayıtlar tek seferde tarayıcıya gönderilir. 50 kayıtta sorun olmaz; 50.000 kayıtta sayfa donar. Bu örnekte gerçek dünya senaryosunu göstermek için açık bırakıldı.

Bootstrap 5 sürümünü güncelleyebilir miyim?

Evet, assets/ altındaki dosyaları değiştirmeniz yeterli. Tasarım kalıbı Bootstrap'in üzerine ekleme yapar, onu değiştirmez — bu yüzden sürüm yükseltmeleri sorunsuz geçer.


Canlı Ortama Alırken

  • [ ] APP_DEBUG değerini false yapın
  • [ ] Veritabanı için root yerine sınırlı yetkili bir kullanıcı oluşturun
  • [ ] Kimlik bilgilerini ortam değişkeni olarak tanımlayın, koda gömmeyin
  • [ ] HTTPS kullanın; session.cookie_secure = 1 ve session.cookie_httponly = 1 ayarlayın
  • [ ] Nginx kullanıyorsanız .htaccess çalışmaz — yükleme klasöründe PHP'yi sunucu yapılandırmasından kapatın:

```nginx
location ^~ /upload/ {
location ~ \.php$ { deny all; }
}
```

  • [ ] upload/ klasörünü düzenli yedekleyin
  • [ ] Giriş sistemi ekleyin — bu örnekte kimlik doğrulama yoktur, herkes tüm kayıtları düzenleyebilir

Sorun Giderme

BelirtiÇözüm
"Veritabanına bağlanılamadı"MySQL çalışmıyor veya DB_* bilgileri hatalı. XAMPP panelinden MySQL'i başlatın.
Tablo boş, "Yükleniyor…" takılıTarayıcı konsolunu (F12) açın. Genelde system/ajax.php bir PHP hatası döndürüyordur; APP_DEBUG = true yapıp Network sekmesinden yanıtı okuyun.
HTTP 419 hatasıOturum düşmüş — sayfayı yenileyin. Sunucuda session.save_path yazılabilir olmalıdır.
Invalid parameter numberAynı isimli yer tutucuyu bir sorguda iki kez kullanmışsınız. EMULATE_PREPARES = false iken buna izin verilmez; farklı isimler verin.
$ is not definedJavaScript yükleme sırası bozulmuş. jQuery her zaman en başta gelmelidir.
"Görsel kaydedilemedi"upload/ klasörü yok veya yazma izni yok → chmod 755 upload
Türkçe karakterler bozukVeritabanı utf8mb4 değil. crud.sql sonundaki CONVERT TO CHARACTER SET utf8mb4 komutunu çalıştırın.
Büyük dosya yüklenmiyorphp.ini içindeki upload_max_filesize ve post_max_size değerlerini artırın.
DataTables "Requested unknown parameter"`` sayısı ile sunucudan dönen dizi uzunluğu farklı. İkisini eşitleyin.

Yol Haritası

  • [ ] Kullanıcı girişi ve rol tabanlı yetkilendirme
  • [ ] Toplu silme (checkbox ile çoklu seçim)
  • [ ] Excel / CSV / PDF dışa aktarma (DataTables Buttons)
  • [ ] Sunucu tarafında görsel yeniden boyutlandırma ve thumbnail
  • [ ] REST API katmanı (JWT ile)
  • [ ] Soft delete + işlem geçmişi (audit log)
  • [ ] PHPUnit ile birim testleri
  • [ ] Koyu tema için elle açma/kapama düğmesi

Katkı

Bu proje herkese açıktır — dilediğiniz geliştirmeyle katkı sağlayabilirsiniz.

📦 Depo: github.com/CilginYazilim/php-pdo-ajax-crud

Nasıl katkı sağlarım?Nereden
🐛 Hata bildirIssues
💡 Özellik önerIssues
🔧 Kod gönderPull Requests
❓ Soru sorDiscussions

Pull request adımları

# 1) Depoyu çatallayın (GitHub'da "Fork" butonu), sonra kendi kopyanızı indirin
git clone https://github.com/KULLANICI-ADINIZ/php-pdo-ajax-crud.git
cd php-pdo-ajax-crud

# 2) Değişikliğiniz için yeni bir dal açın
git checkout -b ozellik/yeni-ozellik

# 3) Kodunuzu yazın, sonra kaydedin
git add .
git commit -m "Yeni özellik: kısa ve açıklayıcı bir başlık"

# 4) Kendi çatalınıza gönderin
git push origin ozellik/yeni-ozellik

# 5) GitHub'da "Compare & pull request" butonuna tıklayın

Katkı ölçütleri

  • Kod açıklamalı olsun. Bu projenin temel amacı öğretmek; yorumsuz kod PR'ı geri döner.
  • Güvenlik kontrollerini atlamayın. Prepared statement, e() ile kaçışlama ve require_csrf() her yeni işlemde de olmalı.
  • Tasarım değişikliklerini cilginyazilim.css üzerinden yapın, satır içi style="..." kullanmayın.
  • Sütun eklerken ` sayısı ile $data[]` uzunluğunu eşitlemeyi unutmayın.
  • Yeni bir dış kütüphane eklemeden önce issue açıp tartışalım — proje bilinçli olarak bağımlılıksızdır.

Lisans

MIT — ticari kullanım dahil serbesttir.

Önce bir deneyin

&nbsp;

cilginyazilim.com tarafından ❤ ile geliştirildi

Faydalı bulduysanız ⭐ vermeyi unutmayın.

Kaynak kod ağaçtan bir dosya seçin

php-pdo-ajax-crud
Dosya seçilmedi

İncelemek istediğiniz dosyayı ağaçtan seçin.

Güvenlik gereği kaynak dosyalardaki parola, API anahtarı ve benzeri gizli değerler gösterilmeden önce maskelenir (••••••••).

Sık sorulan sorular

SQL enjeksiyonu bu örnekte nasıl engelleniyor?

Kullanıcıdan gelen hiçbir değer sorgu metnine yazılmaz. Tüm sorgular PDO'nun hazırlanmış ifadeleriyle çalışır: sorgunun yapısı önce veritabanına gönderilir, değerler ayrı parametre olarak bağlanır. Böylece bir değerin içindeki tırnak ya da SQL anahtar kelimesi sorgunun anlamını değiştiremez.

XSS için ne yapılıyor?

Veritabanından gelen her metin ekrana basılmadan önce kaçışlanır (htmlspecialchars). Böylece bir kaydın içine yazılmış HTML ya da betik, sayfada çalışacak kod olarak değil düz metin olarak görünür. Kaçışlama girişte değil çıkışta yapılır; veriyi bozmadan doğru katmanda çözmenin yolu budur.

Kurulum için Composer ya da npm gerekiyor mu?

Hayır. Klonlayın, crud.sql dosyasını içe aktarın, çalıştırın. Başka hiçbir kurulum adımı yoktur; Composer, npm ve hatta internet bağlantısı bile gerekmez, çünkü tüm kütüphaneler proje içinde durur. Paylaşımlı hostinglerde de doğrudan çalışır.

Yüklenen görseller güvenli mi?

Yüklenen dosyanın türü, tarayıcının gönderdiği başlığa değil dosyanın gerçek içeriğine bakılarak doğrulanır ve yalnızca izin verilen görsel türleri kabul edilir. Dosya adı yeniden üretilir, böylece kullanıcının verdiği ad diske yazılan adı belirlemez. Daha derin bir savunma isterseniz kütüphanedeki güvenli dosya yükleme örneği on iki katmanlı sürümü anlatır.

Bu örnek üzerine kendi projemi kurabilir miyim?

Evet, MIT lisanslıdır ve tam olarak bunun için hazırlanmıştır. Tablo adını ve alanları kendi verinize göre değiştirip aynı kalıbı sürdürebilirsiniz: sunucu taraflı liste, modal form, Ajax uçları ve doğrulama akışı aynen kalır. Canlıya alırken hata gösterimini kapatmayı unutmayın.

Bu örneğin daha gelişmişi projenizde mi lazım?

İhtiyacınızı anlatın; bu yapıyı sizin sisteminize uyarlayalım ya da size özel geliştirelim.

Projenizi Anlatın

Yorumlar

1 konuşma
Aytek
DataTables'ı ilk defa kullanıyorum, burada tam olarak ne işe yarıyor?

Soru sorun veya yorum yazın

Yorumunuz onaylandıktan sonra yayınlanır. Teknik sorularınıza ekibimiz yanıt verir.

Yayınlanmaz; yalnızca gerektiğinde size ulaşmak için.

En az 10 karakter.

İlgili kod örnekleri

Orta

arayuz-ve-tablo/surukle-birak-gorev-panosu

Sürükle-Bırak Görev Panosu

  • PHP 8
  • PDO
  • MySQL
  • Ajax
  • +2

167 inceleme 55 canlı açılış 1 beğeni 2 yorum

Tüm kod örnekleri