
Kesehatan yang bagus, Penjaja! Dalam proses pengerjaan proyek situs kencan, menjadi perlu untuk mengatur penyimpanan foto pengguna. Menurut kerangka acuan, jumlah foto per pengguna dibatasi hingga 10 file. Tetapi mungkin ada puluhan ribu pengguna. Terutama mengingat bahwa proyek dalam bentuk saat ini sudah ada sejak awal "nol". Artinya, sudah ada ribuan pengguna dalam database. Hampir semua sistem file, sejauh yang saya tahu, bereaksi sangat negatif terhadap sejumlah besar simpul anak dalam folder. Dari pengalaman, saya dapat mengatakan bahwa masalah dimulai setelah 1000-1500 file / folder di folder induk.
Penafian. Saya mencari di Google sebelum menulis artikel dan menemukan beberapa solusi untuk masalah yang sedang dibahas (misalnya, di sini atau di sini ). Tetapi saya tidak menemukan solusi tunggal yang sama persis dengan solusi saya. Selain itu, dalam artikel ini saya hanya membagikan pengalaman saya sendiri dalam menyelesaikan masalah.Teori
Selain tugas penyimpanan seperti itu, ada juga kondisi dalam pernyataan kerja, yang menurutnya perlu meninggalkan keterangan dan keterangan untuk foto. Tentu saja, Anda tidak dapat melakukannya tanpa basis data. Artinya, hal pertama yang kita lakukan adalah membuat tabel di mana kita meresepkan pemetaan meta-data (tanda tangan, judul, dll.) Dengan file pada disk. Setiap file sesuai dengan satu baris dalam database. Dengan demikian, setiap file memiliki pengenal.
Penyimpangan kecil. Mari kita bicara tentang peningkatan otomatis. Situs kencan mungkin memiliki selusin atau dua ribu pengguna. Pertanyaannya adalah berapa banyak pengguna pada umumnya pergi melalui proyek selama seluruh keberadaannya. Misalnya, khalayak aktif kencan-ru adalah beberapa ratus ribu. Namun, bayangkan saja berapa banyak pengguna yang tersisa selama masa proyek ini; berapa banyak pengguna yang belum diaktifkan sejauh ini. Sekarang tambahkan ke undang-undang kami, yang mewajibkan kami untuk menyimpan informasi tentang pengguna selama setidaknya enam bulan ... Cepat atau lambat, 4 dengan satu sen dari
INT TANDA akan berakhir. Oleh karena itu, yang terbaik adalah mengambil
BIGINT untuk kunci utama.
Sekarang mari kita coba membayangkan sejumlah jenis
BIGINT . Ini adalah 8 byte. Setiap byte dari 0 hingga 255. 255 node anak cukup normal untuk sistem file apa pun. Artinya, kami mengambil pengidentifikasi file dalam representasi heksadesimal, kami memecahnya menjadi potongan dua karakter. Kami menggunakan potongan ini sebagai nama folder, yang terakhir sebagai nama file fisik. KEUNTUNGAN!
0f/65/84/10/67/68/19/ff.file
Elegan dan sederhana. Ekstensi file tidak penting di sini. Bagaimanapun, file tersebut akan diberikan oleh skrip yang akan memberikan browser tipe MIME tertentu, yang juga akan kami simpan dalam database. Selain itu, menyimpan informasi tentang file di dalam basis data memungkinkan Anda untuk mendefinisikan kembali jalur ke sana untuk browser. Katakanlah, file yang kita miliki sebenarnya terletak relatif terhadap direktori proyek di sepanjang path
/content/files/0f/65/84/10/67/68/19/ff.file
. Dan dalam database Anda dapat menulis URL untuk itu, misalnya,
/content/users/678/files/somefile
. SEO mungkin cukup tersenyum sekarang. Semua ini memungkinkan kita untuk tidak khawatir lagi tentang di mana menempatkan file secara fisik.
Tabel dalam database
Selain pengenal, tipe MIME, URL, dan lokasi fisik, kami akan menyimpan file md5 dan sha1 dalam tabel untuk memfilter file yang sama jika perlu. Tentu saja, kita juga perlu menyimpan hubungan entitas dalam tabel ini. Misalkan ID pengguna tempat file tersebut berada. Dan jika proyeknya tidak terlalu besar, maka dalam sistem yang sama kita dapat menyimpan, katakanlah, foto barang. Oleh karena itu, kami juga akan menyimpan nama kelas entitas tempat catatan itu berada.
Berbicara tentang burung. Jika Anda menutup folder menggunakan .htaccess untuk akses eksternal, file hanya dapat diperoleh melalui skrip. Dan dalam skrip akan dimungkinkan untuk menentukan akses ke file. Ke depan sedikit, saya akan mengatakan bahwa dalam CMS saya (di mana proyek tersebut digergaji sekarang) akses ditentukan oleh grup pengguna dasar, yang saya punya 8 - tamu, pengguna, manajer, admin, tidak aktif, diblokir, dihapus dan admin super. Super-admin dapat melakukan segalanya, sehingga tidak berpartisipasi dalam menentukan akses. Jika pengguna memiliki bendera admin super, maka ia adalah admin super. Semuanya sederhana. Artinya, kami akan menentukan akses ke tujuh grup yang tersisa. Akses sederhana - baik memberikan file atau tidak memberi. Secara total, Anda dapat mengambil bidang tipe
TINYINT .
Dan satu hal lagi. Menurut hukum kami, kami harus secara fisik menyimpan gambar khusus. Artinya, kita perlu menandai gambar entah bagaimana terhapus, daripada menghapus secara fisik. Akan lebih mudah untuk menggunakan bidang bit untuk keperluan ini. Dalam kasus seperti itu, saya biasanya menggunakan bidang bertipe
INT . Untuk cadangan, untuk berbicara. Selain itu, saya sudah memiliki tradisi menempatkan bendera
DIHAPUS di bit ke-5 dari akhir. Tapi itu tidak masalah lagi.
Apa yang kita miliki sebagai hasilnya:
create table `files` ( `id` bigint not null auto_increment,
Kelas operator
Sekarang kita perlu membuat kelas untuk mengunggah file. Kelas harus menyediakan kemampuan untuk membuat file, mengganti / memodifikasi file, menghapus file. Selain itu, ada baiknya mempertimbangkan dua poin. Pertama, proyek dapat ditransfer dari server ke server. Jadi di kelas Anda perlu mendefinisikan properti yang berisi direktori root file. Kedua, akan sangat tidak menyenangkan jika seseorang membuat tabel dalam database. Jadi, Anda perlu menyediakan kemungkinan pemulihan data. Dengan yang pertama, semuanya umumnya jelas. Adapun cadangan data, kami hanya akan memesan apa yang tidak dapat dipulihkan.
ID - dipulihkan dari lokasi fisik file
entitas_type - tidak dipulihkan
entitas - tidak dipulihkan
mime - dipulihkan menggunakan ekstensi finfo
md5 - dipulihkan dari file itu sendiri
sha1 - dipulihkan dari file itu sendiri
file - dipulihkan dari lokasi fisik file
url - tidak dikembalikan
meta - tidak dikembalikan
ukuran - dikembalikan dari file itu sendiri
dibuat - Anda dapat mengambil informasi dari file
diperbarui - Anda dapat mengambil informasi dari file
akses - tidak dipulihkan
bendera - tidak dipulihkan
Anda dapat segera membuang informasi meta. Itu tidak penting untuk fungsi sistem. Dan untuk pemulihan yang lebih cepat, Anda masih perlu menyimpan tipe MIME. Total: jenis entitas, ID entitas, MIME, URL, akses, dan bendera. Untuk meningkatkan keandalan sistem, kami akan menyimpan informasi cadangan untuk setiap folder tujuan secara terpisah di folder itu sendiri.
Kode kelas <?php class BigFiles { const FLAG_DELETED = 0x08000000;
Pertimbangkan beberapa hal:
-
realRoot - path lengkap ke folder dengan sistem file berakhir dengan garis miring.
-
webRoot - lintasan dari root situs tanpa garis miring (lihat alasannya di bawah).
- Sebagai DBMS, saya menggunakan ekstensi
MySQLi .
- Faktanya, informasi dari array
$ _FILES diteruskan sebagai argumen pertama ke metode
unggah .
- Jika Anda memanggil metode
pembaruan untuk meneruskan ID dari file yang ada, itu akan diganti jika array input di
tmp_name tidak kosong.
- Anda dapat menghapus dan mengubah flag beberapa file sekaligus. Untuk melakukan ini, alih-alih meneruskan pengidentifikasi file, Anda harus meneruskan array dengan pengidentifikasi, atau string dengan mereka, dipisahkan dengan koma.
Routing
Sebenarnya, ia turun ke beberapa baris di htaccess di root situs (diasumsikan bahwa mod_rewrite diaktifkan):
RewriteCond %{REQUEST_URI} ^/content/(.*)$ RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.+)$ content/index.php?file=$1 [L,QSA]
"Konten" adalah folder di root situs dalam kasus saya. Tentu saja Anda dapat memberi nama folder secara berbeda. Dan tentu saja index.php sendiri, disimpan dalam case saya di folder konten:
<?php $dbHost = '127.0.0.1'; $dbUser = 'user'; $dbPass = '****'; $dbName = 'database'; try { if (empty($_REQUEST['file'])) { header('HTTP/1.1 400 Bad Request'); exit; } $userG = 'anonimous';
Nah, dengan sendirinya, kita menutup sistem file itu sendiri dari akses eksternal. Letakkan file
.htaccess
di root folder
content/files
dengan hanya satu baris:
Deny from all
Ringkasan
Solusi ini memungkinkan Anda untuk menghindari hilangnya kinerja sistem file karena peningkatan jumlah file. Setidaknya masalah dalam bentuk ribuan file dalam satu folder pasti bisa dihindari. Dan pada saat yang sama, kita dapat mengatur dan mengontrol akses ke file di alamat yang dapat dibaca manusia. Ditambah kepatuhan dengan undang-undang suram kami. Segera melakukan reservasi, solusi ini BUKAN cara lengkap untuk melindungi konten. Ingat: jika sesuatu diputar di browser, itu dapat diunduh secara gratis.