php - tutorial - w3schools




কেন আমি পিএইচপি mysql_*ফাংশন ব্যবহার করা উচিত নয়? (10)

ব্যবহারে সহজ

বিশ্লেষণাত্মক এবং সিন্থেটিক কারণ ইতিমধ্যে উল্লেখ করা হয়েছে। নতুনদের জন্য তারিখের mysql_ ফাংশন ব্যবহার বন্ধ করার জন্য আরো উল্লেখযোগ্য উত্সাহ আছে।

সমসাময়িক ডাটাবেস API ব্যবহার করা সহজ

এটি বেশিরভাগ আবদ্ধ প্যারামিটার যা কোডটি সহজ করে তুলতে পারে। এবং share PDO রূপান্তরিত হওয়া অত্যধিক কষ্টকর নয়।

একবার একটি বড় কোড বেস পুনর্বিবেচনা সময় লাগে। এই মধ্যবর্তী বিকল্পের জন্য Raison d'être:

Equivalent pdo_ * mysql_ এর পরিবর্তে ফাংশন *

<pdo_mysql.php> ব্যবহার করে আপনি পুরোনো mysql_ ফাংশন থেকে সর্বনিম্ন প্রচেষ্টার মাধ্যমে স্যুইচ করতে পারেন। এটি pdo_ ফাংশন wrappers যোগ করে যা তাদের mysql_ counterparts প্রতিস্থাপন।

  1. শুধু include_once( <pdo_mysql.php> ); প্রতিটি ইনভোকেশন স্ক্রিপ্ট যা ডাটাবেসের সাথে যোগাযোগ করতে হবে।

  2. সর্বত্র mysql_ ফাংশন উপসর্গ সরান এবং এটি pdo_ দিয়ে প্রতিস্থাপন করুন।

    • mysql_ connect() mysql_ connect() হয়ে যায়
    • mysql_ query() pdo_ query() হয়ে যায় query()
    • mysql_ num_rows() mysql_ num_rows() হয়ে যায়
    • mysql_ insert_id() mysql_ insert_id() হয়ে যায়
    • mysql_ fetch_array() mysql_ fetch_array() হয়ে যায়
    • mysql_ fetch_assoc() mysql_ fetch_assoc() হয়ে যায়
    • mysql_ real_escape_string() mysql_ real_escape_string() হয়ে যায়
    • এবং তাই ...

  3. আপনার কোডটি একইভাবে কাজ করবে এবং এখনও বেশিরভাগই একই রকম দেখাবে:

    include_once("pdo_mysql.php"); 
    
    pdo_connect("localhost", "usrABC", "pw1234567");
    pdo_select_db("test");
    
    $result = pdo_query("SELECT title, html FROM pages");  
    
    while ($row = pdo_fetch_assoc($result)) {
        print "$row[title] - $row[html]";
    }
    

এবং আরো দেখুন।
আপনার কোড পিডিও ব্যবহার করা হয়
এখন এটি আসলে ব্যবহার করার সময়।

বাঁধ পরামিতি ব্যবহার করা সহজ হতে পারে

আপনি শুধু একটি কম অপ্রয়োজনীয় API প্রয়োজন।

pdo_query() আবদ্ধ পরামিতি জন্য খুব pdo_query() সমর্থন যোগ করে। পুরানো কোড রূপান্তর সহজবোধ্য:

এসকিউএল স্ট্রিং আউট আপনার ভেরিয়েবল সরান।

  • pdo_query() কমা বিভক্ত ফাংশন পরামিতি হিসাবে তাদের যোগ করুন।
  • প্রশ্ন চিহ্ন রাখুন ? স্থানধারক হিসাবে যেখানে ভেরিয়েবল আগে ছিল।
  • ' একক উদ্ধৃতিগুলি পরিত্রাণ পান যা পূর্বে স্ট্রিং মানগুলি / ভেরিয়েবলগুলি যুক্ত করেছিল।

সুবিধা দীর্ঘতর কোড জন্য আরো স্পষ্ট হয়ে ওঠে।

প্রায়শই স্ট্রিং ভেরিয়েবলগুলি কেবলমাত্র এসকিউএল-এ বিভক্ত নয়, তবে এর মধ্যবর্তী কলগুলি পাল্টে দেওয়া হয়।

pdo_query("SELECT id, links, html, title, user, date FROM articles
   WHERE title='" . pdo_real_escape_string($title) . "' OR id='".
   pdo_real_escape_string($title) . "' AND user <> '" .
   pdo_real_escape_string($root) . "' ORDER BY date")

সঙ্গে ? স্থানধারক প্রয়োগ করেছেন যেটি আপনাকে বিরক্ত করতে হবে না:

