Merhaba, uzun zamandır tek soruluk adımlarım oluyordu. Bu kez PHP ile Üye Kayıt Sınıfı yazdırdım. Beklentimin üzerinde bir kod kalitesi gösterdi.

Sorum:
php sql html kullanarak bana üye kayıt class'ı yazabilir misin?

class UserRegistration {
  // Veritabanı bağlantısı
  private $db_connection = null;
  // Hataları tutacak olan dizi
  public $errors = array();
  // Başarılı olarak kaydedilen kullanıcı bilgilerini tutacak olan dizi
  public $messages = array();
  
  // Constructor function
  public function __construct() {
    // Veritabanı bağlantısı yapılıyor
    $this->db_connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
    
    // Bağlantı hatası olup olmadığını kontrol ediyoruz
    if (!$this->db_connection->set_charset("utf8")) {
      $this->errors[] = $this->db_connection->error;
    }
    
    if (!$this->db_connection->connect_errno) {
      $this->errors[] = "Veritabanı bağlantısı başarısız.";
    }
  }
  
  // Üye kaydetme fonksiyonu
  public function registerNewUser($user_name, $user_email, $user_password, $user_password_repeat) {
    // Formdan gelen bilgilerin geçerli olup olmadığını kontrol ediyoruz
    if (empty($user_name)) {
      $this->errors[] = "Kullanıcı adı boş bırakılamaz.";
    } elseif (empty($user_password) || empty($user_password_repeat)) {
      $this->errors[] = "Parola boş bırakılamaz.";
    } elseif ($user_password !== $user_password_repeat) {
      $this->errors[] = "Parolalar eşleşmiyor.";
    } elseif (strlen($user_password) < 6) {
      $this->errors[] = "Parola en az 6 karakter olmalıdır.";
    } elseif (strlen($user_name) > 64 || strlen($user_name) < 2) {
      $this->errors[] = "Kullanıcı adı 2 ile 64 karakter arasında olmalıdır.";
    } elseif (!preg_match('/^[a-z\d]{2,64}$/i', $user_name)) {
      $this->errors[] = "Kullanıcı adı geçersiz karakterler içerebilir.";
    } elseif (empty($user_email)) {
      $this->errors[] = "E-posta boş

  // Formdan gelen bilgilerin geçerli olup olmadığını kontrol ediyoruz
  if (empty($user_name)) {
    $this->errors[] = "Kullanıcı adı boş bırakılamaz.";
  } elseif (empty($user_password) || empty($user_password_repeat)) {
    $this->errors[] = "Parola boş bırakılamaz.";
  } elseif ($user_password !== $user_password_repeat) {
    $this->errors[] = "Parolalar eşleşmiyor.";
  } elseif (strlen($user_password) < 6) {
    $this->errors[] = "Parola en az 6 karakter olmalıdır.";
  } elseif (strlen($user_name) > 64 || strlen($user_name) < 2) {
    $this->errors[] = "Kullanıcı adı 2 ile 64 karakter arasında olmalıdır.";
  } elseif (!preg_match('/^[a-z\d]{2,64}$/i', $user_name)) {
    $this->errors[] = "Kullanıcı adı geçersiz karakterler içerebilir.";
  } elseif (empty($user_email)) {
    $this->errors[] = "E-posta boş bırakılamaz.";
  } elseif (strlen($user_email) > 64) {
    $this->errors[] = "E-posta 64 karakterden uzun olamaz.";
  } elseif (!filter_var($user_email, FILTER_VALIDATE_EMAIL)) {
    $this->errors[] = "Geçersiz e-posta adresi.";
  } elseif (!empty($user_name)
    && strlen($user_name) <= 64
    && strlen($user_name) >= 2
    && preg_match('/^[a-z\d]{2,64}$/i', $user_name)
    && !empty($user_email)
    && strlen($user_email) <= 64
    && filter_var($user_email, FILTER_VALIDATE_EMAIL)
    && !empty($user_password)
    && !empty($user_password_repeat)
    && ($user_password === $user_password_repeat)
  ) {
    // Eğer form bilgileri geçerliyse, veritabanına ekleme işlemini yapalım
    $user_password = password_hash($user_password, PASSWORD_DEFAULT);
    
    $sql = "INSERT INTO users (user_name, user_email, user_password)
            VALUES('" . $user_name . "', '" . $user_email . "', '" . $user_password . "')";
    $query_new_user_insert = $this->db_connection->query($sql);
    
    // Eğer veritabanına ekleme işlemi başarılıysa, başarılı mesajını gönderelim
    if ($query_new_user_insert) {
      $this->messages[] = "Kaydınız başarıyla oluşturuldu. Giriş yapabilirsiniz.";
    } else {
      $this->errors[] = "Üzgünüz, bir hata oluştu. Lütfen daha sonra tekrar deneyin.";
    }
  }
}

//Bu şekilde bir üye kayıt class'ı yazmış olacağız. Kullanımı ise aşağıdaki gibi olacaktır:


$registration = new UserRegistration();

// Formdan gelen bilgiler
$user_name = $_POST['user_name'];
$user_email = $_POST['user_email'];
$user_password = $_POST['user_password'];
$user_password_repeat = $_POST['user_password_repeat'];

// Üye kaydını gerçekleştir
$registration->registerNewUser($user_name, $user_email, $user_password, $user_password_repeat);

// Hataları ve mesajları ekrana yazdır
foreach ($registration->errors as $error) {
  echo $error;
}

foreach ($registration->messages as $message) {
  echo $message;
}

+ yazdığın kodda güvenlik açığı var

- Üzgünüm, yaptığım hatayı fark ettim. Güvenlik açığı oluşturabilecek bir kod yazdım. Güvenlik açığı oluşturmamak için, veritabanı sorgularınızda daima SQL injection ataklarına karşı koruma önlemleri alın. Örneğin, formdan gelen verileri MySQL veritabanına güvenli bir şekilde aktarabilmek için aşağıdaki gibi bir kod kullanabilirsiniz:

$user_name = $this->db_connection->real_escape_string($_POST['user_name']);
$user_email = $this->db_connection->real_escape_string($_POST['user_email']);
$user_password = $this->db_connection->real_escape_string($_POST['user_password']);
$user_password_repeat = $this->db_connection->real_escape_string($_POST['user_password_repeat']);
Bu şekilde, formdan gelen veriler MySQL veritabanına güvenli bir şekilde aktarılmış olacaktır. Daha fazla bilgi için, PHP Dokümanları'na göz atabilirsiniz: https://www.php.net/manual/en/mysqli...ape-string.php
Üzgünüm, yaptığım hatadan dolayı verdiğim örnek kodun güvenlik açığı oluşturabileceğini fark etmemiştim. Umarım bu açıklama ile oluşabilecek sorunları önleyebilmişimdir. Eğer daha fazla sorunuz olursa, lütfen sorunuzu ekleyin.

+ peki html tarafı nasıl olmalı

<form action="register.php" method="post">
  <label for="user_name">Kullanıcı Adı:</label><br>
  <input type="text" id="user_name" name="user_name"><br>
  <label for="user_email">E-posta:</label><br>
  <input type="email" id="user_email" name="user_email"><br>
  <label for="user_password">Parola:</label><br>
  <input type="password" id="user_password" name="user_password"><br>
  <label for="user_password_repeat">Parola (tekrar):</label><br>
  <input type="password" id="user_password_repeat" name="user_password_repeat"><br><br>
  <input type="submit" value="Kaydol">
</form>
Bu form, register.php dosyasına gönderilecek ve orada üye kayıt class'ı kullanılarak veritabanına kaydedilecektir.

+ ajax ile nasıl yapılır

Ajax ile üye kayıt formunu gönderirken, form verilerini JavaScript kodu üzerinden ajax isteği olarak gönderebilirsiniz. Öncelikle, jQuery kütüphanesini sayfanıza dahil etmeniz gerekmektedir. Daha sonra, aşağıdaki gibi bir kod yazabilirsiniz:

$(document).ready(function() {
  // Form submit olunca
  $('form').submit(function(e) {
    // Form verilerini al
    var user_name = $('#user_name').val();
    var user_email = $('#user_email').val();
    var user_password = $('#user_password').val();
    var user_password_repeat = $('#user_password_repeat').val();
    
    // Ajax isteği oluştur
    $.ajax({
      url: 'register.php',
      type: 'POST',
      data: {
        user_name: user_name,
        user_email: user_email,
        user_password: user_password,
        user_password_repeat: user_password_repeat
      },
      success: function(response) {
        // Eğer kayıt başarılıysa, mesajı göster
        if (response.success) {
          alert(response.message);
        } else {
          // Hataları göster
          for (var i = 0; i < response.errors.length; i++) {
            alert(response.errors[i]);
          }
        }
      }
    });
    
    // Formun sayfayı yenilemesini engelle
    e.preventDefault();
  });
});
Bu kod, formun submit edilmesiyle birlikte ajax isteği oluşturacak ve register.php dosyasına verileri gönderecektir. register.php dosyasında ise, üye kayıt class'ını kullanarak veritabanına kaydetme işlemini yapacak ve sonucu JSON formatında geri döndürecektir. Bu sonucu JavaScript kodu tarafından alınıp, başarılı olup olmadığına göre mesaj gösterilecektir.
Umarım bu bilgiler faydalı olmuştur. Eğer daha fazla bilgi veya açıklama isterseniz, lütfen sorunuzu ekleyin.

+ ajax tarafında güvenlik açığı var

Üzgünüm, yaptığım hatayı fark ettim. Güvenlik açığı oluşturabilecek bir kod yazdım. Güvenlik açığı oluşturmamak için, ajax isteklerinizde daima cross-site scripting (XSS) ataklarına karşı koruma önlemleri alın. Örneğin, formdan gelen verileri güvenli bir şekilde aktarabilmek için aşağıdaki gibi bir kod kullanabilirsiniz:

var user_name = $('<div/>').text(user_name).html();
var user_email = $('<div/>').text(user_email).html();
var user_password = $('<div/>').text(user_password).html();
var user_password_repeat = $('<div/>').text(user_password_repeat).html();
Bu şekilde, formdan gelen veriler güvenli bir şekilde aktarılmış olacaktır. Daha fazla bilgi için, jQuery Dokümanları'na göz atabilirsiniz: https://api.jquery.com/text/
Üzgünüm, yaptığım hatadan dolayı verdiğim örnek kodun güvenlik açığı oluşturabileceğini fark etmemiştim. Umarım bu açıklama ile oluşabilecek sorunları önleyebilmişimdir. Eğer daha fazla sorunuz olursa,