• 26-07-2023, 01:00:31
    #1
    Anti-Multi File Upload System Nedir?
    Kullanıcılarınızın aynı resim dosyalarını tekrar, tekrar yüklemelerini engelleyip bir nebzede olsa sunucu yükünü hafifletmeyi amaçlar.
    Aşağıda kodlar verilmiştir, geliştirilmeye açık bir projedir, ben yolu gösterdim gerisi size kalmış.

    Lütfen dikkat!
    Bu bir ticari konu olmadığı gibi sizde benim herhangi bir profesyonel coder olduğumu düşündürtmesin. Ben PHP acemisi olduğumu her konuda belirtiyorum. Bu yüzden yorum yaparken bilhassa bunu göz önünde bulundurarak yapınız. (Ülkemiz de ne yazık ki eleştiri kültürü absürt olduğu için bu uyarı yapmak zorunda kalıyorum.)


    https://youtu.be/g0YOqNUomxM



    <!DOCTYPE html>
    <html>
    <head>
        <title>Kullanıcı Avatar Sistemi ^^ By OfelyaCoding </title>
    </head>
    <body>
        <?php
      require_once "db_connect.php";
    session_start();
    
    if (!isset($_SESSION["user_id"]) || empty($_SESSION["user_id"])) {
        header("Location: login.php");
        exit();
    }
    $userID = $_SESSION["user_id"];
           
    
        try {
            // PDO bağlantısını oluşturalım
            
    
            // Kullanıcının mevcut avatarını alalım
           
            $query = $db->prepare("SELECT profilepicture FROM users WHERE id = :username");
            $query->bindParam(':username', $userID);
            $query->execute();
            $result = $query->fetch(PDO::FETCH_ASSOC);
            $currentAvatar = $result['profilepicture'];
    
            // Avatar güncelleme formunu oluşturalım
            echo '<h1>Kullanıcı Avatar Güncelleme</h1>';
            echo '<img src="https://enyorum.net/v2/' . $currentAvatar . '" alt="Mevcut Avatar"><br>';
            echo '<form action="profile2.php" method="post" enctype="multipart/form-data">';
            echo '<input type="file" name="avatar" id="avatar" accept="image/*"><br>';
            echo '<input type="submit" name="submit" value="Güncelle">';
            echo '</form>';
     
    
            // Form gönderildiğinde yeni avatarı kaydedelim
            if (isset($_POST['submit'])) {
                if (isset($_FILES['avatar']) && $_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
                    $avatarTmpName = $_FILES['avatar']['tmp_name'];
                    $avatarName = $_FILES['avatar']['name'];
                   $extension = pathinfo($avatarName, PATHINFO_EXTENSION);
                $uniqueFileName = uniqid('', true) . '.' . $extension; // Benzersiz bir dosya adı oluştur
                $avatarPath = 'uploads/' . $uniqueFileName; // Dosya adını avatar yoluna ekle
    
                  
    
     // Dosya türü kontrolü
                    $allowedTypes = ['image/jpeg', 'image/png'];
                    $fileType = $_FILES['avatar']['type'];
                    if (!in_array($fileType, $allowedTypes)) {
                        echo '<p>Yalnızca JPEG ve PNG formatında resimler kabul edilir!</p>';
                        exit;
                    }
                    
                                    // Dosya boyutu kontrolü (1 MB = 1048576 byte)
                    $maxFileSize = 1048576;
                    $fileSize = $_FILES['avatar']['size'];
                    if ($fileSize > $maxFileSize) {
                        echo '<p>Yüklenen dosya 1 MB\'tan büyük olamaz!</p>';
                        exit;
                    }
                    
                             
     
                      /* Eski avatardan kurtulalım
                    if (file_exists($currentAvatar) && $currentAvatar !== 'avatars/default-avatar.png') {
                        unlink($currentAvatar);
                    } */
                $md5Hash = md5_file($avatarTmpName);
                    
                                // Mevcut avatarın MD5 hash değerini alalım
    $query = $db->prepare("SELECT md5Hash, file_name FROM uploaded_images WHERE user_id = :user_id");
    $query->bindParam(':user_id', $userID);
    $query->execute();
    $result = $query->fetchAll(PDO::FETCH_ASSOC);
    
    // MD5 hash değerini arayarak dosya adını bulalım
    $guncelavatar = '';
    foreach ($result as $row) {
        if ($row['md5Hash'] === $md5Hash) {
            $guncelavatar = $row['file_name'];
            break;
        }
    }
    
    
    // Eğer $guncelavatar hala boş ise, yeni resim yüklenecektir.
    if (empty($guncelavatar)) {
        // Yeni resmin bilgilerini uploaded_images tablosuna ekleyelim
        $query = $db->prepare("INSERT INTO uploaded_images (file_name, user_id, md5Hash) VALUES (:file_name, :user_id, :md5Hash)");
        $query->bindParam(':file_name', $avatarPath);
        $query->bindParam(':user_id', $userID);
        $query->bindParam(':md5Hash', $md5Hash);
        $query->execute();
        move_uploaded_file($avatarTmpName, $avatarPath);
    
        // Yeni avatarın dosya adını profil resmi olarak güncelleyelim
        $query = $db->prepare("UPDATE users SET profilepicture = :avatar_path WHERE id = :user_id");
        $query->bindParam(':avatar_path', $avatarPath);
        $query->bindParam(':user_id', $userID);
        $query->execute();
    } else {
        // Eğer $guncelavatar dolu ise, mevcut profil resmini güncelleyelim
        $query = $db->prepare("UPDATE users SET profilepicture = :avatar_path WHERE id = :user_id");
        $query->bindParam(':avatar_path', $guncelavatar);
        $query->bindParam(':user_id', $userID);
        $query->execute();
    }
    
                    
                
                    
                    // Yeni avatara geçelim
    
                    /*Veritabanında avatar yolunu güncelleyelim
                    $query = $db->prepare("UPDATE users SET profilepicture = :avatar_path WHERE id = :username");
                    $query->bindParam(':avatar_path', $avatarPath);
                    $query->bindParam(':username', $userID);
                    $query->execute();
    */
                    // Sayfayı yeniden yükleyelim
                    header("Location: profile2.php");
                    exit;
                }
                else{
                    echo "Herhangi bir dosya seçilmedi!";
                }
            } 
                
        } catch (PDOException $e) {
            echo 'Hata: ' . $e->getMessage();
        }
        ?>
    </body>
    </html>
    • phpwebdeveloper
    phpwebdeveloper bunu beğendi.
    1 kişi bunu beğendi.
  • 26-07-2023, 01:04:42
    #2
    Elinize sağlık
  • 26-07-2023, 01:08:03
    #3
    Teoride güzel fakat pratikte çalışmaz. Diyelim ki 1000 adet kullanıcınızdan 2si de image isimli dosya yüklemeye kalktı e ikisinin de md5 değeri aynı olacağı için ve x kişisi y kişisinden önce yüklemiş olacağı için y kişisi o dosyayı yükleyemeyecek. Bundan ötürü bu sistem pek efektif olmaz fakat böyle durumlarda basit çözüm olarak önce mevcut resmi silip sonrasında yeni update edilen dosyaya rastgele rand() komutuyla bir yeni isim vererek yükleme yaptırırsanız hem önceki görsel silinmiş olacağı için yer tutmayacak hem de bütün isimler benzersiz olacağı için sistem çalışmış olacak (En basit haliyle).

    Fakat yaptığınız iş gayet güzel elinize kolunuza sağlık yeni konularınızı bekliyorum takipteyim
  • 26-07-2023, 01:15:14
    #4
    phpwebdeveloper adlı üyeden alıntı: mesajı görüntüle
    Teoride güzel fakat pratikte çalışmaz. Diyelim ki 1000 adet kullanıcınızdan 2si de image isimli dosya yüklemeye kalktı e ikisinin de md5 değeri aynı olacağı için ve x kişisi y kişisinden önce yüklemiş olacağı için y kişisi o dosyayı yükleyemeyecek. Bundan ötürü bu sistem pek efektif olmaz fakat böyle durumlarda basit çözüm olarak önce mevcut resmi silip sonrasında yeni update edilen dosyaya rastgele rand() komutuyla bir yeni isim vererek yükleme yaptırırsanız hem önceki görsel silinmiş olacağı için yer tutmayacak hem de bütün isimler benzersiz olacağı için sistem çalışmış olacak (En basit haliyle).

    Fakat yaptığınız iş gayet güzel elinize kolunuza sağlık yeni konularınızı bekliyorum takipteyim
    Hayır hocam kodları incelerseniz eğer zaten eğer bu dosyayı bulursa file_name kısmını çekiyor ve kullanıcın profilepicture kısmına ekliyor.Yani bir nevi link olarak çekiyor diyebiliriz.







    Alıntı
    $query = $db->prepare("SELECT md5Hash, file_name FROM uploaded_images WHERE user_id = :user_id");
    $query->bindParam(':user_id', $userID);
    $query->execute();
    $result = $query->fetchAll(PDO::FETCH_ASSOC);

    // MD5 hash değerini arayarak dosya adını bulalım
    $guncelavatar = '';
    foreach ($result as $row) {
    if ($row['md5Hash'] === $md5Hash) {
    $guncelavatar = $row['file_name'];
    break;
    }
    }
    Yukarda gördüğünüz gibi user_id ye göre ayarladım yani sadece o üyenin yüklediği dosyalar da arama yapıyor. Burayı direkt yüklenen dosyanın md5hashını alıp sql de tüm sonuçlar da kontrol ettirip ona göre işlem yaptırmak kâfi olucaktır
  • 26-07-2023, 01:21:50
    #5
    Misafir adlı üyeden alıntı: mesajı görüntüle
    Hayır hocam kodları incelerseniz eğer zaten eğer bu dosyayı bulursa file_name kısmını çekiyor ve kullanıcın profilepicture kısmına ekliyor.Yani bir nevi link olarak çekiyor diyebiliriz.









    Yukarda gördüğünüz gibi user_id ye göre ayarladım yani sadece o üyenin yüklediği dosyalar da arama yapıyor. Burayı direkt yüklenen dosyanın md5hashını alıp sql de tüm sonuçlar da kontrol ettirip ona göre işlem yaptırmak kâfi olucaktır
    Doğruyu söylemek gerekirse kodları detaylı incelemedim üstün körü baktım videoyu izleyince standart bir dosya yükleme işlemi yaptığınızı düşündüm ondan ötürü öyle bir yorum yaptım bu haliyle dediğiniz gibi çakışma olmaz. O yüzden o örneği verdim zaten benim hatam. Bu örnek üzerinde benim aklıma takılan tek şey neden md5 kullanıyorsunuz onu anlayamadım zaten dosya isimlerini tutuyorsunuz ve hepsi aynı oradan da md5 kullanmadan eşleştirme yapabilirsiniz
  • 26-07-2023, 01:28:46
    #6
    phpwebdeveloper adlı üyeden alıntı: mesajı görüntüle
    Doğruyu söylemek gerekirse kodları detaylı incelemedim üstün körü baktım videoyu izleyince standart bir dosya yükleme işlemi yaptığınızı düşündüm ondan ötürü öyle bir yorum yaptım bu haliyle dediğiniz gibi çakışma olmaz. O yüzden o örneği verdim zaten benim hatam. Bu örnek üzerinde benim aklıma takılan tek şey neden md5 kullanıyorsunuz onu anlayamadım zaten dosya isimlerini tutuyorsunuz ve hepsi aynı oradan da md5 kullanmadan eşleştirme yapabilirsiniz
    Hocam şöyle anlatayım size dosya isimleri random olarak uploads klasörüne kaydediliyor.
    Bir dosyanın md5hash o dosyaya manuel müdahale edilmedikçe değişmiyor hocam. Yani örneğin bir tane gemi resmi var diyelim siz bu resmi photoshopda açıp üstüne ekleme yapmadığınız sürece md5 değeri asla değişmiyor. Kısaca ip adresi gibi düşünebiliriz.

    sadece dosya isimlerini tutsaydım eğer proje çalışmazdı, dosya isimlerini aslında md5 eğer varsa direkt profil resmi kısmını update etsin diye tutuyorum

    birde mesela deniz resminin ismini avatar vs yapsanız da md5 aynı kalıyor değişmiyor bu yüzden md5 hash şart hocam

    Yani temelde projenin amacı zaten yüklenmiş bir dosyayı tekrar uploads klasörüne yükletmemek.

    yani 50 kullanıcı var elliside aynı resim dosyasını yükledi diyelim boş yere uploads klasörüne 50 tane farklı isimde resim olucak ama bu sistem de md5hash kontrol ettiğimiz için tek bir resim dosyası olucak ve o 50 kullanıcının profil resmi linkide aynı olucak 😇
    • phpwebdeveloper
    phpwebdeveloper bunu beğendi.
    1 kişi bunu beğendi.
  • 26-07-2023, 01:37:52
    #7
    Misafir adlı üyeden alıntı: mesajı görüntüle
    Hocam şöyle anlatayım size dosya isimleri random olarak uploads klasörüne kaydediliyor.
    Bir dosyanın md5hash o dosyaya manuel müdahale edilmedikçe değişmiyor hocam. Yani örneğin bir tane gemi resmi var diyelim siz bu resmi photoshopda açıp üstüne ekleme yapmadığınız sürece md5 değeri asla değişmiyor. Kısaca ip adresi gibi düşünebiliriz.

    sadece dosya isimlerini tutsaydım eğer proje çalışmazdı, dosya isimlerini aslında md5 eğer varsa direkt profil resmi kısmını update etsin diye tutuyorum

    birde mesela deniz resminin ismini avatar vs yapsanız da md5 aynı kalıyor değişmiyor bu yüzden md5 hash şart hocam

    Yani temelde projenin amacı zaten yüklenmiş bir dosyayı tekrar uploads klasörüne yükletmemek.

    yani 50 kullanıcı var elliside aynı resim dosyasını yükledi diyelim boş yere uploads klasörüne 50 tane farklı isimde resim olucak ama bu sistem de md5hash kontrol ettiğimiz için tek bir resim dosyası olucak ve o 50 kullanıcının profil resmi linkide aynı olucak 😇
    Yanlış anlaşıldım sanırım aslında bunun için sormamıştım yani teknik olarak sadece user_id üzerinden yaptığınız bu işlemi diğer kullanıcılar da yükleyebileceği için aynı dosyayı md5 bana dediğim gibi mantıksız geliyor ben çok düz mantık olarak öncesini siler yenisini eklerim yalan yok yani md5 kullanımı burada çok mantıklı gelmiyor bana bu bahsettiğim kısıtlamadan ötürü ve zaten o kısıtlama kalkarsa da baştaki dediğim noktaya geliyoruz orada da md5 kontrolü yapıp dosya yolunu update edebilirsiniz o zaman doğrudan anlaşırız hiç sıkıntı olmaz ama dediğim gibi bu haliyle hala md5 kullanmanın bir anlamı yok gibi benim için (tamamen kişisel görüşüm).
  • 26-07-2023, 01:42:46
    #8
    phpwebdeveloper adlı üyeden alıntı: mesajı görüntüle
    Yanlış anlaşıldım sanırım aslında bunun için sormamıştım yani teknik olarak sadece user_id üzerinden yaptığınız bu işlemi diğer kullanıcılar da yükleyebileceği için aynı dosyayı md5 bana dediğim gibi mantıksız geliyor ben çok düz mantık olarak öncesini siler yenisini eklerim yalan yok yani md5 kullanımı burada çok mantıklı gelmiyor bana bu bahsettiğim kısıtlamadan ötürü ve zaten o kısıtlama kalkarsa da baştaki dediğim noktaya geliyoruz orada da md5 kontrolü yapıp dosya yolunu update edebilirsiniz o zaman doğrudan anlaşırız hiç sıkıntı olmaz ama dediğim gibi bu haliyle hala md5 kullanmanın bir anlamı yok gibi benim için (tamamen kişisel görüşüm).
    Evet videoda yazdığım gibi sadece o giriş yapmış kullanıcı için check ettirdim tüm kullanıcıların yüklediği dosyalarda checklettirmemiz lazım burası doğru ✅
    Ama zaten temel mantık diğer kullanıcıların o dosyayı yüklerken sadece profilpicture linklerini güncellemek olduğu için sadece userid üzerinden checkletmeyi kaldırmak yeterli 🙂
    Yarın konuya güncellenmiş halini eklerim
    • phpwebdeveloper
    phpwebdeveloper bunu beğendi.
    1 kişi bunu beğendi.