স্ট্রিং এবং রেগুলার এক্সপ্রেশন (The Silent Performance Killers)

স্ট্রিং ম্যানিপুলেশন যেকোনো অ্যাপ্লিকেশনের অন্যতম প্রধান কাজ। কিন্তু পিএইচপি-তে স্ট্রিং এবং রিজেক্স (Regex) সঠিকভাবে হ্যান্ডেল না করলে মেমোরি লিক এবং CPU স্পাইক হতে পারে।

এই অধ্যায়ে আমরা স্ট্রিং-এর বাইনারি লেভেল এবং PCRE ইঞ্জিনের গভীরে প্রবেশ করব।

৫.১ স্ট্রিং ইন্টারনাল আর্কিটেকচার (Byte Sequence)

পিএইচপি-তে স্ট্রিং হলো Immutable Binary-Safe Byte Sequence। সহজ কথায়, পিএইচপি স্ট্রিং-কে ক্যারেক্টার হিসেবে চেনে না, চেনে বাইট (Byte) হিসেবে।

📦 মেমোরি মডেল এবং Immutability

পিএইচপি স্ট্রিং Immutable (অপরিবর্তনযোগ্য)। এর মানে হলো, আপনি যখনই কোনো স্ট্রিং পরিবর্তন করেন, পিএইচপি মেমোরিতে সম্পূর্ণ নতুন একটি স্ট্রিং তৈরি করে।

$str = "Hello";
$str[0] = "J"; // Internally: নতুন মেমোরি অ্যালোকেট হয়, পুরনোটা ফেলে দেওয়া হয় না (COW)

📏 সাইজ বনাম মেমোরি (Overhead)

আপনি যদি ১ মেগাবাইটের একটি স্ট্রিং তৈরি করেন, তবে র‍্যামে ঠিক ১ মেগাবাইট জায়গা খরচ হয় না।

$str = str_repeat("A", 1_000_000); // 1 Million Bytes
// Actual RAM usage: ~1.04 MB (Zval structure + Metadata overhead)

প্রতিটি স্ট্রিংয়ের সাথে পিএইচপি কিছু মেটাডেটা (Length, Refcount) রাখে, তাই সাইজ সবসময় একটু বেশি হয়।

৫.২ স্ট্রিং ম্যানিপুলেশন এবং মেমোরি অপ্টিমাইজেশন

❌ ১. কনক্যাটিনেশন (Concatenation) এর বিপদ

বড় টেক্সট জেনারেট করার সময় ডট (.) অপারেটর ব্যবহার করা মেমোরির জন্য ক্ষতিকর।