pdo_query("SELECT id, links, html, title, user, date FROM articles
   WHERE title=? OR id=? AND user<>? ORDER BY date", $title, $id, $root)

মনে রাখবেন যে pdo_ * এখনও বা হয়
শুধু একটি পরিবর্তনশীল অব্যাহতি না এবং একই প্রশ্নের মধ্যে এটি বাঁধ।

  • স্থানধারক বৈশিষ্ট্য এটি পিছনে আসল পিডিও দ্বারা উপলব্ধ করা হয়।
  • এছাড়াও অনুমোদিত :named পরে স্থানধারক তালিকা :named

আরো গুরুত্বপূর্ণভাবে আপনি কোন প্রশ্নটির পরে নিরাপদে $ _REQUEST [] ভেরিয়েবলগুলি পাস করতে পারেন। জমা দেওয়ার সময় <form> ক্ষেত্র ডাটাবেস গঠন ঠিক মিলছে এটি এমনকি ছোট:

pdo_query("INSERT INTO pages VALUES (?,?,?,?,?)", $_POST);

এত সরলতা। তবে আসুন আমরা আরো কিছু পুনর্লিখন পরামর্শ এবং প্রযুক্তিগত কারণে কেন আপনি mysql_ থেকে মুক্তি পেতে এবং পালিয়ে যেতে চান।

ফিক্স বা কোন oldschool sanitize() ফাংশন মুছে ফেলুন

একবার আপনি সমস্ত mysql_ কলগুলি pdo_query আবদ্ধ mysql_ রূপান্তরিত হয়ে গেলে, সমস্ত অপ্রয়োজনীয় pdo_real_escape_string কলগুলি সরান।

বিশেষ করে আপনাকে কোনও sanitize বা clean বা filterThis উচিত, অথবা এই filterThis বা clean_data ফাংশনটি এক ফর্ম বা অন্যের মধ্যে তারিখযুক্ত টিউটোরিয়াল দ্বারা বিজ্ঞাপিত করা উচিত:

function sanitize($str) {
   return trim(strip_tags(htmlentities(pdo_real_escape_string($str))));
}

এখানে সর্বাধিক glaring বাগ ডকুমেন্টেশন অভাব। আরো উল্লেখযোগ্যভাবে ফিল্টারিং অর্ডার ভুল আদেশ ছিল।

  • সঠিক htmlentities strip_tags অন্তর্মুখী কল হিসাবে strip_tags , তারপর trim , পরে strip_tags , আউটপুট প্রেক্ষাপটে htmlentities , এবং শেষ পর্যন্ত _escape_string এর অ্যাপ্লিকেশনটি সরাসরি এসকিউএল ইন্টারার্স্স্সিংকে এগিয়ে নিতে হবে।

  • কিন্তু প্রথম ধাপে শুধু _real_escape_string কল থেকে পরিত্রাণ পান

  • যদি আপনার ডাটাবেস এবং অ্যাপ্লিকেশন প্রবাহ HTML- প্রসঙ্গ-নিরাপদ স্ট্রিংগুলির প্রত্যাশা করে তবে আপনাকে আপনার বাকি sanitize() ফাংশনটি এখনই রাখতে হবে। একটি মন্তব্য যুক্ত করুন যে এটি এখন থেকে কেবলমাত্র HTML টি escaping প্রযোজ্য।

  • স্ট্রিং / মান হ্যান্ডলিংটি পিডিও এবং তার পরামিতিযুক্ত বিবৃতিতে উপস্থাপিত হয়।

  • আপনার স্যানিটাইজ ফাংশনে stripslashes() এর কোন উল্লেখ থাকলে, এটি একটি উচ্চ স্তরের তত্ত্বাবধান নির্দেশ করতে পারে।

    Magic_quotes উপর ঐতিহাসিক নোট। যে বৈশিষ্ট্য সঠিকভাবে বর্জন করা হয়। এটি প্রায়ই ভুল ত্রুটিপূর্ণ নিরাপত্তা বৈশিষ্ট্য হিসাবে চিত্রিত করা হয়। কিন্তু ম্যাজিক_কোটগুলি একটি ব্যর্থ নিরাপত্তা বৈশিষ্ট্য হিসাবে টেনিস বল পুষ্টি উৎস হিসাবে ব্যর্থ হয়েছে। যে কেবল তাদের উদ্দেশ্য ছিল না।

    পিএইচপি 2 / ফাই এর আসল বাস্তবায়নটি স্পষ্টতই " কোটগুলি স্বয়ংক্রিয়ভাবে এমএসকিএল প্রশ্নের সাথে ফর্ম তথ্য পাস করা সহজ করে তুলবে " এর সাথে স্পষ্টভাবে প্রকাশ করে। বিশেষত এটি mSQL ব্যবহার করার জন্য mSQL নিরাপদ ছিল, যেহেতু এটি শুধুমাত্র ASCII সমর্থিত।
    তারপর পিএইচপি 3 / জেন্ড মাইএসকিউএল-এর জন্য ম্যাজিক_কোটগুলি পুনঃপ্রবর্তন করে এবং এটি নথিভুক্ত করে। কিন্তু মূলত এটি কেবলমাত্র একটি সুবিধাজনক বৈশিষ্ট্য ছিল , সুরক্ষাটির জন্য নয়।

কিভাবে প্রস্তুত বিবৃতি ভিন্ন

যখন আপনি এসকিউএল ক্যোয়ারিতে স্ট্রিং ভেরিয়েবলগুলিকে ভঙ্গ করেন তখন এটি অনুসরণ করার জন্য এটি আরও জটিল নয়। এটা আবার MySQL কোড এবং তথ্য পৃথকীকরণ জন্য বহিরাগত প্রচেষ্টা।

কোড প্রেক্ষাপটে তথ্য bleeds যখন এসকিউএল ইনজেকশন সহজভাবে হয়। একটি ডাটাবেস সার্ভারটি পরে স্পট করতে পারে না যেখানে পিএইচপি মূলত গ্লুয়েড ভেরিয়েবলগুলি কোয়েরি ক্লজগুলির মধ্যে থাকে।

আবদ্ধ পরামিতিগুলির সাথে আপনি আপনার পিএইচপি কোডে এসকিউএল কোড এবং SQL- প্রসঙ্গ মান পৃথক করুন। কিন্তু দৃশ্যের পিছনে এটি আবার ফাঁস হয়ে যায় না (পিডিও :: EMULATE_PREPARES ছাড়া)। আপনার ডাটাবেস unvaried এসকিউএল কমান্ড এবং 1: 1 পরিবর্তনশীল মান প্রাপ্ত।

এই উত্তরটি stresses যে আপনি mysql_ ড্রপ করার পঠনযোগ্যতা সুবিধা সম্পর্কে যত্ন mysql_ । এই দৃশ্যমান এবং প্রযুক্তিগত ডেটা / কোড বিচ্ছেদের কারণে মাঝে মাঝে মাঝেও একটি কর্মক্ষমতা সুবিধা (কেবল ভিন্ন মান সহ পুনরাবৃত্ত INSERT গুলি)।

সীমাবদ্ধ যে পরামিতি সাবধানে সব এসকিউএল ইনজেকশন বিরুদ্ধে একটি জাদু এক স্টপ সমাধান নয় । এটি তথ্য / মানগুলির জন্য সর্বাধিক সাধারণ ব্যবহার পরিচালনা করে। তবে কলামের নাম / টেবিল সনাক্তকারীগুলিকে হোয়াইটলিস্ট করতে পারবেন না, গতিশীল বিভাগ নির্মাণের ক্ষেত্রে সহায়তা করতে, অথবা কেবল সাধারণ অ্যারের মান তালিকাতে সহায়তা করতে পারেন।

হাইব্রিড পিডিও ব্যবহার

এই pdo_* wrapper ফাংশন একটি কোডিং-বান্ধব স্টপ-ফাঁক API তৈরি করে। ( MYSQLI ফাংশন স্বাক্ষরিত শিফটের জন্য এটি না থাকলে এটি MYSQLI কী হতে পারে)। তারা বেশিরভাগ সময়ে আসল পিডিও প্রকাশ করে।
নতুন pdo_ ফাংশন নাম ব্যবহার করে রিটার্নিং বন্ধ করতে হবে না। আপনি প্রতিটি pdo_query () এক প্লেইন একাউন্টে প্লেইন-> () -> চালানো () কল করতে পারেন।

তবে আবার সহজে শুরু করা ভাল। উদাহরণস্বরূপ সাধারণ ফলাফল আনয়ন:

$result = pdo_query("SELECT * FROM tbl");
while ($row = pdo_fetch_assoc($result)) {

শুধু একটি foreach পুনরাবৃত্তি সঙ্গে প্রতিস্থাপিত করা যাবে:

foreach ($result as $row) {

অথবা ভাল এখনো একটি সরাসরি এবং সম্পূর্ণ অ্যারে পুনরুদ্ধার:

$result->fetchAll();

আপনি বেশিরভাগ ক্ষেত্রেই PDO বা mysql_ এর চেয়ে বেশি সহায়ক সতর্কতা পাবেন ব্যর্থ প্রশ্নগুলির পরে।

অন্যান্য অপশন

তাই এই আশা কিছু mysql_ ড্রপ করার জন্য কিছু বাস্তব কারণ এবং একটি worthwile পথ mysql_

শুধু pdo সুইচিং এটি বেশ কাটা না। pdo_query() এটি সম্মুখের শুধু একটি সম্মুখভাগ।

আপনি যদি প্যারামিটার বাইন্ডিং চালু না করেন বা নিকার API থেকে অন্য কিছু ব্যবহার করতে না পারেন তবে এটি একটি বিন্দুহীন সুইচ। আমি আশা করি এটি নতুনদের কাছে নিরুৎসাহিত না করার পক্ষে যথেষ্ট সহজ। (শিক্ষা সাধারণত নিষেধাজ্ঞা চেয়ে ভাল কাজ করে।)

এটি সহজ-জিনিস-যে-সম্ভব-সম্ভবত-কাজ বিভাগের জন্য যোগ্যতা অর্জন করে, এটি এখনও খুব পরীক্ষামূলক কোড। আমি শুধু সপ্তাহান্তে এটি লিখেছেন। তবে বিকল্পগুলির বেশিরভাগই আছে। শুধু পিএইচপি ডাটাবেস বিমূর্তকরণ জন্য গুগল এবং সামান্য ব্রাউজ করুন। এমন কাজগুলির জন্য সর্বদা চমৎকার লাইব্রেরি রয়েছে এবং সেখানে থাকবে।

আপনি যদি আপনার ডেটাবেস ইন্টারঅ্যাকশন আরও সহজ করতে চান তবে Paris/Idiorm মত Paris/Idiorm একটি চেষ্টা করার যোগ্য। জাভাস্ক্রিপ্টে ব্লুমড ডিওএম ব্যবহার করে কেউ কেউ আজকালই কাঁচা ডেটাবেস ইন্টারফেসকে আজকাল বেবিসিট করতে হবে না।

mysql_* জন্য mysql_* ফাংশন ব্যবহার করা উচিত নয় তা কারিগরি কারন? (যেমন mysql_query() , mysql_real_escape_string() অথবা mysql_real_escape_string() )?

কেন তারা আমার সাইটে কাজ করলেও আমি অন্য কিছু ব্যবহার করবো?

যদি তারা আমার সাইটে কাজ না করে তবে আমি কেন ত্রুটি পেতে পারি

সতর্কতা: mysql_connect (): কোনও ফাইল বা ডিরেক্টরি নেই


MySQL এক্সটেনশন:

  • সক্রিয় উন্নয়ন অধীনে না
  • পিএইচপি 5.5 ( আনুষ্ঠানিকভাবে ২013 সালের জুনে প্রকাশিত) হিসাবে deprecated করা deprecated
  • সম্পূর্ণরূপে পিএইচপি 7.0 হিসাবে removed হয়েছে (ডিসেম্বর 2015 মুক্তি)
    • এর মানে 31 ডিসেম্বর 2018 হিসাবে এটি পিএইচপি সমর্থিত সংস্করণে বিদ্যমান থাকবে না। বর্তমানে, এটি শুধুমাত্র নিরাপত্তা আপডেট পায়।
  • একটি OO ইন্টারফেস অভাব
  • সমর্থন করে না
    • অ ব্লকিং, অ্যাসিঙ্ক্রোনাস প্রশ্ন
    • প্রস্তুত বিবৃতি বা পরামিতি প্রশ্নের
    • সংরক্ষিত পদ্ধতি
    • একাধিক বিবৃতি
    • লেনদেন
    • "নতুন" পাসওয়ার্ড প্রমাণীকরণ পদ্ধতি (ডিফল্টরূপে MySQL 5.6 তে; 5.7 এ প্রয়োজন)
    • MySQL 5.1 এ সমস্ত কার্যকারিতা

যেহেতু এটি অব্যবহৃত, এটি ব্যবহার করে আপনার কোড কম ভবিষ্যতের প্রমাণ করে তোলে।

প্রস্তুত বিবৃতিগুলির জন্য সমর্থনের অভাব বিশেষত গুরুত্বপূর্ণ কারণ এটি একটি পৃথক ফাংশন কল দিয়ে নিজে থেকে পালিয়ে যাওয়ার পরিবর্তে বাহ্যিক ডেটা এড়িয়ে ও উদ্ধৃত করার একটি পরিষ্কার, কম ত্রুটি-প্রবণ পদ্ধতি সরবরাহ করে।

এসকিউএল এক্সটেনশন তুলনা দেখুন।


প্রথমত, আমরা মানক মন্তব্য দিয়ে শুরু করি যা আমরা সবাইকে দিই:

share । তারা আর রক্ষণাবেক্ষণ করা হয় না deprecatedলাল বক্স দেখুন ? পরিবর্তে প্রস্তুত বিবৃতি সম্পর্কে জানুন, এবং PDO বা MySQLi ব্যবহার করুন - এই নিবন্ধটি আপনাকে সিদ্ধান্ত নিতে সাহায্য করবে যা। আপনি যদি PDO নির্বাচন করেন, এখানে একটি ভাল টিউটোরিয়াল

চলুন এই বাক্যটি দিয়ে বাক্যটি পরিদর্শন করে ব্যাখ্যা করুন:

  • তারা আর রক্ষণাবেক্ষণ করা হয় না, এবং আনুষ্ঠানিকভাবে বর্জন করা হয়

    এর অর্থ হল পিএইচপি সম্প্রদায় এই ধীরে ধীরে এই পুরোনো ফাংশনগুলির জন্য সমর্থন হ্রাস করছে। তারা ভবিষ্যতে (সাম্প্রতিক) সংস্করণে বিদ্যমান নেই পিএইচপি এর সংস্করণ! এই ফাংশনগুলির ক্রমাগত ব্যবহার আপনার কোডটিকে (ভবিষ্যতে নয়) দূরে ভাঙ্গতে পারে।

    নতুন! - ext / mysql এখন deprecated

    নবীনতর! এক্সপি / MySQL মুছে ফেলা হয়েছে পিএইচপি 7

  • পরিবর্তে, আপনি প্রস্তুত বিবৃতি শিখতে হবে

    mysql_* এক্সটেনশানটি এসকিউএল ইনজেকশন এর বিরুদ্ধে একটি খুব কার্যকর countermeasure (যা অন্যান্য জিনিসের মধ্যে) যা প্রস্তুত বিবৃতিগুলিকে সমর্থন করে না। এটি মাইএসকিউএল নির্ভর অ্যাপ্লিকেশনগুলিতে একটি গুরুতর দুর্বলতা সংশোধন করে যা আক্রমণকারীদের আপনার স্ক্রিপ্টে অ্যাক্সেস পেতে এবং আপনার ডাটাবেসের কোনও সম্ভাব্য অনুসন্ধান সম্পাদন করতে দেয়।

    আরও তথ্যের জন্য, আমি কিভাবে পিএইচপি এ এসকিউএল ইনজেকশন প্রতিরোধ করতে পারি?

  • লাল বক্স দেখুন?

    যখন আপনি কোনও mysql ফাংশন ম্যানুয়াল পৃষ্ঠাতে যান, তখন আপনি একটি লাল বাক্স দেখেন, ব্যাখ্যা করে যে এটি আর ব্যবহার করা উচিত নয়।

  • পিডিও বা MySQLi ব্যবহার করুন

    আরও ভাল, আরো শক্তিশালী এবং ভালভাবে নির্মিত বিকল্পগুলি, PDO , যা ডাটাবেস ইন্টারঅ্যাকশনে সম্পূর্ণ MySQLi পদ্ধতির প্রস্তাব দেয় এবং MySQLi , যা একটি MySQL নির্দিষ্ট উন্নতি।


mysql_ * ফাংশনগুলি পছন্দের ( পিএইচপি 5.5 হিসাবে ) সত্য যে ফাংশন এবং কোড স্ট্রাকচারগুলি উন্নত করা হয়েছে। ফাংশনটি অব্যবহৃত হয়ে যাওয়ার অর্থ হল পারফরম্যান্স এবং নিরাপত্তা অনুসারে এটি আরও উন্নত করার কোনও প্রচেষ্টা করা হবে না, এর মানে এটি ভবিষ্যতের কম প্রমাণ

আপনি আরো কারণ প্রয়োজন হলে:

  • mysql_ * ফাংশন প্রস্তুত বিবৃতি সমর্থন করে না।
  • mysql_ * ফাংশন পরামিতি বাঁধাই সমর্থন করে না।
  • mysql_ * ক্রিয়াকলাপগুলি বস্তু ওরিয়েন্টেড প্রোগ্রামিংয়ের জন্য কার্যকারিতা অভাব করে।
  • তালিকা চলে যায় ...

এই উত্তরটি খারাপ লেখার পিএইচপি ব্যবহারকারী-যাচাইকরণ কোড, কীভাবে (এবং কী ব্যবহার করা হচ্ছে) কীভাবে কাজ করে এবং কীভাবে পুরানো MySQL ফাংশনগুলিকে সুরক্ষিত প্রস্তুত বিবৃতির সাথে প্রতিস্থাপন করতে হয় তা কতটা তুচ্ছ তা দেখানোর জন্য লেখা হয় - এবং মূলত স্ট্যাকঅভারফ্লো ব্যবহারকারী কেন (সম্ভবত অনেক প্রতিপালকের সাথে) নতুন ব্যবহারকারীদের কাছে তাদের কোড উন্নত করতে প্রশ্ন জিজ্ঞাসা করছে।

প্রথম বন্ধ, এই পরীক্ষা mysql ডাটাবেস তৈরি করতে বিনা দ্বিধায় দয়া করে (আমি আমার প্রিপেইড বলা হয়েছে):

mysql> create table users(
    -> id int(2) primary key auto_increment,
    -> userid tinytext,
    -> pass tinytext);
Query OK, 0 rows affected (0.05 sec)

mysql> insert into users values(null, 'Fluffeh', 'mypass');
Query OK, 1 row affected (0.04 sec)

mysql> create user 'prepared'@'localhost' identified by 'example';
Query OK, 0 rows affected (0.01 sec)

mysql> grant all privileges on prep.* to 'prepared'@'localhost' with grant option;
Query OK, 0 rows affected (0.00 sec)

যে কাজ করে, আমরা আমাদের পিএইচপি কোড করতে পারেন।

নিম্নোক্ত স্ক্রিপ্টটি কোনও ওয়েবসাইটে অ্যাডমিনের জন্য যাচাই প্রক্রিয়াটি যাচাই করা যাক (সরলীকৃত কিন্তু আপনি কপি এবং পরীক্ষার জন্য এটি ব্যবহার করলে কাজ করছেন):

<?php 

    if(!empty($_POST['user']))
    {
        $user=$_POST['user'];
    }   
    else
    {
        $user='bob';
    }
    if(!empty($_POST['pass']))
    {
        $pass=$_POST['pass'];
    }
    else
    {
        $pass='bob';
    }

    $database='prep';
    $link=mysql_connect('localhost', 'prepared', 'example');
    mysql_select_db($database) or die( "Unable to select database");

    $sql="select id, userid, pass from users where userid='$user' and pass='$pass'";
    //echo $sql."<br><br>";
    $result=mysql_query($sql);
    $isAdmin=false;
    while ($row = mysql_fetch_assoc($result)) {
        echo "My id is ".$row['id']." and my username is ".$row['userid']." and lastly, my password is ".$row['pass']."<br>";
        $isAdmin=true;
        // We have correctly matched the Username and Password
        // Lets give this person full access
    }
    if($isAdmin)
    {
        echo "The check passed. We have a verified admin!<br>";
    }
    else
    {
        echo "You could not be verified. Please try again...<br>";
    }
    mysql_close($link);

?>

<form name="exploited" method='post'>
    User: <input type='text' name='user'><br>
    Pass: <input type='text' name='pass'><br>
    <input type='submit'>
</form>

প্রথম নজরে পর্যাপ্ত legit মনে হয়।

ব্যবহারকারী লগইন এবং পাসওয়ার্ড প্রবেশ করতে হবে, অধিকার?

উজ্জ্বল, নিম্নলিখিত লিখুন না:

user: bob
pass: somePass

এবং এটি জমা দিন।

নিম্নরূপ আউটপুট হয়:

You could not be verified. Please try again...

সুপার! প্রত্যাশিত হিসাবে কাজ করে, এখন আসল ব্যবহারকারীর নাম এবং পাসওয়ার্ড চেষ্টা করে দেখুন:

user: Fluffeh
pass: mypass

অ্যামেজিং! Hi-fives সব বৃত্তাকার, কোড সঠিকভাবে একটি অ্যাডমিন যাচাই। এইটা ঠিক আছে!

সত্যিই ভাল না. চলুন ব্যবহারকারী একটি চতুর চতুর ব্যক্তি বলুন। চলুন বলুন লোকটি আমাকে।

নিম্নলিখিত লিখুন:

user: bob
pass: n' or 1=1 or 'm=m

এবং আউটপুট হয়:

The check passed. We have a verified admin!

অভিনন্দন, আপনি আমাকে একটি মিথ্যা ব্যবহারকারীর নাম এবং একটি মিথ্যা পাসওয়ার্ড প্রবেশ করে শুধুমাত্র আমার বিভাগে আপনার সুরক্ষিত-সুরক্ষিত প্রশাসকগুলি প্রবেশ করার অনুমতি দিয়েছেন। গুরুতরভাবে, যদি আপনি আমাকে বিশ্বাস করেন না তবে আমি যে কোডটি দিয়েছি তার সাথে ডাটাবেস তৈরি করুন এবং এই পিএইচপি কোডটি চালান - যা নজরে আসলেই ব্যবহারকারীর নাম এবং পাসওয়ার্ডটি সুন্দরভাবে যাচাই করে।

সুতরাং, উত্তরে, কেন আপনি এটি চালু হচ্ছে হচ্ছে।

সুতরাং, কি ভুল হয়েছে তা একবার দেখে নিন এবং কেন আমি আপনার অতি-অ্যাডমিন-কেবল-ব্যাট-গুহায় ঢুকলাম। আমি একটি অনুমান নিয়েছিলাম এবং আপনি আপনার ইনপুটগুলির সাথে সতর্কতা অবলম্বন করে নিচ্ছেন এবং সরাসরি সেগুলি সরাসরি ডেটাবেসে প্রেরণ করেছেন বলে ধরেছেন। আমি একটি উপায় ইনপুট নির্মিত tht আপনি আসলে চলমান ছিল যে পরিবর্তন পরিবর্তন করবে। সুতরাং, এটা কি অনুমিত ছিল, এবং এটি শেষ পর্যন্ত কি শেষ?

select id, userid, pass from users where userid='$user' and pass='$pass'

এটিই প্রশ্ন, কিন্তু আমরা যখন ব্যবহারযোগ্য প্রকৃত ইনপুটগুলির সাথে ভেরিয়েবলগুলি প্রতিস্থাপন করি, তখন আমরা নিম্নলিখিতগুলি পাই:

select id, userid, pass from users where userid='bob' and pass='n' or 1=1 or 'm=m'

দেখুন কিভাবে আমি আমার "পাসওয়ার্ড" তৈরি করেছি যাতে এটি প্রথমে পাসওয়ার্ডের প্রায় একক উদ্ধৃতি বন্ধ করে দেবে, তারপরে সম্পূর্ণ নতুন তুলনাটি পরিচয় করিয়ে দেবে? তারপরে নিরাপত্তার জন্য, আমি আরেকটি "স্ট্রিং" যোগ করেছি যাতে আমরা যে কোডটি পেয়েছিলাম তার মধ্যে প্রত্যাশিত হিসাবে একক উদ্ধৃতি বন্ধ হয়ে যাবে।

তবে, এই লোকেরা এখন আপনার কাছে চিৎকার করছে না, এটি আপনাকে আপনার কোডকে আরো নিরাপদ করে তুলতে আপনাকে দেখানো সম্পর্কে নয়।

ঠিক আছে, তাই কি ভুল হয়েছে, এবং কিভাবে আমরা এটা ঠিক করতে পারি?

এটি একটি ক্লাসিক এসকিউএল ইনজেকশন আক্রমণ। যে বিষয়টি জন্য সহজতম এক। আক্রমণ ভেক্টরের স্কেলে, এটি একটি ট্যাবলেট আক্রমণকারী একটি ট্যাংক - এবং জিতেছে।

সুতরাং, আমরা কিভাবে আপনার পবিত্র অ্যাডমিন বিভাগ রক্ষা এবং এটি সুন্দর এবং নিরাপদ করা? করতে হবে প্রথম জিনিস সত্যিই যারা পুরানো এবং অব্যবহৃত mysql_*ফাংশন ব্যবহার বন্ধ করা হবে । আমি জানি, আপনি অনলাইনে পাওয়া একটি টিউটোরিয়ালটি অনুসরণ করেছেন এবং এটি কাজ করে, তবে এটি পুরানো, এটি পুরানো এবং কয়েক মিনিটের জায়গাতেই আমি একটি ঘাম ভেঙে এতটুকু ছাড়াই তা ভেঙে ফেলেছি।

এখন, আপনার mysqli_ বা PDO ব্যবহার করার জন্য আরও ভাল বিকল্প PDO । আমি ব্যক্তিগতভাবে PDO এর একটি বড় ফ্যান, তাই আমি এই উত্তর বাকি PDO ব্যবহার করা হবে। প্রো এবং কন এর আছে, কিন্তু ব্যক্তিগতভাবে আমি খুঁজে পাই যে প্রো এর তুলনায় অনেক দূরে। এটি একাধিক ডাটাবেস ইঞ্জিনে পোর্টেবল - যদি আপনি মাইএসকিউএল বা ওরাকল ব্যবহার করছেন বা শুধু রক্তাক্ত কিছু ব্যবহার করছেন - কেবল সংযোগ স্ট্রিংটি পরিবর্তন করে, এটির সমস্ত বৈশিষ্ট্য রয়েছে যা আমরা ব্যবহার করতে চাই এবং এটি চমৎকার এবং পরিচ্ছন্ন। আমি পরিষ্কার চাই।

এখন, আবার সেই কোডটি দেখুন, এই সময় একটি PDO অবজেক্ট ব্যবহার করে লেখা হয়েছে:

<?php 

    if(!empty($_POST['user']))
    {
        $user=$_POST['user'];
    }   
    else
    {
        $user='bob';
    }
    if(!empty($_POST['pass']))
    {
        $pass=$_POST['pass'];
    }
    else
    {
        $pass='bob';
    }
    $isAdmin=false;

    $database='prep';
    $pdo=new PDO ('mysql:host=localhost;dbname=prep', 'prepared', 'example');
    $sql="select id, userid, pass from users where userid=:user and pass=:password";
    $myPDO = $pdo->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
    if($myPDO->execute(array(':user' => $user, ':password' => $pass)))
    {
        while($row=$myPDO->fetch(PDO::FETCH_ASSOC))
        {
            echo "My id is ".$row['id']." and my username is ".$row['userid']." and lastly, my password is ".$row['pass']."<br>";
            $isAdmin=true;
            // We have correctly matched the Username and Password
            // Lets give this person full access
        }
    }

    if($isAdmin)
    {
        echo "The check passed. We have a verified admin!<br>";
    }
    else
    {
        echo "You could not be verified. Please try again...<br>";
    }

?>

<form name="exploited" method='post'>
    User: <input type='text' name='user'><br>
    Pass: <input type='text' name='pass'><br>
    <input type='submit'>
</form>

প্রধান পার্থক্য যে কোন mysql_*ফাংশন আছে। এটি সমস্ত একটি PDO বস্তুর মাধ্যমে সম্পন্ন করা হয়, দ্বিতীয়ত, এটি একটি প্রস্তুত বিবৃতি ব্যবহার করা হয়। এখন, আপনি একটি প্রিপ্রেড বিবৃতি কি জিজ্ঞাসা? এটি একটি প্রশ্ন চালানোর আগে ডেটাবেসকে বলার উপায়, কোন প্রশ্নটি আমরা চালানোর জন্য যাচ্ছি। এই ক্ষেত্রে, আমরা ডেটাবেসকে বলি: "হাই, আমি একটি আইডি, ইউজার আইডির জন্য একটি পছন্দসই বিবৃতি চালাতে যাচ্ছি এবং টেবিল ব্যবহারকারীদের কাছ থেকে পাস করব যেখানে ইউজার আইডি একটি পরিবর্তনশীল এবং পাসও একটি পরিবর্তনশীল।"

তারপর, কার্যকর বিবৃতিতে, আমরা ডাটাবেসের একটি অ্যারে পাস করি যা সমস্ত ভেরিয়েবলের সাথে এটি এখন প্রত্যাশা করে।

ফলাফল চমত্কার। আসুন আবার ব্যবহারকারীর নাম এবং পাসওয়ার্ড সমন্বয় চেষ্টা করে দেখুন:

user: bob
pass: somePass

ব্যবহারকারী যাচাই করা হয় নি। অসাধারণ.

কেমন:

user: Fluffeh
pass: mypass

ওহ, আমি একটু উত্তেজিত হয়েছি, এটি কাজ করেছে: চেক পাস হয়েছে। আমরা একটি যাচাই প্রশাসক আছে!

এখন, আমাদের ডেটা চেষ্টা করে দেখুন যে একটি চতুর চ্যাপটি আমাদের সামান্য যাচাইকরণ পদ্ধতিটি পেতে চেষ্টা করবে:

user: bob
pass: n' or 1=1 or 'm=m

এই সময়, আমরা নিম্নলিখিত পেতে:

You could not be verified. Please try again...

এই কারণেই প্রশ্ন পোস্ট করার সময়ে আপনাকে চিৎকার করা হচ্ছে - এটি এমন কারণ যে লোকেরা দেখতে পারে যে আপনার কোডটি এমনকি চেষ্টা না করেই ছাড়িয়ে যেতে পারে। দয়া করে, এই প্রশ্নটি ব্যবহার করুন এবং আপনার কোড উন্নত করার জন্য এটি আরও নিরাপদ এবং বর্তমান ক্রিয়াকলাপগুলি ব্যবহার করুন।

অবশেষে, এটি এই সম্পূর্ণ কোড বলে না। আরও অনেক কিছু আছে যা আপনি এটি উন্নত করতে পারেন, উদাহরণস্বরূপ হ্যাশ পাসওয়ার্ডগুলি ব্যবহার করুন, নিশ্চিত করুন যে যখন আপনি ডাটাবেসগুলিতে সংবেদনশীল তথ্য সঞ্চয় করেন তখন আপনি এটি সাধারণ প্লেইনটিতে সংরক্ষণ করবেন না, যাচাইকরণের একাধিক স্তর আছে - কিন্তু যদি সত্যিই আপনি শুধু আপনার পুরানো ইনজেকশন প্রবণ কোডটি পরিবর্তন করুন, আপনি ভাল কোড লেখার পাশাপাশি ভাল হবেন - এবং আপনি যে পর্যন্ত এটি অর্জন করেছেন এবং এখনও পড়ছেন তা আমাকে একটি ধারনা দেয় যে আপনি কেবল এই ধরনের প্রয়োগটিই করবেন না আপনার ওয়েবসাইটগুলি এবং অ্যাপ্লিকেশনগুলি লেখার সময় কোডটি ব্যবহার করে, তবে আপনি যেসব জিনিসগুলিকে আমি ঠিক উল্লিখিত করেছি - এবং আরও কিছু অনুসন্ধান করতে পারেন। সেরা কোডটি লিখুন যা আপনি করতে পারেন, সবচেয়ে মৌলিক কোড যা সবেমাত্র কাজ করে না।


mysql_*MySQLi বা PDO ব্যবহার করে প্রায় সব ফাংশন সংজ্ঞায়িত করা সম্ভব । শুধু আপনার পুরানো পিএইচপি অ্যাপ্লিকেশন উপরে তাদের অন্তর্ভুক্ত করুন, এবং এটি পিএইচপি 7 কাজ করবে। আমার সমাধান here

<?php

define('MYSQL_LINK', 'dbl');
$GLOBALS[MYSQL_LINK] = null;

function mysql_link($link=null) {
    return ($link === null) ? $GLOBALS[MYSQL_LINK] : $link;
}

function mysql_connect($host, $user, $pass) {
    $GLOBALS[MYSQL_LINK] = mysqli_connect($host, $user, $pass);
    return $GLOBALS[MYSQL_LINK];
}

function mysql_pconnect($host, $user, $pass) {
    return mysql_connect($host, $user, $pass);
}

function mysql_select_db($db, $link=null) {
    $link = mysql_link($link);
    return mysqli_select_db($link, $db);
}

function mysql_close($link=null) {
    $link = mysql_link($link);
    return mysqli_close($link);
}

function mysql_error($link=null) {
    $link = mysql_link($link);
    return mysqli_error($link);
}

function mysql_errno($link=null) {
    $link = mysql_link($link);
    return mysqli_errno($link);
}

function mysql_ping($link=null) {
    $link = mysql_link($link);
    return mysqli_ping($link);
}

function mysql_stat($link=null) {
    $link = mysql_link($link);
    return mysqli_stat($link);
}

function mysql_affected_rows($link=null) {
    $link = mysql_link($link);
    return mysqli_affected_rows($link);
}

function mysql_client_encoding($link=null) {
    $link = mysql_link($link);
    return mysqli_character_set_name($link);
}

function mysql_thread_id($link=null) {
    $link = mysql_link($link);
    return mysqli_thread_id($link);
}

function mysql_escape_string($string) {
    return mysql_real_escape_string($string);
}

function mysql_real_escape_string($string, $link=null) {
    $link = mysql_link($link);
    return mysqli_real_escape_string($link, $string);
}

function mysql_query($sql, $link=null) {
    $link = mysql_link($link);
    return mysqli_query($link, $sql);
}

function mysql_unbuffered_query($sql, $link=null) {
    $link = mysql_link($link);
    return mysqli_query($link, $sql, MYSQLI_USE_RESULT);
}

function mysql_set_charset($charset, $link=null){
    $link = mysql_link($link);
    return mysqli_set_charset($link, $charset);
}

function mysql_get_host_info($link=null) {
    $link = mysql_link($link);
    return mysqli_get_host_info($link);
}

function mysql_get_proto_info($link=null) {
    $link = mysql_link($link);
    return mysqli_get_proto_info($link);
}
function mysql_get_server_info($link=null) {
    $link = mysql_link($link);
    return mysqli_get_server_info($link);
}

function mysql_info($link=null) {
    $link = mysql_link($link);
    return mysqli_info($link);
}

function mysql_get_client_info() {
    $link = mysql_link();
    return mysqli_get_client_info($link);
}

function mysql_create_db($db, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    return mysqli_query($link, "CREATE DATABASE `$db`");
}

function mysql_drop_db($db, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    return mysqli_query($link, "DROP DATABASE `$db`");
}

function mysql_list_dbs($link=null) {
    $link = mysql_link($link);
    return mysqli_query($link, "SHOW DATABASES");
}

function mysql_list_fields($db, $table, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    $table = str_replace('`', '', mysqli_real_escape_string($link, $table));
    return mysqli_query($link, "SHOW COLUMNS FROM `$db`.`$table`");
}

function mysql_list_tables($db, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    return mysqli_query($link, "SHOW TABLES FROM `$db`");
}

function mysql_db_query($db, $sql, $link=null) {
    $link = mysql_link($link);
    mysqli_select_db($link, $db);
    return mysqli_query($link, $sql);
}

function mysql_fetch_row($qlink) {
    return mysqli_fetch_row($qlink);
}

function mysql_fetch_assoc($qlink) {
    return mysqli_fetch_assoc($qlink);
}

function mysql_fetch_array($qlink, $result=MYSQLI_BOTH) {
    return mysqli_fetch_array($qlink, $result);
}

function mysql_fetch_lengths($qlink) {
    return mysqli_fetch_lengths($qlink);
}

function mysql_insert_id($qlink) {
    return mysqli_insert_id($qlink);
}

function mysql_num_rows($qlink) {
    return mysqli_num_rows($qlink);
}

function mysql_num_fields($qlink) {
    return mysqli_num_fields($qlink);
}

function mysql_data_seek($qlink, $row) {
    return mysqli_data_seek($qlink, $row);
}

function mysql_field_seek($qlink, $offset) {
    return mysqli_field_seek($qlink, $offset);
}

function mysql_fetch_object($qlink, $class="stdClass", array $params=null) {
    return ($params === null)
        ? mysqli_fetch_object($qlink, $class)
        : mysqli_fetch_object($qlink, $class, $params);
}

function mysql_db_name($qlink, $row, $field='Database') {
    mysqli_data_seek($qlink, $row);
    $db = mysqli_fetch_assoc($qlink);
    return $db[$field];
}

function mysql_fetch_field($qlink, $offset=null) {
    if ($offset !== null)
        mysqli_field_seek($qlink, $offset);
    return mysqli_fetch_field($qlink);
}

function mysql_result($qlink, $offset, $field=0) {
    if ($offset !== null)
        mysqli_field_seek($qlink, $offset);
    $row = mysqli_fetch_array($qlink);
    return (!is_array($row) || !isset($row[$field]))
        ? false
        : $row[$field];
}

function mysql_field_len($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    return is_object($field) ? $field->length : false;
}

function mysql_field_name($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    if (!is_object($field))
        return false;
    return empty($field->orgname) ? $field->name : $field->orgname;
}

function mysql_field_table($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    if (!is_object($field))
        return false;
    return empty($field->orgtable) ? $field->table : $field->orgtable;
}

function mysql_field_type($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    return is_object($field) ? $field->type : false;
}

function mysql_free_result($qlink) {
    try {
        mysqli_free_result($qlink);
    } catch (Exception $e) {
        return false;
    }
    return true;
}

কারিগরি কারণে বলার অপেক্ষা রাখে না, শুধুমাত্র কয়েকটি, অত্যন্ত নির্দিষ্ট এবং খুব কমই ব্যবহৃত হয়। সম্ভবত আপনি কখনও আপনার জীবনে তাদের ব্যবহার করবে না।
হয়তো আমি খুব অজ্ঞান, কিন্তু আমি তাদের মত জিনিস ব্যবহার করার সুযোগ ছিল না

  • অ ব্লকিং, অ্যাসিঙ্ক্রোনাস প্রশ্ন
  • একাধিক ফলাফল ফিরে সঞ্চিত পদ্ধতি
  • এনক্রিপশন (এসএসএস)
  • সঙ্কোচন

যদি আপনার তাদের দরকার হয় - তবে এটি কোন সন্দেহজনক বিষয় নয় যে মাইএসএলএল এক্সটেনশান থেকে আরো কিছু আড়ম্বরপূর্ণ এবং আধুনিক চেহারা দিকে সরাতে প্রযুক্তিগত কারণ।

তবুও, কিছু অ-প্রযুক্তিগত সমস্যাও রয়েছে যা আপনার অভিজ্ঞতাটি আরও কঠিন করে তুলতে পারে

  • আধুনিক পিএইচপি সংস্করণের সাথে এই ফাংশনগুলির আরও ব্যবহার বর্জনযোগ্য স্তরের বিজ্ঞপ্তিগুলি বাড়াবে। তারা কেবল বন্ধ করা যাবে।
  • একটি দূরবর্তী ভবিষ্যতে, তারা সম্ভবত ডিফল্ট পিএইচপি বিল্ড থেকে সরানো যেতে পারে। একটি বড় চুক্তিও নয়, কারণ মাইডসএলএল এক্সটি পিইসিএল-এ সরানো হবে এবং প্রতিটি হোস্টার এটির সাথে পিএইচপি কম্পাইল করতে পেরে খুশি হবে, কারণ তারা কয়েক সপ্তাহ ধরে ক্লায়েন্টদের সাইটগুলি হারাতে চাইছেন না।
  • সম্প্রদায় থেকে শক্তিশালী প্রতিরোধের। আপনি সর্বদা এই সৎ ফাংশন উল্লেখ, আপনি বলা হয় যে তারা কঠোর নিষিদ্ধ অধীনে।
  • গড় পিএইচপি ব্যবহারকারী হওয়া, সম্ভবত এই ফাংশন ব্যবহার করার আপনার ধারণা ত্রুটি-প্রবণ এবং ভুল। শুধু এই অসংখ্য টিউটোরিয়াল এবং ম্যানুয়ালগুলি যা আপনাকে ভুল পথে শিক্ষা দেয়। ফাংশনগুলি নিজেই নয় - আমাকে এটি জোরদার করতে হবে - কিন্তু সেগুলি কীভাবে ব্যবহার করা হয়।

এই পরের সমস্যা একটি সমস্যা।
কিন্তু, আমার মতে, প্রস্তাবিত সমাধানটি ভাল নয়।
এটি আমার কাছে খুব আদর্শবাদী একটি স্বপ্ন দেখে মনে হচ্ছে যে এগুলি পিএইচপি ব্যবহারকারীরা একবারে সঠিকভাবে এসকিউএল প্রশ্নগুলি কীভাবে পরিচালনা করবেন তা শিখবে। সর্বাধিক সম্ভবত তারা mysql_ * mysqli_ * তে যান্ত্রিকভাবে পরিবর্তন করবে, একই পদ্ধতিটি একইভাবে ছেড়ে দেবে । বিশেষত কারণ mysqli তৈরি বিবৃতি ব্যবহার করে অবিশ্বাস্য বেদনাদায়ক এবং বিরক্তিকর।
উল্লেখ্য যে স্থানীয় প্রস্তুত বিবৃতিগুলি এসকিউএল ইনজেকশন থেকে রক্ষা করার জন্য যথেষ্ট নয় , এবং না MySQLi বা PDO একটি সমাধান সরবরাহ করে।

সুতরাং, এই সৎ এক্সটেনশানটি যুদ্ধ করার পরিবর্তে, আমি ভুল অনুশীলনগুলি এবং জনগণকে সঠিকভাবে শিক্ষিত করতে পছন্দ করি।

এছাড়াও, কিছু মিথ্যা বা অ উল্লেখযোগ্য কারণ আছে, যেমন

  • সংরক্ষিত পদ্ধতি সমর্থন করে না (আমরা mysql_query("CALL my_proc");বয়সের জন্য ব্যবহার করা হয়)
  • লেনদেন সমর্থন করে না (উপরের হিসাবে একই)
  • একাধিক বিবৃতি সমর্থন করে না (যারা তাদের প্রয়োজন?)
  • না সক্রিয় উন্নয়ন অধীনে (তাই কি? এটা প্রভাবিত করে আপনি কোন ব্যবহারিক ভাবে?)
  • OO ইন্টারফেসকে ছাড়িয়ে যায় (এক তৈরি করতে কয়েক ঘন্টা সময় লাগবে)
  • প্রস্তুত বিবৃতি বা Parametrized প্রশ্নের সমর্থন করে না

শেষ এক একটি আকর্ষণীয় পয়েন্ট। যদিও মাইএসকিউএল এক্সটি স্থানীয় প্রস্তুত বিবৃতিগুলিকে সমর্থন করে না তবে সেগুলি নিরাপত্তার জন্য প্রয়োজন হয় না। ম্যানুয়ালি পরিচালিত স্থানধারক ব্যবহার করে আমরা সহজেই জাল প্রস্তুত বিবৃতিগুলি তৈরি করতে পারি (ঠিক যেমন পিডিও করে):

function paraQuery()
{
    $args  = func_get_args();
    $query = array_shift($args);
    $query = str_replace("%s","'%s'",$query); 

    foreach ($args as $key => $val)
    {
        $args[$key] = mysql_real_escape_string($val);
    }

    $query  = vsprintf($query, $args);
    $result = mysql_query($query);
    if (!$result)
    {
        throw new Exception(mysql_error()." [$query]");
    }
    return $result;
}

$query  = "SELECT * FROM table where a=%s AND b LIKE %s LIMIT %d";
$result = paraQuery($query, $a, "%$b%", $limit);

voila , সবকিছু পরামিতি এবং নিরাপদ।

কিন্তু ঠিক আছে, যদি আপনি ম্যানুয়ালের লাল বাক্সটি পছন্দ করেন না, তবে পছন্দসই একটি সমস্যা দেখা দেয়: Mysqli বা PDO?

ভাল, উত্তর নিম্নরূপ হবে:

  • আপনি ডাটাবেস বিমূর্তকরণ স্তর ব্যবহার এবং একটি তৈরি করার জন্য API খোঁজার প্রয়োজনীয়তা বুঝতে পারলে , mysqli একটি খুব ভাল পছন্দ, কারণ এটি প্রকৃতপক্ষে অনেক MySQL-নির্দিষ্ট বৈশিষ্ট্যগুলিকে সমর্থন করে।
  • যদি পিএইচপি ফোনের বিশাল সংখ্যার মত, আপনি সঠিকভাবে অ্যাপ্লিকেশন কোড (যা মূলত ভুল অনুশীলন) তে কাঁচা API কল ব্যবহার করছেন - পিডিও একমাত্র পছন্দ , কেননা এই এক্সটেনশানটি কেবল API নয় বরং একটি আধা-ডাল বলে দাবি করে, এখনও অসম্পূর্ণ কিন্তু অনেক গুরুত্বপূর্ণ বৈশিষ্ট্য সরবরাহ করে, এদের মধ্যে দুটি পিডিও সমালোচিতভাবে মাইস্ক্লি থেকে পৃথক করে তোলে:

    • Mysqli অসদৃশ, পিডিও স্থানধারক দ্বারা মান দ্বারা আবদ্ধ করতে পারেন , যা গতিশীলভাবে নির্মিত প্রশ্ন বেশ নোংরা কোড বিভিন্ন পর্দা ছাড়া সম্ভব।
    • MySQLi এর বিপরীতে, পিডিও সর্বদা সাধারণ সাধারণ অ্যারের মধ্যে কোয়েরি ফলাফলটি ফেরত দিতে পারে, যখন MySQL এটি শুধুমাত্র MySQL ইনস্টলগুলিতে করতে পারে।

সুতরাং, যদি আপনি একজন গড় পিএইচপি ব্যবহারকারী হন এবং স্থানীয় প্রস্তুত বিবৃতিগুলি ব্যবহার করার সময় নিজের মাথাব্যাথাগুলির একটি টন সংরক্ষণ করতে চান তবে পিডিও - আবার - একমাত্র পছন্দ।
যাইহোক, পিডিও একটি রূপালী বুলেট না এবং তার কষ্ট আছে।
সুতরাং, আমি PDO ট্যাগ উইকি-তে সমস্ত সাধারণ সমস্যা এবং জটিল ক্ষেত্রে সমাধানগুলি লিখেছি

যাইহোক, এক্সটেনশন সম্পর্কে কথা বলা প্রত্যেকেরই সবসময় Mysqli এবং PDO সম্পর্কে 2 গুরুত্বপূর্ণ তথ্য অনুপস্থিত :

  1. প্রস্তুত বিবৃতি একটি রূপালী বুলেট না । ডাইনামিক্যাল আইডেন্টিফায়ার রয়েছে যা প্রস্তুত বিবৃতি ব্যবহার করে আবদ্ধ হতে পারে না। একটি অজানা সংখ্যক পরামিতিগুলির সাথে গতিশীল প্রশ্ন রয়েছে যা ক্যোয়ারী বিল্ডিংকে কঠিন কাজ করে তোলে।

  2. Neither mysqli_ * অথবা পিডিও ফাংশনগুলি অ্যাপ্লিকেশন কোডে উপস্থিত হওয়া উচিত ছিল না। তাদের এবং অ্যাপ্লিকেশন কোডের মধ্যে
    একটি বিমূর্তকরণ স্তর থাকা উচিত, যা বাইন্ডিং, লুপিং, ত্রুটি হ্যান্ডলিং ইত্যাদির সমস্ত নোংরা কাজ করবে, অ্যাপ্লিকেশন কোডটি DRY এবং পরিচ্ছন্ন করে তুলবে। বিশেষত জটিল ক্ষেত্রে যেমন গতিশীল ক্যোয়ারী বিল্ডিং।

তাই, শুধু পিডিও বা মাইসক্লি তে স্যুইচ করা যথেষ্ট নয়। কাউকে তাদের কোডে কাঁচা API ফাংশন কল করার পরিবর্তে একটি ORM, বা একটি ক্রেতা নির্মাতা বা কোনও ডেটাবেস বিমূর্ত শ্রেণী ব্যবহার করতে হবে।
এবং বিপরীত - যদি আপনার অ্যাপ্লিকেশন কোড এবং mysql API এর মধ্যে একটি বিমূর্তকরণ স্তর থাকে - এটি আসলে কোন ইঞ্জিন ব্যবহার করা হয় তা কোন ব্যাপার না। আপনি MySQL ext ব্যবহার করতে পারবেন না যতক্ষণ না এটি অপ্রয়োজনীয় হয়ে যায় এবং তারপরে আপনার এক্সট্রাস্টक्शन ক্লাসটি অন্য ইঞ্জিনে সহজেই পুনর্লিখন করে, সমস্ত অ্যাপ্লিকেশন কোড অক্ষত থাকে।

এই ধরনের একটি বিমূর্ত শ্রেণী কীভাবে হওয়া উচিত তা দেখানোর জন্য এখানে আমার Safemysql ক্লাসের উপর ভিত্তি করে কিছু উদাহরণ দেওয়া হয়েছে:

$city_ids = array(1,2,3);
$cities   = $db->getCol("SELECT name FROM cities WHERE is IN(?a)", $city_ids);

পিডিওর সাথে আপনার প্রয়োজনীয় কোডের পরিমাণ সহ এই একক লাইন তুলনা করুন ।
তারপর কাঁচা মাইস্ক্লি প্রস্তুত বিবৃতির সাথে আপনার প্রয়োজনীয় কোডের পাগল পরিমাণের সাথে তুলনা করুন । মনে রাখবেন যে ত্রুটি হ্যান্ডলিং, প্রোফাইলিং, ক্যোয়ারী লগিং ইতিমধ্যেই তৈরি এবং চলছে।

$insert = array('name' => 'John', 'surname' => "O'Hara");
$db->query("INSERT INTO users SET ?u", $insert);

স্বাভাবিক পিডিও সন্নিবেশের সাথে এটি তুলনা করুন, যখন প্রতিটি একক ক্ষেত্র নাম ছয় থেকে দশ বার পুনরাবৃত্তি করা হয় - এই সমস্ত নামযুক্ত স্থানধারক, বাইন্ডিং এবং ক্যোয়ারী সংজ্ঞাগুলিতে।

আরেকটি উদাহরণ:

$data = $db->getAll("SELECT * FROM goods ORDER BY ?n", $_GET['order']);

আপনি PDO যেমন বাস্তব ক্ষেত্রে হ্যান্ডেল করতে একটি উদাহরণ খুঁজে পেতে পারেন।
এবং এটি খুব শব্দবিহীন এবং সম্ভবত অনিরাপদ হতে হবে।

সুতরাং, আরো একবার - এটি কেবলমাত্র কাঁচা ড্রাইভার নয় তবে উদ্বেগের শ্রেণী হওয়া উচিত নয়, কেবল শিক্ষানবিসীর ম্যানুয়াল থেকে নিরীহ উদাহরণগুলির জন্য নয় বরং বাস্তব জীবনের সমস্যাগুলির সমাধান করার জন্য দরকারী।


অনেকগুলি কারণ রয়েছে, তবে সম্ভবত সবচেয়ে গুরুত্বপূর্ণ বিষয় হল যে সেই ক্রিয়াকলাপগুলি অনিরাপদ প্রোগ্রামিং অনুশীলনগুলিকে উত্সাহ দেয় কারণ তারা প্রস্তুত বিবৃতিগুলিকে সমর্থন করে না। প্রস্তুত বিবৃতি এসকিউএল ইনজেকশন আক্রমণ প্রতিরোধ করতে সাহায্য করে।

mysql_*ফাংশন ব্যবহার করার সময়, ব্যবহারকারীর দ্বারা সরবরাহিত পরামিতি চালানোর জন্য আপনাকে মনে রাখতে হবে mysql_real_escape_string()। যদি আপনি কেবলমাত্র এক জায়গায় ভুলে যান বা যদি আপনি কেবল ইনপুট অংশ থেকে পালাতে থাকেন তবে আপনার ডেটাবেস আক্রমণের বিষয় হতে পারে।

প্রস্তুত বিবৃতি ব্যবহার করে PDOবা mysqliএটি তৈরি করবে যাতে প্রোগ্রামিং ত্রুটিগুলির এই ধরণেরগুলি আরও কঠিন করা যায়।


ফাংশন যা অনুরূপ mysql_connect(), mysql_query()টাইপ আগের সংস্করণ পিএইচপি অর্থাৎ (পিএইচপি 4) ফাংশন এবং এখন ব্যবহার করা হয় না।

এই দ্বারা প্রতিস্থাপিত হয় mysqli_connect(), mysqli_query()একইভাবে সর্বশেষ পিএইচপি 5।

এই ত্রুটি পিছনে কারণ।


মাইএসকিউএল এক্সটেনশানটি তিনের মধ্যে প্রাচীনতম এবং এটি মূল উপায় যা ডেভেলপাররা MySQL এর সাথে যোগাযোগ করতে ব্যবহৃত হয়। পিএইচপি এবং মাইএসকিউএল উভয় নতুন রিলিজে উন্নতির কারণে এই এক্সটেনশানটি এখন অন্য mysqli_PDO পক্ষে deprecated হচ্ছে ।mysqli_ PDO

  • mysqli_ মাইএসকিউএল ডাটাবেসের সাথে কাজ করার জন্য 'উন্নত' এক্সটেনশান। এটি মাইএসকিউএল সার্ভারের নতুন সংস্করণগুলিতে উপলব্ধ বৈশিষ্ট্যগুলি গ্রহণ করে, এটি ফাংশন ভিত্তিক এবং একটি বস্তু ভিত্তিক ইন্টারফেস ডেভেলপারকে প্রকাশ করে এবং কিছু অন্যান্য নিফটি জিনিসগুলি প্রকাশ করে।

  • PDO একটি API সরবরাহ করে যা সর্বাধিক প্রধান ডেটাবেস অ্যাক্সেস এক্সটেনশানগুলি, যেমন মাইএসকিউএল, পোস্টগ্রিএসকিউএল, এসকিউএলাইট, এমএসএসকিউএল ইত্যাদি জুড়ে প্রসারিত করে এমন বেশিরভাগ কার্যকারিতাগুলিকে একত্রিত করে। ইন্টারফেসটি প্রোগ্রামারের ডেটাবেস সংযোগ, প্রশ্নগুলির সাথে কাজ করার জন্য উচ্চ স্তরের অবজেক্ট প্রকাশ করে ফলাফল সেট, এবং নিম্ন স্তরের ড্রাইভার ডাটাবেস সার্ভারের সাথে যোগাযোগ এবং সংস্থান পরিচালনা পরিচালনা করে। অনেক আলোচনা এবং কাজ পিডিওতে যাচ্ছে এবং এটি আধুনিক, পেশাদার কোডের ডেটাবেসগুলির সাথে কাজ করার উপযুক্ত পদ্ধতি হিসাবে বিবেচিত হয়।







database