ফাইল সিস্টেম এবং I/O (Senior-Level Deep Dive)
ফাইল রিড/রাইট করা শুনতে সহজ মনে হয়, কিন্তু যখন ১ জিবি ফাইল নিয়ে কাজ করতে হয় কিংবা হাই-ট্রাফিক সাইটে ইউজার আপলোড হ্যান্ডেল করতে হয়,
তখন সাধারণ file_get_contents সার্ভার ক্র্যাশ ঘটাতে পারে।
এই অধ্যায়ে আমরা ফাইল সিস্টেমের মেমোরি ম্যানেজমেন্ট এবং সিকিউরিটি নিয়ে আলোচনা করব।
১১.১ ফাইল রিড/রাইট — ইন্টারনাল মেকানিজম
পিএইচপি ফাইল সিস্টেম হ্যান্ডেল করার জন্য Streams Layer ব্যবহার করে।
🔥 মেমোরি সমস্যা (The RAM Killer)
// ❌ জুনিয়র অ্যাপ্রোচ
$content = file_get_contents("huge_log.txt");
এটি পুরো ফাইলটি র্যামে লোড করে। যদি ফাইলের সাইজ ১ জিবি হয় এবং আপনার memory_limit ৫১২ এমবি হয়, তবে স্ক্রিপ্ট Fatal Error দিয়ে মারা যাবে।
✅ সিনিয়র অ্যাপ্রোচ (মেমোরি সেফ স্ট্রিমিং)
আমরা পুরো ফাইল লোড না করে, অল্প অল্প করে (Chunk) পড়ব।
$fp = fopen("huge_log.txt", "r");
// বাফার সাইজ অনুযায়ী ডাটা পড়া (Line by Line or Chunk)
while (!feof($fp)) {
$line = fgets($fp); // এক লাইন পড়ে এবং মেমোরি থেকে ফেলে দেয়
// Process $line...
}
fclose($fp);
এটি ১ জিবি বা ১০ জিবি ফাইলও মাত্র কয়েক কিলোবাইট র্যাম খরচ করে প্রসেস করতে পারে।
💡 Modern OOP Way: পিএইচপির SPL লাইব্রেরিতে SplFileObject আছে যা fopen এর চেয়ে বেশি রিডেবল এবং অবজেক্ট ওরিয়েন্টেড।
১১.২ লকিং ফাইল (Race Condition প্রতিরোধ)
হাই ট্রাফিক সাইটে একই ফাইলে একাধিক প্রসেস একসাথে রাইট করার চেষ্টা করলে ডাটা করাপ্ট হয়ে যায়। একে Race Condition বলে।
🔒 সমাধান: flock (File Lock)
$fp = fopen("counter.txt", "c+"); // c+ মানে রিড/রাইট, না থাকলে ক্রিয়েট
if (flock($fp, LOCK_EX)) { // Exclusive Lock (অন্য কাউকে রাইট করতে দেবে না)
$count = (int) fread($fp, 1024);
$count++;
ftruncate($fp, 0); // ফাইল ক্লিয়ার করা
rewind($fp); // পয়েন্টার শুরুতে আনা
fwrite($fp, $count);
flock($fp, LOCK_UN); // লক রিলিজ করা
} else {
echo "Could not lock file!";
}
fclose($fp);
১১.৩ স্ট্রিমস (Streams) — পিএইচপির আসল শক্তি
পিএইচপিতে ফাইল, নেটওয়ার্ক রিকোয়েস্ট, জিপ ফাইল—সবকিছুই স্ট্রিম।
📦 php://input
Raw Request Body পড়ার জন্য (JSON API বা Webhook এর জন্য ফরজ)
💾 php://memory
র্যামে টেম্পোরারি ফাইল তৈরি করে
🌡️ php://temp
ডাটা কম হলে র্যামে রাখে, বেশি হলে ফাইলে মুভ করে (Smart Memory Management)
📤 php://output
সরাসরি ব্রাউজারে বা কনসোলে রাইট করার জন্য (echo এর বিকল্প)
🔧 স্ট্রিম ফিল্টার (On-the-fly Modification)
ফাইল রাইট করার সময় অটোমেটিক্যালি কন্টেন্ট মডিফাই করা যায়।
$fp = fopen("data.txt", "w");
// যা লিখব সব আপারকেস হয়ে যাবে
stream_filter_append($fp, "string.toupper");
fwrite($fp, "hello world");
// ফাইলে সেভ হবে: "HELLO WORLD"
১১.৪ ফাইল পারমিশন (Linux Mode Explained)
লিনাক্সে পারমিশন ৩টি ডিজিটে থাকে (Octal)।
4
2
1
📊 সিকিউর পারমিশন স্ট্রাকচার:
- ফাইল:
644(Owner: RW, Group: R, Others: R). ফাইলে এক্সিকিউট (x) পারমিশন থাকা বিপজ্জনক - ফোল্ডার:
755(Owner: RWX, Others: RX). ফোল্ডারে ঢোকার জন্য x লাগে
⚠️ সতর্কতা: কখনোই chmod 777 দেবেন না। এর মানে পৃথিবীর যে কেউ আপনার ফাইল ডিলিট বা এডিট করতে পারবে।
১১.৫ ফাইল আপলোড সিকিউরিটি (Most Critical Part)
ফাইল আপলোড ফিচার হ্যাকারদের প্রিয় জায়গা। তারা image.php বা shell.php.jpg আপলোড করে সার্ভার হ্যাক করতে চায়।
🛡️ ১. MIME টাইপ ভ্যালিডেশন (Extension বিশ্বাস করবেন না)
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->file($_FILES['file']['tmp_name']);
$allowed = ['image/jpeg', 'image/png', 'application/pdf'];
if (!in_array($mimeType, $allowed)) {
throw new Exception("Invalid file type!");
}
$_FILES['file']['type'] হ্যাকার ম্যানিপুলেট করতে পারে, তাই finfo দিয়ে ফাইলের কন্টেন্ট চেক করতে হয় (Magic Bytes)।
🚫 ২. এক্সিকিউশন বন্ধ করা (Nginx/Apache Rule)
আপলোড ফোল্ডারে যাতে কোনো পিএইচপি স্ক্রিপ্ট রান না করে।
# Nginx Config
location /uploads/ {
location ~ \.php$ {
deny all;
}
}
🎲 ৩. র্যান্ডম ফাইলের নাম
কখনোই ইউজারের দেওয়া নাম রাখবেন না।
$ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
$filename = bin2hex(random_bytes(16)) . "." . $ext;
// output: a1b2c3d4... .jpg
১১.৬ লার্জ ফাইল অপ্টিমাইজেশন
📦 ১. চাঙ্কড রিডিং (Chunked Reading)
বড় ফাইল ডাউনলোডের সময় মেমোরি বাঁচাতে বাফার ফ্লাশ করতে হয়।
$fp = fopen("movie.mp4", "rb");
while (!feof($fp)) {
echo fread($fp, 8192); // 8KB করে পড়ো
ob_flush(); // বাফার ক্লিয়ার করো
flush(); // ব্রাউজারে পাঠাও
}
fclose($fp);
⚡ ২. X-Accel-Redirect (Nginx Level Optimization)
পিএইচপি দিয়ে ফাইল সার্ভ করা স্লো কারণ পিএইচপি প্রসেস এনগেজড থাকে। সিনিয়রা ফাইল সার্ভ করার দায়িত্ব Nginx কে দিয়ে দেয়।
- পিএইচপি অথেনটিকেশন চেক করবে
- পিএইচপি একটি স্পেশাল হেডার পাঠাবে
- Nginx হেডার দেখে নিজেই ফাইল সার্ভ করবে (পিএইচপি প্রসেস ফ্রি হয়ে যাবে)
// PHP Code
if ($user->canDownload()) {
header("X-Accel-Redirect: /protected_files/video.mp4");
header("Content-Type: video/mp4");
exit; // পিএইচপির কাজ শেষ, বাকিটা Nginx দেখবে
}
এটি সার্ভারের লোড ৯৯% কমিয়ে দিতে পারে।
🎯 Senior Developer Interview Questions (Chapter 11)
Q: file_get_contents দিয়ে বড় ফাইল রিড করলে কী সমস্যা হতে পারে? সমাধান কী?
এটি পুরো ফাইল র্যামে লোড করে, যা Memory Exhaustion এরর ঘটাতে পারে। সমাধান হলো fopen এবং fgets/fread ব্যবহার করে স্ট্রিম (Chunk) আকারে পড়া।
Q: ফাইল আপলোডের সময় এক্সটেনশন চেক করা কি যথেষ্ট?
না। হ্যাকাররা ফাইলের নাম virus.php.jpg দিতে পারে। তাই finfo বা mime_content_type ব্যবহার করে ফাইলের ইন্টারনাল ম্যাজিক বাইটস চেক করতে হবে।
Q: flock (File Locking) কেন প্রয়োজন?
কনকারেন্সি বা মাল্টিপল রিকোয়েস্ট হ্যান্ডেল করার সময়। যাতে এক প্রসেস রাইট করার সময় অন্য প্রসেস সেই ফাইলে হাত দিয়ে ডাটা করাপ্ট না করতে পারে।
Q: X-Accel-Redirect বা X-Sendfile এর সুবিধা কী?
এটি লার্জ ফাইল সার্ভ করার দায়িত্ব পিএইচপি (Application Layer) থেকে সরিয়ে ওয়েব সার্ভার (Nginx/Apache) কে দেয়। ফলে পিএইচপি প্রসেস বা ওয়ার্কার ফ্রি হয়ে যায় এবং মেমোরি খরচ শূন্যের কোঠায় থাকে।
🎯 অধ্যায় ১১ এর সারাংশ (Summary)
এই অধ্যায়ে আমরা শিখলাম:
- ✓Memory-Efficient Reading: fopen + fgets/fread for large files
- ✓File Locking (flock): Prevent race conditions with LOCK_EX/LOCK_UN
- ✓Stream Wrappers: php://input, php://memory, php://temp
- ✓File Permissions: 644 for files, 755 for directories, NEVER 777
- ✓Secure Upload: finfo (magic bytes), random filename, disable PHP execution
- ✓X-Accel-Redirect: Offload file serving to Nginx, 99% load reduction
✨ এখন আপনি ফাইল সিস্টেম হ্যান্ডলিংয়েও মাস্টার।
🚀 PHP Senior Journey: 11/?? Chapters Completed