// ❌ Bad Practice (High Memory Churn)
$html = "";
foreach ($data as $row) {
    $html .= "
" . $row . "
"; // প্রতি লুপে আগের $html কপি হচ্ছে + নতুন পার্ট যোগ হচ্ছে = মেমোরি ওয়েস্ট }

✅ Senior Way (Buffer Method):

$buffer = [];
foreach ($data as $row) {
    $buffer[] = "
" . $row . "
"; } $html = implode("", $buffer); // মাত্র একবার মেমোরি অ্যালোকেশন হয়। বড় ডেটার জন্য এটি অনেক ফাস্ট।

⚡ ২. strpos বনাম preg_match

সিম্পল সার্চের জন্য কখনোই preg_match ব্যবহার করবেন না।

  • strpos: O(n) (C-level byte scan, অত্যন্ত ফাস্ট)
  • preg_match: Regex ইঞ্জিন লোড করে, প্যাটার্ন কম্পাইল করে, তারপর সার্চ করে (১০-২০ গুণ স্লো)

৫.৩ রেগুলার এক্সপ্রেশন: পারফরম্যান্স রুলস (PCRE Engine)

পিএইচপি PCRE (Perl Compatible Regular Expressions) লাইব্রেরি ব্যবহার করে। এটি শক্তিশালী কিন্তু ভারী।

🔄 Regex এক্সিকিউশন স্টেপস:

  • Compilation: প্যাটার্নটি ইন্টারনাল বাইটকোডে কম্পাইল হয়
  • Execution: ইঞ্জিন ইনপুট স্ট্রিং স্ক্যান করে
  • Backtracking: ম্যাচ না পেলে সে পেছনে ফিরে আবার চেষ্টা করে

⚠️ Catastrophic Backtracking (সার্ভার হ্যাং করার উপায়)

সবচেয়ে ভয়ংকর Regex প্যাটার্ন হলো নেস্টেড কোয়ান্টিফায়ার।

// ❌ DANGEROUS CODE
preg_match('/(a+)+b/', "aaaaaaaaaaaaaaaaaaaaac");

কেন এটি বিপজ্জনক?
এখানে (a+)+ প্যাটার্নটি a-কে গ্রাস করে। শেষে b না পেয়ে সে এক ধাপ পেছনে যায়, আবার চেষ্টা করে। ৫০০০ ক্যারেক্টারের জন্য এটি $2^{5000}$ বার চেষ্টা করতে পারে! একে বলা হয় Catastrophic Backtracking। এটি আপনার CPU 100% করে সার্ভার ডাউন করে দেবে।

💡 Senior Rule: কখনোই নেস্টেড লুপের মতো (x+)+ প্যাটার্ন লিখবেন না।

৫.৪ preg_replace বনাম str_replace

সিনিয়দের গোল্ডেন রুল: "যদি Regex ছাড়া কাজ হয়, তবে Regex ব্যবহার করবেন না।"

❌ Slow

preg_replace('/World/', 'PHP', $text);

✅ Fast (20x Faster)

str_replace('World', 'PHP', $text);

📋 তুলনা:

  • str_replace: কোনো কম্পাইলেশন নেই, সরাসরি ক্যারেক্টার রিপ্লেস করে। সুপার ফাস্ট
  • preg_replace: প্যাটার্ন কম্পাইল করে, ম্যাচ খোঁজে, নতুন স্ট্রিং তৈরি করে

📞 preg_replace_callback

যখন ডাইনামিক লজিক দরকার হয়, তখন এটি ব্যবহার করুন। এটি e মডিফায়ার (যা এখন ডেপ্রিকেটেড) এর চেয়ে নিরাপদ।

৫.৫ UTF-8 এবং মাল্টি-বাইট ট্র্যাপ (The Most Common Bug)

পিএইচপি স্ট্রিং বাইট-বেইজড, ক্যারেক্টার-বেইজড নয়। এই পার্থক্য না বুঝলে ইমোজি বা বাংলা টেক্সট নিয়ে কাজ করা অসম্ভব।

📏 ১. strlen বনাম mb_strlen

$str = "বাংলা"; // ৩টি অক্ষর মনে হলেও আসলে ৫টি কোডপয়েন্ট
echo strlen($str);    // Output: 15 (প্রতি বাংলা অক্ষর ৩ বাইট করে)
echo mb_strlen($str); // Output: 5 (সঠিক ক্যারেক্টার কাউন্ট)

শিক্ষা: ইউজার ইনপুট বা পাসওয়ার্ড লেন্থ চেক করতে সবসময় mb_strlen ব্যবহার করুন।

✂️ ২. substr এর বিপদ (Mojibake)

$text = "Hello বাংলা";
echo substr($text, 0, 7); 
// Output: "Hello " (Broken character - মাল্টি-বাইট ক্যারেক্টার অর্ধেক কেটে ফেলেছে)

substr বাইট কেটে ফেলে, তাই মাল্টি-বাইট ক্যারেক্টারের মাঝখানে কেটে ফেললে স্ট্রিং করাপ্ট হয়ে যায়।

সমাধান: mb_substr($text, 0, 7, "UTF-8") ব্যবহার করুন।

🔍 ৩. Regex এবং UTF-8 (u modifier)

ডিফল্টভাবে Regex ইঞ্জিন বাইট ধরে কাজ করে। বাংলা বা ইমোজি ঠিকঠাক ম্যাচ করাতে u মডিফায়ার ব্যবহার করতে হয়।

// ❌ ভুল
preg_match('/^[w]+$/', "বাংলা"); // false (কারণ w শুধু a-z, 0-9 চেনে)

// ✅ সঠিক
preg_match('/^[p{L}]+$/u', "বাংলা"); // true (p{L} মানে যেকোনো ভাষার অক্ষর)

🎯 Senior Developer Interview Questions (Chapter 5)

Q: strlen("🔥") এর আউটপুট কত এবং কেন?

আউটপুট 4। কারণ পিএইচপি বাইট কাউন্ট করে, আর ইমোজিটি UTF-8 এনকোডিংয়ে ৪ বাইট জায়গা নেয়। সঠিক ক্যারেক্টার কাউন্ট পেতে mb_strlen ব্যবহার করতে হবে।

Q: Catastrophic Backtracking কী? একটি উদাহরণ দিন।

যখন একটি Regex প্যাটার্নে নেস্টেড কোয়ান্টিফায়ার থাকে (যেমন /(a+)+b/) এবং ইনপুট স্ট্রিং প্রায় ম্যাচ করে কিন্তু শেষে ফেইল করে, তখন ইঞ্জিন এক্সপোনেনশিয়াল টাইম (O(2^n)) নিয়ে ব্যাকট্র্যাক করে, যা সিস্টেম ফ্রিজ করে দেয়।

Q: বড় স্ট্রিং কনক্যাটিনেশনের জন্য . অপারেটরের চেয়ে implode কেন ভালো?

. অপারেটর প্রতি স্টেপে পুরনো স্ট্রিং কপি করে এবং নতুন মেমোরি অ্যালোকেট করে। implode বা array বাফারিং ব্যবহার করলে মেমোরি অ্যালোকেশন মাত্র একবার হয়, যা পারফরম্যান্স বাড়ায়।

Q: preg_replace বনাম str_replace - কখন কোনটি ব্যবহার করবেন?

যদি প্যাটার্ন ফিক্সড স্ট্রিং হয়, তবে সবসময় str_replace (ফাস্ট)। যদি প্যাটার্ন জটিল হয় (যেমন ওয়াইল্ডকার্ড বা রেঞ্জ), কেবল তখনই preg_replace ব্যবহার করা উচিত।

🎯 অধ্যায় ৫ এর সারাংশ (Summary)

এই অধ্যায়ে আমরা শিখলাম:

  • String Internals: পিএইচপি স্ট্রিং বাইট-বেইজড (Binary-safe), Immutable
  • Concatenation Optimization: . অপারেটরের বদলে implode() ব্যবহার করুন
  • strpos vs preg_match: Simple search এর জন্য strpos 20x faster
  • Catastrophic Backtracking: Nested quantifier (a+)+ সার্ভার হ্যাং করতে পারে
  • UTF-8 Traps: mb_strlen, mb_substr, এবং u modifier ব্যবহার করুন
  • preg_replace vs str_replace: Static replace-এ str_replace 20x faster

✨ পরবর্তী অধ্যায়: Part 6 — OOP (Full Senior Level) — যেখানে LSP (Liskov Substitution), Late Static Binding, Dependency Injection এবং আরও অনেক কিছু নিয়ে আলোচনা হবে।

প্রস্তুত তো? 🚀

🔒 কপিরাইট সুরক্ষিত কন্টেন্ট 🔒

কপি, স্ক্রিনশট, প্রিন্ট করা সম্পূর্ণ নিষিদ্ধ।