මම PHP හි mysql_ * ශ්‍රිත භාවිතා නොකළ යුත්තේ ඇයි?


2505

යමෙක් mysql_*කාර්යයන් භාවිතා නොකිරීමට ඇති තාක්ෂණික හේතු මොනවාද? (උදා mysql_query(), mysql_connect()හෝ mysql_real_escape_string())?

ඔවුන් මගේ වෙබ් අඩවියේ වැඩ කළත් මා වෙනත් දෙයක් භාවිතා කළ යුත්තේ ඇයි?

ඔවුන් මගේ වෙබ් අඩවියේ වැඩ නොකරන්නේ නම්, ඇයි මට එවැනි දෝෂ ලැබෙන්නේ?

අවවාදයයි: mysql_connect (): එවැනි ගොනුවක් හෝ නාමාවලියක් නොමැත


සමාන වීමට ඇති දෝෂය: මාරක දෝෂය: හඳුනා නොගත් දෝෂය: නිර්වචනය නොකළ ශ්‍රිතයට අමතන්න mysql_connect () ...
Bimal Poudel

21
ඒවායින් වැළකී සිටීමට පමණක් ප්‍රමාණවත් වේ
සාසා 1234

Answers:


2088

MySQL දිගුව:

  • ක්‍රියාකාරී සංවර්ධනය යටතේ නොමැත
  • ඇත නිල නිකුතුව සමඟ අතහැර (2013 ජූනි මස නිකුත්) PHP 5.5 ලෙස.
  • PHP 7.0 (2015 දෙසැම්බර් නිකුත් කරන ලද) වන විට සම්පූර්ණයෙන්ම ඉවත් කර ඇත
    • මෙයින් අදහස් කරන්නේ 2018 දෙසැම්බර් 31 වන විට එය PHP හි කිසිදු සහය දක්වන අනුවාදයක නොපවතින බවයි. ඔබ එයට සහය දක්වන PHP අනුවාදයක් භාවිතා කරන්නේ නම්, ඔබ භාවිතා කරන්නේ ආරක්ෂක ගැටළු නිරාකරණය නොවන අනුවාදයකි.
  • OO අතුරුමුහුණතක් නොමැත
  • සහාය නොදක්වයි:
    • අවහිර නොකරන, අසමමුහුර්ත විමසුම්
    • සකස් කළ ප්‍රකාශ හෝ පරාමිතිගත විමසුම්
    • ගබඩා කළ ක්රියා පටිපාටි
    • බහුවිධ ප්‍රකාශ
    • ගනුදෙනු
    • "නව" මුරපද සත්‍යාපන ක්‍රමය (පෙරනිමියෙන් MySQL 5.6; 5.7 හි අවශ්‍ය වේ)
    • MySQL 5.1 හෝ ඊට පසුව ඇති ඕනෑම නව ක්‍රියාකාරිත්වයක්

එය අවලංගු කර ඇති බැවින්, එය භාවිතා කිරීමෙන් ඔබගේ කේතය අනාගත සාධනය අඩු කරයි.

සකස් කරන ලද ප්‍රකාශ සඳහා සහය නොමැතිකම විශේෂයෙන් වැදගත් වන්නේ ඒවා වෙනම ක්‍රියාකාරී ඇමතුමකින් අතින් පැන යාමට වඩා පැහැදිලි, අඩු දෝෂ ඇතිවීමේ ක්‍රමයක් බාහිර දත්ත වලින් උපුටා දැක්වීමේ හා උපුටා දැක්වීමේ ක්‍රමයක් සපයන බැවිනි.

SQL දිගු වල සංසන්දනය බලන්න .


287
ඒවායින් වැළකී සිටීම පමණක් ප්‍රමාණවත් නොවේ. ඔවුන් කවදා හෝ එහි නොසිටින අතර ඔබ ඔවුන් මත විශ්වාසය තැබුවහොත් ඔබ සතුටු නොවනු ඇත. ඉතිරිය පැරණි දිගු භාවිතා කිරීමෙන් මිනිසුන් ඉගෙනීමෙන් වළක්වා ඇති දේවල් ලැයිස්තුවක් පමණි.
ටිම් පෝස්ට්

111
ක්ෂය කිරීම යනු සෑම කෙනෙකුම සිතන ආකාරයට පෙනෙන මැජික් උණ්ඩය නොවේ. PHP එක දවසකවත් එහි නොසිටිනු ඇත, නමුත් අද අප සතුව ඇති මෙවලම් මත අපි විශ්වාසය තබමු. අපට මෙවලම් වෙනස් කිරීමට සිදු වූ විට, අපි එසේ කරන්නෙමු.
කක්ෂයේ සැහැල්ලු ධාවන තරඟ

133
IghtLightnessRacesinOrbit - ක්ෂය කිරීම මැජික් උණ්ඩයක් නොවේ, එය "මෙය උරා බොන බව අපි හඳුනා ගනිමු, එබැවින් අපි වැඩි කාලයක් එයට සහාය නොදක්වන්නෙමු" යනුවෙන් පවසන ධජයකි. අවලංගු කරන ලද අංගයන්ගෙන් move ත් වීමට හොඳ අනාගත කේතයක් සනාථ කිරීම හොඳ හේතුවක් වන අතර, එය එකම එක නොවේ (හෝ ප්‍රධාන එක පවා). මෙවලම් වෙනස් කරන්න වඩා හොඳ මෙවලම් ඇති නිසා මිස ඔබට බල කරන නිසා නොවේ. (ඔබට බල කිරීමට පෙර මෙවලම් වෙනස් කිරීම යන්නෙන් අදහස් වන්නේ ඔබේ කේතය වැඩ කිරීම නවතා දමා ඊයේ නිවැරදි කිරීම අවශ්‍ය වූ පමණින් ඔබ නව ඒවා ඉගෙන නොගන්නා බවයි… මෙය නව මෙවලම් ඉගෙන ගැනීමට ඇති නරකම කාලයයි).
ක්වෙන්ටින්

18
සූදානම් කළ ප්‍රකාශ නොමැතිවීම ගැන මා දැක නැති එක් දෙයක් නම් කාර්ය සාධන ප්‍රශ්නයයි. ඔබ ප්‍රකාශයක් නිකුත් කරන සෑම අවස්ථාවකම, යමක් සම්පාදනය කළ යුතු අතර එමඟින් MySQL ඩීමන්ට එය තේරුම් ගත හැකිය. මෙම API සමඟ, ඔබ එකම විමසුමක් 200,000 ක් ලූපයකින් නිකුත් කරන්නේ නම්, එය තේරුම් ගැනීමට MySQL සඳහා විමසුම සම්පාදනය කළ යුතුය. සකස් කළ ප්‍රකාශ සමඟ, එය එක් වරක් සම්පාදනය කරනු ලැබේ, පසුව අගයන් සම්පාදනය කරන ලද SQL වෙත පරාමිතිකරණය කෙරේ.
ගෝල්ඩෙන්ටෝ 11

20
@symcbean, එය නියත වශයෙන්ම නැත නොවන සූදානම් ප්රකාශ සහාය. එය ප්‍රතික්ෂේප කිරීමට ප්‍රධාන හේතුව එයයි. (භාවිතා කිරීමට පහසු) සූදානම් කළ ප්‍රකාශ නොමැතිව MySQL දිගුව බොහෝ විට SQL එන්නත් කිරීමේ ප්‍රහාරයන්ට ගොදුරු වේ.
rustyx

1286

MySQL හා සම්බන්ධ වීමට PHP විවිධ API තුනක් ඉදිරිපත් කරයි. මේවා mysql(PHP 7 වන විට ඉවත් කර ඇත) mysqli, සහ PDOදිගු වේ.

මෙම mysql_*කාර්යයන් ඉතා ජනප්රිය විය කිරීම සඳහා භාවිතා, නමුත් ඔවුන්ගේ භාවිතය තවදුරටත් දිරිමත් නැහැ. ප්‍රලේඛන කණ්ඩායම දත්ත සමුදායේ ආරක්‍ෂිත තත්ත්වය පිළිබඳව සාකච්ඡා කරමින් සිටින අතර බහුලව භාවිතා වන ext / mysql දිගුවෙන් ඉවත් වීමට පරිශීලකයින් දැනුවත් කිරීම මෙහි කොටසකි ( php.internals පරීක්ෂා කරන්න : ext / mysql අවලංගු කිරීම ).

සහ එහි පසු, PHP සංවර්ධක කණ්ඩායම ජනනය කිරීමට තීරණය කර තිබේ E_DEPRECATEDහරහා යන්න, පරිශීලකයන් MySQL වෙත සම්බන්ධ වන විට වැරදි mysql_connect(), mysql_pconnect()හෝ බවට ඉදි ගම්ය සම්බන්ධයක් ක්රියාකාරිත්වය ext/mysql.

ext/mysqlවිය නිල PHP 5.5 ක අදහසට විරුද්ධ ලෙස හා කර ඇත , PHP 7 ලෙස ඉවත් .

රතු කොටුව බලන්න?

ඔබ කිසියම් mysql_*ක්‍රියාකාරී අත්පොත පිටුවකට ගිය විට, ඔබට රතු කොටුවක් පෙනේ, එය තවදුරටත් භාවිතා නොකළ යුතු බව පැහැදිලි කරයි.

මන්ද


එයින් ඉවත් ext/mysqlවීම ආරක්ෂාව ගැන පමණක් නොව, MySQL දත්ත ගබඩාවේ සියලුම අංග වෙත ප්‍රවේශය ලබා ගැනීම ද වේ.

ext/mysqlMySQL 3.23 සඳහා ගොඩනගා ඇති අතර එතැන් සිට එකතු කිරීම් කිහිපයක් පමණක් ලැබී ඇති අතර බොහෝ විට මෙම පැරණි අනුවාදය සමඟ අනුකූලතාව පවත්වා ගෙන යන අතර එමඟින් කේතය නඩත්තු කිරීම තරමක් අපහසු වේ. පහත දැක්වෙන අංග වලට සහය නොදක්වන අංග ext/mysqlඇතුළත් වේ: ( PHP අත්පොතෙන් ).

mysql_*ශ්‍රිතය භාවිතා නොකිරීමට හේතුව :

  • ක්‍රියාකාරී සංවර්ධනය යටතේ නොවේ
  • PHP 7 වන විට ඉවත් කර ඇත
  • OO අතුරුමුහුණතක් නොමැත
  • අවහිර නොකරන, අසමමුහුර්ත විමසුම් සඳහා සහය නොදක්වයි
  • සකස් කළ ප්‍රකාශ හෝ පරාමිතිගත විමසුම් සඳහා සහය නොදක්වයි
  • ගබඩා කළ ක්‍රියා පටිපාටිවලට සහය නොදක්වයි
  • බහු ප්‍රකාශ සඳහා සහය නොදක්වයි
  • ගනුදෙනු සඳහා සහාය නොදක්වයි
  • MySQL 5.1 හි ඇති සියලුම ක්‍රියාකාරිත්වයට සහය නොදක්වයි

ක්වෙන්ටින්ගේ පිළිතුරෙන් උපුටා ගත් කරුණ

සකස් කරන ලද ප්‍රකාශ සඳහා සහය නොමැතිකම විශේෂයෙන් වැදගත් වන්නේ ඒවා වෙනම ක්‍රියාකාරී ඇමතුමකින් අතින් පැන යාමට වඩා පැහැදිලි, අඩු දෝෂ සහිත බාහිර දත්ත පැන යාම සහ උපුටා දැක්වීමකි.

SQL දිගු වල සංසන්දනය බලන්න .


ක්ෂයවීම් අනතුරු ඇඟවීම් යටපත් කිරීම

කේතය MySQLi/ බවට පරිවර්තනය වන අතර PDO, බැහැර කිරීම සඳහා php.ini හි E_DEPRECATEDසැකසීමෙන් දෝෂ යටපත් කළ හැකියerror_reportingE_DEPRECATED:

error_reporting = E_ALL ^ E_DEPRECATED

මෙය වෙනත් ක්ෂයවීම් අනතුරු ඇඟවීම් ද සඟවනු ඇති බව සලකන්න , කෙසේ වෙතත්, MySQL හැර වෙනත් දේ සඳහා විය හැකිය. ( PHP අත්පොතෙන් )

PDO එදිරිව MySQLi ලිපිය : ඔබ භාවිතා කළ යුත්තේ කුමක්ද? විසින් Dejan Marjanovic ඔබ තෝරා ගැනීමට උපකාරී වනු ඇත.

වඩා හොඳ ක්‍රමයක් නම් PDO, මම දැන් සරල PDOනිබන්ධනයක් ලියමි.


සරල හා කෙටි PDO නිබන්ධනයක්


ප්‍රශ්නය - මගේ මනසේ මුල්ම ප්‍රශ්නය වූයේ: “පීඩීඕ” යනු කුමක්ද?

පිළිතුර -පීඩීඕ - පීඑච්පී දත්ත වස්තු - බහු දත්ත සමුදායන් වෙත ඒකාකාරී ප්‍රවේශයක් සපයන දත්ත සමුදා ප්‍රවේශ ස්ථරයකි.”

alt පෙළ


MySQL වෙත සම්බන්ධ වෙමින්

mysql_*ක්‍රියාකාරීත්වය සමඟ හෝ අපට එය පැරණි ක්‍රමය ලෙස පැවසිය හැකිය (PHP 5.5 සහ ඊට ඉහළින් ඉවත් කර ඇත)

$link = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('testdb', $link);
mysql_set_charset('UTF-8', $link);

සමග PDO: ඔබ කළ යුත්තේ නව PDOවස්තුවක් නිර්මාණය කිරීම පමණි . මෙම ඉදිකිරීමටත් දත්ත සමුදාය ප්රභවය නියම සඳහා පරාමිතීන් පිළිගන්නා PDOගේ ඉදිකිරීමටත් බොහෝ දුරට ලබන පරාමිති හතර ගනී DSN(දත්ත ප්රභවය නම) විකල්පයක් හා username, password.

මෙන්න මම හිතන්නේ ඔබ හැර අන් සියල්ලන්ටම හුරුපුරුදු ය DSN; මෙය අළුත් දෙයක් PDO. A DSNයනු මූලික වශයෙන් PDOකුමන ධාවකය භාවිතා කළ යුතුද යන්න සහ සම්බන්ධතා තොරතුරු පවසන විකල්ප මාලාවකි. වැඩි විස්තර සඳහා PDO MySQL DSN පරීක්ෂා කරන්න .

$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');

සටහන: ඔබට ද භාවිතා කළ හැකිය charset=UTF-8, නමුත් සමහර විට එය දෝෂයක් ඇති කරයි, එබැවින් එය භාවිතා කිරීම වඩා හොඳය utf8.

කිසියම් සම්බන්ධතා දෝෂයක් තිබේ නම්, එය තවදුරටත් PDOExceptionහැසිරවීමට අල්ලා ගත හැකි වස්තුවක් විසි කරයි Exception.

හොඳ කියවීම : සම්බන්ධතා සහ සම්බන්ධතා කළමනාකරණය

සිව්වන පරාමිතිය සඳහා අරාව ලෙස ඔබට ධාවක විකල්ප කිහිපයකින් සමත් විය හැකිය. PDOව්‍යතිරේක ප්‍රකාරයට ඇතුළත් වන පරාමිතිය සම්මත කිරීමට මම නිර්දේශ කරමි . සමහර PDOරියදුරන් ස්වදේශික සූදානම් කළ ප්‍රකාශයන්ට සහාය නොදක්වන හෙයින් PDO, සූදානම අනුකරණය කරයි. මෙම අනුකරණය අතින් සක්‍රීය කිරීමට ද එය ඔබට ඉඩ සලසයි. ස්වදේශීය සේවාදායකයේ සූදානම් කළ ප්‍රකාශ භාවිතා කිරීමට, ඔබ එය පැහැදිලිවම සැකසිය යුතුය false.

අනෙක් කාරණය නම් MySQLපෙරනිමියෙන් ධාවකයේ සක්‍රීය කර ඇති සූදානම් කිරීමේ අනුකරණය අක්‍රිය කිරීමයි, නමුත් PDOආරක්ෂිතව භාවිතා කිරීම සඳහා අනුකරණය කිරීම අක්‍රිය කළ යුතුය .

සූදානම් කිරීමේ අනුකරණය අක්‍රිය කළ යුත්තේ මන්දැයි මම පසුව පැහැදිලි කරමි. හේතුව සොයා ගැනීමට කරුණාකර මෙම ලිපිය පරීක්ෂා කරන්න .

එය භාවිතා කළ හැක්කේ MySQLමා නිර්දේශ නොකරන පැරණි අනුවාදයක් භාවිතා කරන්නේ නම් පමණි .

ඔබට එය කළ හැකි ආකාරය පිළිබඳ උදාහරණයක් පහත දැක්වේ:

$db = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF-8', 
              'username', 
              'password',
              array(PDO::ATTR_EMULATE_PREPARES => false,
              PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

PDO ඉදිකිරීමෙන් පසු අපට ගුණාංග සැකසිය හැකිද?

ඔව් , PDO ඉදිකිරීමෙන් පසුව අපට setAttributeක්‍රමවේදය සමඟ සමහර ගුණාංග සැකසිය හැකිය :

$db = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF-8', 
              'username', 
              'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

හැසිරවීමේ දෝෂයකි


දෝෂ හැසිරවීම වඩාත් පහසු වේ PDOවඩා mysql_*.

භාවිතා කරන විට පොදු සිරිතක් mysql_*වන්නේ:

//Connected to MySQL
$result = mysql_query("SELECT * FROM table", $link) or die(mysql_error($link));

OR die()අපට එය හැසිරවිය නොහැකි බැවින් දෝෂය හැසිරවීමට හොඳ ක්‍රමයක් නොවේ die. එය ස්ක්‍රිප්ට් එක හදිසියේම අවසන් කර සාමාන්‍යයෙන් ඔබේ අවසාන පරිශීලකයින්ට පෙන්වීමට අවශ්‍ය නොවන දෝෂය තිරය වෙත දෝංකාර දෙයි, සහ ලේවැකි හැකර්වරුන්ට ඔබේ ක්‍රමෝපාය සොයා ගැනීමට ඉඩ දෙන්න. විකල්පයක් ලෙස, දෝෂ වල mysql_*ක්‍රියාකාරිත්වය සඳහා බොහෝ විට ශ්‍රිතවල ප්‍රතිලාභ අගයන් mysql_error () සමඟ ඒකාබද්ධව භාවිතා කළ හැකිය.

PDOවඩා හොඳ විසඳුමක් ඉදිරිපත් කරයි: ව්‍යතිරේක. අප සමග ඕනෑම දෙයක් PDOඑතූ කළ යුතු try- catchවාරණ. PDOදෝෂ මාදිලියේ ගුණාංගය සැකසීමෙන් අපට දෝෂ ක්‍රම තුනෙන් එකකට බල කළ හැකිය . දෝෂ හැසිරවීමේ ක්‍රම තුනක් පහතින්.

  • PDO::ERRMODE_SILENT. එය හුදෙක් දෝෂ කේත සැකසීම පමණක් වන mysql_*අතර ඔබ එක් එක් ප්‍රති result ලය පරික්ෂා කර බැලිය යුතු තැනට සමාන ලෙස ක්‍රියා කරයි $db->errorInfo();.
  • PDO::ERRMODE_WARNINGඔසවන්න E_WARNING. (ධාවන කාල අනතුරු ඇඟවීම් (මාරාන්තික නොවන දෝෂ). පිටපත ක්‍රියාත්මක කිරීම නතර නොවේ.)
  • PDO::ERRMODE_EXCEPTION: ව්‍යතිරේක විසි කරන්න. එය නියෝජනය කරන්නේ PDO විසින් මතු කරන ලද දෝෂයකි. ඔබ PDOExceptionඔබේම කේතයෙන් විසි නොකළ යුතුය . PHP හි ව්‍යතිරේක පිළිබඳ වැඩි විස්තර සඳහා ව්‍යතිරේක බලන්න . එය or die(mysql_error());හසු නොවූ විට එය බොහෝ සෙයින් ක්‍රියා කරයි . නමුත් මෙන් නොව or die(), PDOExceptionඔබ එසේ කිරීමට තෝරා ගන්නේ නම්, එය අල්ලාගෙන මනාව හැසිරවිය හැකිය.

හොඳ කියවීම :

මෙන්:

$stmt->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
$stmt->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$stmt->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

ඔබට එය ඔතා තැබිය හැකිය try- catch, පහත පරිදි:

try {
    //Connect as appropriate as above
    $db->query('hi'); //Invalid query!
} 
catch (PDOException $ex) {
    echo "An Error occured!"; //User friendly message/message you want to show to user
    some_logging_function($ex->getMessage());
}

ඔබ සමඟ කටයුතු කළ යුතු නැත try- catchදැන්. ඔබට සුදුසු ඕනෑම වේලාවක එය අල්ලා ගත හැකිය, නමුත් භාවිතා කිරීමට මම තරයේ නිර්දේශ කරමි try- catch. එසේම එය PDOදේවල් ලෙස හඳුන්වන ශ්‍රිතයට පිටතින් අල්ලා ගැනීම වඩාත් අර්ථවත් විය හැකිය :

function data_fun($db) {
    $stmt = $db->query("SELECT * FROM table");
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

//Then later
try {
    data_fun($db);
}
catch(PDOException $ex) {
    //Here you can handle error and show message/perform action you want.
}

එසේම, ඔබට හැසිරවිය හැකිය, or die()නැතහොත් අපට එසේ පැවසිය හැකිය mysql_*, නමුත් එය සැබවින්ම වෙනස් වනු ඇත. display_errors offඔබේ දෝෂ ලොගය හැරවීම සහ කියවීමෙන් නිෂ්පාදනයේ ඇති භයානක දෝෂ පණිවිඩ සැඟවිය හැක .

දැන්, ඉහත සියලු දේ කියවීමෙන් පසු, ඔබට මීට හිතන්නේ: ද මන්දා මම සරල පක්ෂයට හේත්තු වී ආරම්භ කිරීමට අවශ්ය විට ඒ මොකක්ද SELECT, INSERT, UPDATE, හෝ DELETEප්රකාශ? කණගාටු නොවන්න, මෙන්න අපි යමු:


දත්ත තෝරා ගැනීම

PDO රූපය තෝරන්න

ඉතින් ඔබ කරන්නේ mysql_*කුමක්ද:

<?php
$result = mysql_query('SELECT * from table') or die(mysql_error());

$num_rows = mysql_num_rows($result);

while($row = mysql_fetch_assoc($result)) {
    echo $row['field1'];
}

දැන් PDO, ඔබට මෙය කළ හැකිය:

<?php
$stmt = $db->query('SELECT * FROM table');

while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo $row['field1'];
}

හෝ

<?php
$stmt = $db->query('SELECT * FROM table');
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

//Use $results

සටහන : ඔබ පහත ( query()) වැනි ක්‍රමය භාවිතා කරන්නේ නම් , මෙම ක්‍රමය PDOStatementවස්තුවක් ලබා දෙයි. එබැවින් ඔබට ප්‍රති result ලය ලබා ගැනීමට අවශ්‍ය නම්, ඉහත පරිදි එය භාවිතා කරන්න.

<?php
foreach($db->query('SELECT * FROM table') as $row) {
    echo $row['field1'];
}

PDO දත්ත වලදී, එය ලබා ->fetch()ගන්නේ ඔබේ ප්‍රකාශන හසුරුවීමේ ක්‍රමයක් මගිනි. ලබා ගැනීමට ඇමතීමට පෙර, හොඳම ප්‍රවේශය වනුයේ දත්ත ලබා ගැනීමට ඔබ කැමති ආකාරය PDO ට පැවසීමයි. පහත කොටසෙහි මම මෙය පැහැදිලි කරමි.

මාදිලි ලබා ගන්න

භාවිතය සටහන PDO::FETCH_ASSOCතුළ fetch()හා fetchAll()ඉහත කේතය. PDOක්ෂේත්‍ර නාම යතුරු ලෙස අනුබද්ධ අරාව ලෙස පේළි ආපසු ලබා දීමට මෙය කියයි . තවත් බොහෝ ලබා ගැනීමේ ක්‍රම තිබේ, ඒවා එකින් එක පැහැදිලි කරමි.

පළමුවෙන්ම, ලබා ගැනීමේ මාදිලිය තෝරා ගන්නේ කෙසේදැයි මම පැහැදිලි කරමි:

 $stmt->fetch(PDO::FETCH_ASSOC)

ඉහත, මම භාවිතා කර ඇත fetch(). ඔබට මෙයද භාවිතා කළ හැකිය:

  • PDOStatement::fetchAll() - ප්‍රති result ල කට්ටල පේළි සියල්ලම අඩංගු අරාවක් ලබා දෙයි
  • PDOStatement::fetchColumn() - ප්‍රති result ල කට්ටලයක ඊළඟ පේළියෙන් තනි තීරුවක් ලබා දෙයි
  • PDOStatement::fetchObject() - ඊළඟ පේළිය ලබා ගෙන එය වස්තුවක් ලෙස ආපසු ලබා දේ.
  • PDOStatement::setFetchMode() - මෙම ප්‍රකාශය සඳහා පෙරනිමි ලබා ගැනීමේ මාදිලිය සකසන්න

දැන් මම ලබා ගැනීමේ මාදිලිය වෙත පැමිණියෙමි:

  • PDO::FETCH_ASSOC: ඔබේ ප්‍රති result ල කට්ටලයට අනුව තීරු නාමයෙන් සුචිගත කරන ලද අරාවක් ලබා දෙයි
  • PDO::FETCH_BOTH (පෙරනිමිය): ඔබේ ප්‍රති result ල කට්ටලයට අනුව තීරු නම සහ 0-සුචිගත කළ තීරු අංකය යන දෙකෙන්ම සුචිගත කරන ලද අරාවක් ලබා දෙයි

ඊටත් වඩා තේරීම් තිබේ! ඒවා ගැන PDOStatementෆෙච් ප්‍රලේඛනයෙන් කියවන්න . .

පේළි ගණන ලබා ගැනීම :

mysql_num_rowsආපසු ලබා දුන් පේළි ගණන ලබා ගැනීම සඳහා භාවිතා කරනවා වෙනුවට , ඔබට පහත PDOStatementසහ rowCount()වැනි දේ ලබා ගත හැකිය :

<?php
$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
echo $row_count.' rows selected';

අවසන් වරට ඇතුළත් කළ හැඳුනුම්පත ලබා ගැනීම

<?php
$result = $db->exec("INSERT INTO table(firstname, lastname) VAULES('John', 'Doe')");
$insertId = $db->lastInsertId();

ප්‍රකාශ ඇතුළත් කිරීම සහ යාවත්කාලීන කිරීම හෝ මකා දැමීම

PDO රූපය ඇතුළු කර යාවත්කාලීන කරන්න

අප mysql_*ක්‍රියාකාරීව කරන්නේ:

<?php
$results = mysql_query("UPDATE table SET field='value'") or die(mysql_error());
echo mysql_affected_rows($result);

Pdo හි දී, මෙයම කළ හැක්කේ:

<?php
$affected_rows = $db->exec("UPDATE table SET field='value'");
echo $affected_rows;

ඉහත විමසුමේදී PDO::execSQL ප්‍රකාශයක් ක්‍රියාත්මක කර බලපෑමට ලක් වූ පේළි ගණන නැවත ලබා දේ.

ඇතුළු කිරීම සහ මකා දැමීම පසුව ආවරණය කෙරේ.

ඉහත ක්‍රමය ප්‍රයෝජනවත් වන්නේ ඔබ විමසුමේ විචල්‍යය භාවිතා නොකරන විට පමණි. නමුත් විමසුමකදී ඔබට විචල්‍යයක් භාවිතා කිරීමට අවශ්‍ය වූ විට, සූදානම් කළ ප්‍රකාශයක් හෝ පරාමිතිගත ප්‍රකාශයක් සඳහා කිසි විටෙකත් ඉහත පරිදි උත්සාහ නොකරන්න .


සකස් කළ ප්රකාශ

ප්‍රශ්නය - සූදානම් කළ ප්‍රකාශයක් යනු කුමක්ද? මට ඒවා අවශ්‍ය වන්නේ ඇයි?
පිළිතුර - සූදානම් කළ ප්‍රකාශයක් යනු පෙර සම්පාදනය කරන ලද SQL ප්‍රකාශයකි, එය සේවාදායකයට දත්ත පමණක් යැවීමෙන් කිහිප වතාවක් ක්‍රියාත්මක කළ හැකිය.

සකස් කළ ප්‍රකාශයක් භාවිතා කිරීමේ සාමාන්‍ය කාර්ය ප්‍රවාහය පහත පරිදි වේ ( විකිපීඩියා තුනෙන් උපුටා ගත් කරුණු 3 ):

  1. සකස් කරන්න : ප්‍රකාශන අච්චුව යෙදුම විසින් නිර්මාණය කර දත්ත සමුදා කළමනාකරණ පද්ධතියට (DBMS) යවනු ලැබේ. සමහර අගයන් නිශ්චිතව දක්වා නොමැති අතර පරාමිති, ස්ථාන දරන්නන් හෝ බන්ධන විචල්‍යයන් ලෙස හැඳින්වේ ( ?පහත ලේබල් කර ඇත):

    INSERT INTO PRODUCT (name, price) VALUES (?, ?)

  2. ප්‍රකාශන අච්චුවේ DBMS විග්‍රහ කිරීම, සම්පාදනය කිරීම සහ විමසුම් ප්‍රශස්තිකරණය සිදු කරයි, ප්‍රති result ලය ක්‍රියාත්මක නොකර ගබඩා කරයි.

  3. ක්‍රියාත්මක කරන්න : පසුකාලීනව, යෙදුම පරාමිතීන් සඳහා අගයන් සපයයි (හෝ බන්ධනය කරයි), සහ ඩීබීඑම්එස් ප්‍රකාශය ක්‍රියාත්මක කරයි (සමහර විට ප්‍රති result ලයක් ලබා දෙයි). යෙදුම විවිධ අගයන් සමඟ ප්‍රකාශය අවශ්‍ය වාර ගණනක් ක්‍රියාත්මක කළ හැකිය. මෙම උදාහරණයේ දී, එය පළමු පරාමිතිය 1.00සඳහා සහ දෙවන පරාමිතිය සඳහා 'පාන්' සැපයිය හැකිය .

ඔබේ SQL හි ස්ථාන දරන්නන් ඇතුළත් කිරීමෙන් ඔබට සූදානම් කළ ප්‍රකාශයක් භාවිතා කළ හැකිය. ස්ථාන හිමිකරුවන් නොමැතිව මූලික වශයෙන් තිදෙනෙක් සිටිති (ඉහත විචල්‍යයෙන් මෙය උත්සාහ නොකරන්න), එකක් නම් නොකළ ස්ථාන දරන්නන් සහ තවත් නම් කරන ලද ස්ථාන දරන්නන් සමඟ.

ප්‍රශ්නය - දැන්, ස්ථාන දරන්නන් ලෙස නම් කර ඇත්තේ කුමක්ද සහ මම ඒවා භාවිතා කරන්නේ කෙසේද?
පිළිතුර - ස්ථාන දරන්නන්. ප්‍රශ්න ලකුණු වෙනුවට මහා බඩවැලකට පෙර විස්තරාත්මක නම් භාවිතා කරන්න. නාම ස්ථාන දරන්නාගේ වටිනාකම / අනුපිළිවෙල ගැන අපි තැකීමක් නොකරමු:

 $stmt->bindParam(':bla', $bla);

bindParam(parameter,variable,data_type,length,driver_options)

ක්‍රියාත්මක කිරීමේ අරාව භාවිතා කරමින් ඔබට බන්ධනය කළ හැකිය:

<?php
$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");
$stmt->execute(array(':name' => $name, ':id' => $id));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

OOPමිතුරන් සඳහා ඇති තවත් හොඳ ලක්ෂණයක් නම් නම් කරන ලද ස්ථාන හිමියන්ට ඔබේ දත්ත ගබඩාවට කෙලින්ම වස්තු ඇතුළු කිරීමේ හැකියාව ඇති අතර, එම නම් නම් කරන ලද ක්ෂේත්‍රයන්ට ගැලපෙන ගුණාංග උපකල්පනය කරයි. උදාහරණයක් වශයෙන්:

class person {
    public $name;
    public $add;
    function __construct($a,$b) {
        $this->name = $a;
        $this->add = $b;
    }

}
$demo = new person('john','29 bla district');
$stmt = $db->prepare("INSERT INTO table (name, add) value (:name, :add)");
$stmt->execute((array)$demo);

ප්‍රශ්නය - දැන්, නම් නොකළ ස්ථාන දරන්නන් යනු කුමක්ද සහ මම ඒවා භාවිතා කරන්නේ කෙසේද?
පිළිතුර - අපි උදාහරණයක් කරමු:

<?php
$stmt = $db->prepare("INSERT INTO folks (name, add) values (?, ?)");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->bindValue(2, $add, PDO::PARAM_STR);
$stmt->execute();

සහ

$stmt = $db->prepare("INSERT INTO folks (name, add) values (?, ?)");
$stmt->execute(array('john', '29 bla district'));

ඉහත සඳහන් ?ස්ථානවල, නම ස්ථාන දරන්නා වැනි නමක් වෙනුවට ඒවා දැකිය හැකිය . දැන් පළමු උදාහරණයේ දී, අපි විවිධ ස්ථාන දරන්නන්ට විචල්‍යයන් ලබා දෙමු ( $stmt->bindValue(1, $name, PDO::PARAM_STR);). ඉන්පසුව, අපි එම ස්ථාන හිමියන්ට අගයන් පවරා ප්‍රකාශය ක්‍රියාත්මක කරමු. දෙවන උදාහරණයේ දී, පළමු අරාව මූලද්‍රව්‍යය පළමු ?හා දෙවන දෙවැන්න වෙත යයි ?.

සටහන : නම් නොකල ස්ථාන දරන්නන් තුළ, අපි PDOStatement::execute()ක්‍රමයට යන අරාවෙහි ඇති මූලද්‍රව්‍යයන්ගේ නිසි අනුපිළිවෙල ගැන සැලකිලිමත් විය යුතුය .


SELECT, INSERT, UPDATE, DELETEසූදානම් විමසුම්

  1. SELECT:

    $stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");
    $stmt->execute(array(':name' => $name, ':id' => $id));
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  2. INSERT:

    $stmt = $db->prepare("INSERT INTO table(field1,field2) VALUES(:field1,:field2)");
    $stmt->execute(array(':field1' => $field1, ':field2' => $field2));
    $affected_rows = $stmt->rowCount();
  3. DELETE:

    $stmt = $db->prepare("DELETE FROM table WHERE id=:id");
    $stmt->bindValue(':id', $id, PDO::PARAM_STR);
    $stmt->execute();
    $affected_rows = $stmt->rowCount();
  4. UPDATE:

    $stmt = $db->prepare("UPDATE table SET name=? WHERE id=?");
    $stmt->execute(array($name, $id));
    $affected_rows = $stmt->rowCount();

සටහන:

කෙසේ වෙතත් PDOසහ / හෝ MySQLiසම්පූර්ණයෙන්ම ආරක්ෂිත නොවේ. පිළිතුර පරීක්ෂා කරන්න SQL එන්නත් කිරීම වැළැක්වීමට PDO සකස් කළ ප්‍රකාශ ප්‍රමාණවත්ද? ircmaxell විසින් . එසේම, මම ඔහුගේ පිළිතුරෙන් යම් කොටසක් උපුටා දක්වමි:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->query('SET NAMES GBK');
$stmt = $pdo->prepare("SELECT * FROM test WHERE name = ? LIMIT 1");
$stmt->execute(array(chr(0xbf) . chr(0x27) . " OR 1=1 /*"));

15
ඉහත කියවා ඇති දේ ගැන සඳහන් කළ යුතු දේ: සූදානම් කළ ප්‍රකාශය අර්ථවත් ලෙස භාවිතා කරයි IN (...) construct.
ඉයුජන් රික්

24
ප්රශ්නය වූයේ "මම PHP හි mysql_ * කාර්යයන් භාවිතා නොකළ යුත්තේ ඇයි" යන්නයි. මෙම පිළිතුර, සිත් ඇදගන්නාසුළු හා ප්‍රයෝජනවත් තොරතුරු වලින් පිරී ඇති අතර, එට්‍රෙජ්ඩර් පවසන පරිදි - පුද්ගලයින් 10 දෙනෙකුගෙන් 8 දෙනෙකු එම තොරතුරු මග හැරීමට යන්නේ ඔවුන්ට වැඩ කිරීමට පැය 4 ක් ගත නොවන නිසාය. එය. මෙය වඩා වටිනාකමක් ඇති අතර වඩාත් නිවැරදි, ප්‍රශ්න කිහිපයකට පිළිතුරු ලෙස භාවිතා කරනු ඇත.
ඇලෙක්ස් මැක්මිලන්

පර්සෝන්ලි මම කැමතියි මයිස්ක්ලි සහ පීඩීඕ වලට. නමුත් ඩයි හැසිරවීම සඳහා, මම ව්‍යතිරේක විකල්පයක් උත්සාහ කළෙමි function throwEx() { throw new Exception("You did selected not existng db"); } mysql_select_db("nonexistdb") or throwEx();.
kuldeep.kamboj

ඔබ Doesn't support non-blocking, asynchronous queriesmysql_ භාවිතා නොකිරීමට හේතුවක් ලෙස ලැයිස්තු ගත කරයි - PDO භාවිතා නොකිරීමට හේතුවක් ලෙසද ඔබ ලැයිස්තු ගත කළ යුතුය, මන්ද PDO එයට සහාය නොදක්වන බැවිනි. (නමුත් MySQLi එයට සහය දක්වයි)
hanshenrik

මට මෙය භාවිතා කරන දත්ත සමුදායක් ඇති බැවින් Charset utf8mb4_unicode_ci භාවිතා කළ හැකිද?
රයන් ස්ටෝන්

300

පළමුව, අපි සෑම කෙනෙකුටම ලබා දෙන සම්මත අදහස් දැක්වීමෙන් පටන් ගනිමු:

කරුණාකර, mysql_*නව කේත වල කාර්යයන් භාවිතා නොකරන්න . ඒවා තවදුරටත් නඩත්තු නොකරන අතර නිල වශයෙන් අතහැර දමනු ලැබේ. රතු පෙට්ටිය බලන්න? ඒ වෙනුවට සූදානම් කළ ප්‍රකාශ ගැන ඉගෙන ගෙන PDO හෝ MySQLi භාවිතා කරන්න- මෙම ලිපිය ඔබට තීරණය කිරීමට උපකාරී වේ. ඔබ PDO තෝරා ගන්නේ නම්, මෙන්න හොඳ නිබන්ධනයක් .

අපි මේ හරහා යමු, වාක්‍යයෙන් වාක්‍යය, සහ පැහැදිලි කරන්න:

  • ඒවා තවදුරටත් නඩත්තු නොකරන අතර නිල වශයෙන් ඉවත් කරනු ලැබේ

    මෙයින් අදහස් කරන්නේ PHP ප්‍රජාව මෙම ඉතා පැරණි කාර්යයන් සඳහා ක්‍රමයෙන් සහයෝගය ලබා දෙන බවයි. අනාගත (මෑත) PHP අනුවාදයක ඒවා නොපවතිනු ඇත! මෙම කාර්යයන් අඛණ්ඩව භාවිතා කිරීම අනාගතයේදී (එසේ නොවේ) ඔබේ කේතය බිඳ දැමිය හැකිය.

    නවතම! - ext / mysql දැන් PHP 5.5 වන විට නිල වශයෙන් ඉවත් කර ඇත!

    අලුත්! ext / mysql PHP 7 හි ඉවත් කර ඇත .

  • ඒ වෙනුවට, ඔබ සූදානම් ප්‍රකාශ ගැන ඉගෙන ගත යුතුය

    mysql_*දීර් extension කිරීම සූදානම් කළ ප්‍රකාශයන්ට සහාය නොදක්වයි , එය (වෙනත් දේ අතර) SQL එන්නත් කිරීමට එරෙහිව ඉතා effective ලදායී ප්‍රතිප්‍රහාරයකි . එය MySQL මත යැපෙන යෙදුම්වල ඉතා බරපතල අවදානමක් ඇති කර ඇති අතර එමඟින් ඔබේ ස්ක්‍රිප්ටයට ප්‍රවේශය ලබා ගැනීමට සහ ඔබේ දත්ත ගබඩාවේ හැකි ඕනෑම විමසුමක් කිරීමට ප්‍රහාරකයන්ට ඉඩ දෙයි .

    වැඩි විස්තර සඳහා, PHP හි SQL එන්නත් කිරීම වළක්වා ගන්නේ කෙසේද?

  • රතු කොටුව බලන්න?

    ඔබ කිසියම් mysqlක්‍රියාකාරී අත්පොතකට ගිය විට , ඔබට රතු කොටුවක් පෙනේ, එය තවදුරටත් භාවිතා නොකළ යුතු බව පැහැදිලි කරයි.

  • PDO හෝ MySQLi භාවිතා කරන්න

    වඩා හොඳ, වඩා ශක්තිමත් හා හොඳින් ගොඩනඟන ලද විකල්ප ඇත, දත්ත සමුදා අන්තර්ක්‍රියා සඳහා සම්පූර්ණ OOP ප්‍රවේශයක් සපයන PDO - PHP දත්ත සමුදා වස්තුව සහ MySQL විශේෂිත වැඩිදියුණු කිරීමක් වන MySQLi .


6
තවත් එක් දෙයක් තිබේ: මම සිතන්නේ PHP හි ක්‍රියාකාරීත්වය තවමත් පවතින්නේ එක් හේතුවක් නිසා පමණි - පැරණි, යල් පැන ගිය නමුත් තවමත් ක්‍රියාත්මක වන CMS, ඊ-වාණිජ්‍යය, බුලටින් පුවරු පද්ධති ආදිය සමඟ අනුකූල වීම. අවසාන වශයෙන් එය ඉවත් කර නැවත ලිවීමට සිදුවේ. application ...
Kamil

4
Am කමිල්: ඒක ඇත්ත, නමුත් ඔබ එය භාවිතා නොකිරීමට එය ඇත්තෙන්ම හේතුවක් නොවේ. එය භාවිතා නොකිරීමට හේතුව එය පුරාණ, අනාරක්ෂිත යනාදියයි. :)
මදාරාගේ අවතාරය

4
Ari මාරියෝ - PHP devs හට ක්‍රියාවලියක් ඇති අතර, ඔවුන් 5.5 වන විට ext / mysql විධිමත් ලෙස අවලංගු කිරීමට පක්ෂව ඡන්දය ප්‍රකාශ කර ඇත. එය තවදුරටත් උපකල්පිත ගැටලුවක් නොවේ.
එස්ඩීසී

2
PDO හෝ MySQLi වැනි ඔප්පු කරන ලද තාක්‍ෂණයක් සහිත අමතර රේඛා කිහිපයක් එකතු කිරීමෙන් PHP සෑම විටම ලබා දී ඇති භාවිතයේ පහසුව සලසයි. ඕනෑම නිබන්ධනයක මෙම දෙවියන්ගේ භයානක mysql_ * ක්‍රියාකාරකම් දැකීමෙන් ඇත්ත වශයෙන්ම පාඩමෙන් ract ත් වන බව ඔහු / ඇය දන්නා සංවර්ධකයා වෙනුවෙන් මම බලාපොරොත්තු වෙමි. මීට වසර 10 කට පෙර මෙම ආකාරයේ කේත ඉතා සූක්ෂම බව OP ට පැවසිය යුතුය. නිබන්ධනයේ අදාළත්වය ද!
FredTheWebGuy

1
පිළිතුරේ සඳහන් කළ යුතු දේ: සූදානම් කළ ප්‍රකාශය අර්ථවත් ලෙස භාවිතා කරයි IN (...) construct.
ඉයුජන් රික්

217

භාවිතයේ පහසුව

විශ්ලේෂණාත්මක හා කෘතිම හේතු දැනටමත් සඳහන් කර ඇත. නවකයින් සඳහා, යල් පැන ගිය mysql_ ශ්‍රිත භාවිතා කිරීම නැවැත්වීමට වඩා වැදගත් දිරිගැන්වීමක් ඇත.

සමකාලීන දත්ත සමුදා API භාවිතා කිරීම පහසුය .

එය බොහෝ දුරට කේතය සරල කළ හැකි බැඳී ඇති පරාමිතීන් වේ. විශිෂ්ට නිබන්ධන සමඟ (ඉහත දැක්වෙන පරිදි) PDO වෙත මාරුවීම ඕනෑවට වඩා දුෂ්කර නොවේ.

විශාල කේත පදනමක් එකවර නැවත ලිවීමට කාලය ගතවේ. මෙම අතරමැදි විකල්පය සඳහා රයිසන් ඩිට්‍රේ:

සමාන pdo_ * වෙනුවට කාර්යයන් mysql_ *

< Pdo_mysql.php > භාවිතා කිරීමෙන් ඔබට පැරණි mysql_ ශ්‍රිත වලින් අවම උත්සාහයකින් මාරු විය හැකිය . pdo_එමඟින් ඒවායේ mysql_සගයන් ප්‍රතිස්ථාපනය කරන ශ්‍රිත රැළි එකතු කරයි .

  1. දත්ත සමුදාය සමඟ අන්තර් ක්‍රියා කළ යුතු එක් එක් ආයාචනා පිටපතෙහි සරලවම . include_once("pdo_mysql.php");

  2. මෙම ඉවත් කරන්න mysql_කාර්යය උපසර්ගය සෑම තැනකම එය විස්ථාපනය pdo_.

    • mysql_connect() බවට පත්වේ pdo_connect()
    • mysql_query() බවට පත්වේ pdo_query()
    • mysql_num_rows() බවට පත්වේ pdo_num_rows()
    • mysql_insert_id() බවට පත්වේ pdo_insert_id()
    • mysql_fetch_array() බවට පත්වේ pdo_fetch_array()
    • mysql_fetch_assoc() බවට පත්වේ pdo_fetch_assoc()
    • mysql_real_escape_string() බවට පත්වේ pdo_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]";
    }

Et voilà.
ඔබේ කේතය PDO භාවිතා කරයි.
දැන් එය ඇත්ත වශයෙන්ම භාවිතා කිරීමට කාලයයි .

මායිම් පරාමිතීන් භාවිතා කිරීම පහසුය

ඔබට අවශ්‍ය වන්නේ අඩු අනාරක්ෂිත API ය.

pdo_query()බැඳී ඇති පරාමිතීන් සඳහා ඉතා පහසු සහය එක් කරයි. පැරණි කේතය පරිවර්තනය කිරීම සරල ය:

ඔබේ විචල්යයන් SQL නූලෙන් ඉවතට ගෙන යන්න.

  • කොමා වලින් වෙන් කරන ලද ශ්‍රිත පරාමිතීන් ලෙස ඒවා එක් කරන්න pdo_query().
  • ?පෙර විචල්‍යයන් පැවති ස්ථාන දරන්නන් ලෙස ප්‍රශ්න ලකුණු තබන්න .
  • 'කලින් ඇතුළත් කර ඇති නූල් අගයන් / විචල්‍යයන් ඉවත් කළ තනි උපුටා දැක්වීම් ඉවත් කරන්න .

දිගු කේතය සඳහා වාසිය වඩාත් පැහැදිලි වේ.

බොහෝ විට නූල් විචල්‍යයන් SQL වෙත අන්තර් සම්බන්ධිත නොවේ, නමුත් අතර ඇති ඇමතුම් සමඟ ගැලපේ.

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_ මතක තබා ගන්න * තවමත් ඉඩ එක්කෝ හෝ .
හුදෙක් විචල්ය පැන නෑ සහ එම විමසුම් එය බැඳ.

  • ස්ථාන දරන්නාගේ ලක්ෂණය සපයන්නේ එහි පිටුපස ඇති සැබෑ PDO විසිනි.
  • මේ අනුව :namedපසුව ස්ථාන දරන්නන්ගේ ලැයිස්තු ද අවසර දෙනු ලැබේ.

වැදගත්ම දෙය නම් ඔබට ඕනෑම විමසුමකට පිටුපස $ _REQUEST [] විචල්‍යයන් ආරක්ෂිතව යැවිය හැකිය. ඉදිරිපත් කළ <form>ක්ෂේත්‍ර දත්ත සමුදා ව්‍යුහයට ගැලපෙන විට එය ඊටත් වඩා කෙටි වේ:

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

එතරම් සරල බව. නමුත් ඔබට නැවත ලිවීමට උපදෙස් සහ තාක්ෂණික හේතු කිහිපයක් වෙත ආපසු mysql_යමු.

ඕනෑම පැරණි පාසැල් sanitize()කාර්යයක් නිවැරදි කරන්න හෝ ඉවත් කරන්න

ඔබ සියලු mysql_ඇමතුම් pdo_queryසීමිත පරාමිතීන් සමඟ පරිවර්තනය කළ පසු , අතිරික්ත pdo_real_escape_stringඇමතුම් ඉවත් කරන්න .

විශේෂයෙන් ඔබ යම් නිවැරදි කළ යුතු sanitizeහෝ cleanහෝ filterThisහෝ clean_dataඑක් ආකාරයක හෝ අනෙක් දී පැරනි නිබන්ධන විසින් ප්රචාරය කරන ලෙස ක්රියාත්මක වන:

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

මෙහි දීප්තිමත්ම දෝෂය වන්නේ ලේඛන නොමැති වීමයි. වඩා වැදගත් වන්නේ පෙරීමේ අනුපිළිවෙල හරියටම වැරදි අනුපිළිවෙලකි.

  • නිවැරදි අනුපිළිවෙල වනු ඇත්තේ: stripslashesඅභ්‍යන්තරතම ඇමතුම ලෙස බැහැර කර trim, පසුව strip_tags, htmlentitiesනිමැවුම් සන්දර්භය සඳහා වන අතර, අවසාන _escape_stringවශයෙන් එහි යෙදුම SQL අන්තර්ග්‍රහණයට සෘජුවම පූර්වයෙන් යා යුතුය.

  • නමුත් පළමු පියවර ලෙස ඇමතුමෙන් ඉවත් වන්න_real_escape_string .

  • sanitize()ඔබේ දත්ත සමුදාය සහ යෙදුම් ප්‍රවාහය HTML- සන්දර්භය-ආරක්ෂිත නූල් අපේක්ෂා කරන්නේ නම්, ඔබේ ඉතිරි කාර්යය දැනට තබා ගැනීමට ඔබට සිදු විය හැකිය . මෙතැන් සිට HTML ගැලවීම පමණක් අදාළ වන බවට අදහසක් එක් කරන්න.

  • නූල් / අගය හැසිරවීම PDO සහ එහි පරාමිතිගත ප්‍රකාශ වෙත පවරනු ලැබේ.

  • stripslashes()ඔබේ සනීපාරක්ෂක කාර්යයේ කිසියම් සඳහනක් තිබේ නම් , එය ඉහළ මට්ටමේ අධීක්ෂණයක් පෙන්නුම් කරයි.

    Magic_quotes පිළිබඳ note තිහාසික සටහන. එම අංගය නිවැරදිව ප්‍රතික්ෂේප කර ඇත. කෙසේ වෙතත් එය බොහෝ විට වැරදියට නිරූපණය කර ඇත්තේ අසාර්ථක ආරක්ෂක අංගයක් ලෙස ය. නමුත් මැජික්_කෝට්ස් ටෙනිස් බෝල පෝෂණ ප්‍රභවයක් ලෙස අසමත් වී ඇති තරමටම අසාර්ථක ආරක්ෂක ලක්ෂණයකි. එය ඔවුන්ගේ අරමුණ නොවේ.

    PHP2 / FI හි මුල් ක්‍රියාවට නැංවීම මඟින් එය පැහැදිලිවම හඳුන්වා දී ඇත්තේ “ මිල ගණන් ස්වයංක්‍රීයව ගැලවී යන අතර ආකෘති දත්ත කෙලින්ම msql විමසුම් වෙත යැවීම පහසු කරයි ”. ASCII සඳහා පමණක් සහය දක්වන බැවින් mSQL සමඟ භාවිතා කිරීම අහම්බෙන් ආරක්ෂිත විය .
    පසුව PHP3 / Zend විසින් MySQL සඳහා මැජික්_කෝට්ස් නැවත හඳුන්වා දුන් අතර එය වැරදි ලෙස ලේඛනගත කරන ලදී. නමුත් මුලින් එය පහසුව සඳහා වූ අංගයක් මිස ආරක්ෂාව සඳහා නොවේ.

සූදානම් කළ ප්‍රකාශ වෙනස් වන්නේ කෙසේද

ඔබ SQL විමසුම් වලට නූල් විචල්‍යයන් සීරීමට ලක් කරන විට, එය ඔබට අනුගමනය කිරීම සඳහා වඩාත් සංකීර්ණ නොවේ. කේතය සහ දත්ත නැවත වෙන් කිරීම MySQL සඳහා බාහිර උත්සාහයකි.

SQL එන්නත් කිරීම යනු කේත සන්දර්භයට දත්ත ගලා යන විටය . විමසුම් වගන්ති අතර PHP මුලින් විචල්‍යයන් ඇලවූ ස්ථානය දත්ත සමුදා සේවාදායකයෙකුට පසුව හඳුනාගත නොහැක.

බැඳී ඇති පරාමිතීන් සමඟ ඔබ ඔබේ PHP කේතයේ SQL කේතය සහ SQL- සන්දර්භය අගයන් වෙන් කරයි. නමුත් එය තිරය පිටුපස යළිත් වෙනස් නොවේ (PDO :: EMULATE_PREPARES හැර). ඔබගේ දත්ත ගබඩාවට අසමාන SQL විධාන සහ 1: 1 විචල්‍ය අගයන් ලැබේ.

මෙම පිළිතුර අවධාරණය කරන්නේ ඔබ අතහැර දැමීමේ කියවීමේ වාසි ගැන සැලකිලිමත් විය යුතු mysql_බවයි. මෙම දෘශ්‍ය හා තාක්‍ෂණික දත්ත / කේත වෙන් කිරීම නිසා ඉඳහිට කාර්ය සාධන වාසියක් (වෙනස් වෙනස් අගයන් සහිත නැවත නැවත INSERT) ඇත.

සියලු SQL එන්නත් වලට එරෙහිව පරාමිති බන්ධනය තවමත් මැජික් එක්-නැවතුම් විසඳුමක් නොවන බව පරෙස්සම් වන්න . එය දත්ත / අගයන් සඳහා වඩාත් පොදු භාවිතය හසුරුවයි. නමුත් තීරු නම / වගු හඳුනාගැනීම් සුදු ලැයිස්තු ගත කිරීම, ගතික වගන්ති ඉදිකිරීමට උදව් කිරීම හෝ සරල අරාව අගය ලැයිස්තු ගත කළ නොහැක.

දෙමුහුන් PDO භාවිතය

මෙම pdo_*එතීමේ කාර්යයන් කේතීකරණ-හිතකාමී නැවතුම්-පරතර API කරයි. (එය MYSQLIමුග්ධ ශ්‍රිත අත්සන මාරුව සඳහා නොතිබුනේ නම් කුමක් විය හැකිද). ඔවුන් බොහෝ විට සැබෑ PDO නිරාවරණය කරයි.
නැවත ලිවීම නව pdo_ ශ්‍රිත නාම භාවිතා කිරීම නැවැත්විය යුතු නැත. ඔබට එක් එක් pdo_query () සරල $ pdo-> සකස් කරන්න () -> ක්‍රියාත්මක කරන්න () ඇමතුමකට මාරු කළ හැකිය.

කෙසේ වෙතත් නැවත සරල කිරීම ආරම්භ කිරීම වඩාත් සුදුසුය. උදාහරණයක් ලෙස ලබා ගැනීමේ පොදු ප්‍රති result ලය:

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

පුරෝකථනය කිරීමේ ක්‍රියාවලියකින් පමණක් ප්‍රතිස්ථාපනය කළ හැකිය:

foreach ($result as $row) {

නැතහොත් වඩා හොඳ නමුත් සෘජු හා සම්පූර්ණ අරාව ලබා ගැනීම:

$result->fetchAll();

PDO හෝ mysql_ සාමාන්‍යයෙන් අසමත් විමසුම් වලින් පසුව ලබා දෙනවාට වඩා බොහෝ අවස්ථාවන්හිදී ඔබට වඩාත් ප්‍රයෝජනවත් අනතුරු ඇඟවීම් ලැබෙනු ඇත.

වෙනත් විකල්ප

එබැවින් මෙය ප්‍රායෝගික හේතු කිහිපයක් සහ අතහැර දැමිය යුතු වටිනා මාවතක් දෘශ්‍යමාන කළේය mysql_.

වෙත මාරු වීම පමණි ඒක කපන්නේ නැහැ. pdo_query()එය ද එහි ඉදිරිපස කොටසකි.

ඔබ පරාමිති බන්ධනය හඳුන්වා දීම හෝ වඩා හොඳ API වෙතින් වෙනත් දෙයක් භාවිතා කළ නොහැකි නම්, එය අර්ථ විරහිත ස්විචයකි. නවකයින් අධෛර්යමත් නොකිරීමට එය සරල ලෙස නිරූපණය කර ඇතැයි මම විශ්වාස කරමි. (අධ්‍යාපනය සාමාන්‍යයෙන් තහනමට වඩා හොඳින් ක්‍රියාත්මක වේ.)

එය වැඩ කළ හැකි සරලම දේ සඳහා සුදුසුකම් ලැබුවද, එය තවමත් ඉතා පර්යේෂණාත්මක කේතයකි. මම එය සති අන්තයේ ලියා ඇත. කෙසේ වෙතත් විකල්ප රාශියක් තිබේ. PHP දත්ත සමුදාය සාරාංශ කිරීම සඳහා ගූගල් කර ටිකක් පිරික්සන්න . සෑම විටම එවැනි කාර්යයන් සඳහා විශිෂ්ට පුස්තකාල රාශියක් ඇත.

ඔබේ දත්ත සමුදා අන්තර්ක්‍රියා තවදුරටත් සරල කිරීමට ඔබට අවශ්‍ය නම්, පැරිස් / අයිඩියර්ම් වැනි සිතියම් කරුවන් උත්සාහ කර බැලීම වටී. කිසිවෙකු තවදුරටත් ජාවාස්ක්‍රිප්ට් හි හිස් ඩොම් භාවිතා නොකරනවා සේම, මේ දිනවල ඔබට අමු දත්ත සමුදා අතුරු මුහුණතක් ළදරු කිරීමට අවශ්‍ය නැත.


8
pdo_query("INSERT INTO pages VALUES (?,?,?,?,?)", $_POST);ශ්‍රිතය සමඟ ප්‍රවේශම් වන්න - එනම්:pdo_query("INSERT INTO users VALUES (?, ?, ?), $_POST); $_POST = array( 'username' => 'lawl', 'password' => '123', 'is_admin' => 'true');
rickyduck

Om ටොම් ෂුවර්, එය එතරම් නඩත්තු නොකළද (0.9.2 අන්තිමයා විය), ඔබට ෆොසිල ගිණුමක් සෑදිය හැකිය , විකියට එකතු කළ හැකිය, නැතහොත් දෝෂ වාර්තාවක් ගොනු කළ හැකිය (ලියාපදිංචි IIRC නොමැතිව).
මාරියෝ

pdo_real_escape_string() <- මෙය පවා සැබෑ කාර්යයක්ද, මට ඒ සඳහා කිසිදු ලේඛනයක් සොයාගත නොහැකිද? කරුණාකර මේ සඳහා මූලාශ්‍රයක් පළ කරන්න.
රයන් ස්ටෝන්

144

මෙම mysql_කාර්යයන්:

  1. යල්පැන ඇති - ඒවා තවදුරටත් නඩත්තු නොකෙරේ
  2. වෙනත් දත්ත සමුදා පසුබිමකට පහසුවෙන් ගමන් කිරීමට ඔබට ඉඩ නොදෙන්න
  3. එබැවින් සූදානම් කළ ප්‍රකාශයන්ට සහාය නොදක්වන්න
  4. SQL එන්නත් කිරීමේ අවදානමට තුඩු දෙන විමසුම් තැනීම සඳහා සංයුක්තකරණය භාවිතා කිරීමට ක්‍රමලේඛකයින් දිරිමත් කරන්න

18
# 2 සමානව සත්‍ය වේmysqli_
උදාල්

16
සාධාරණ ලෙස කිවහොත්, SQL උපභාෂාවේ විචල්‍යතාවයන් සැලකිල්ලට ගෙන, PDO පවා ඔබට කිසියම් නිශ්චිතභාවයකින් # 2 ලබා නොදේ. ඒ සඳහා ඔබට නිසි ORM ආවරණයක් අවශ්‍ය වේ.
එස්ඩීසී

මෙම mysql_*උත්සවය නව PHP අනුවාද සඳහා mysqlnd කාර්යයන් බවට ෂෙල් වේ. එබැවින් පැරණි සේවාදායක පුස්තකාලය තවදුරටත් නඩත්තු නොකලද, mysqlnd නඩත්තු කරනු ලැබේ :)
hakre

යල්පැනගිය php අනුවාදය හේතුවෙන් බොහෝ වෙබ් සත්කාරක සැපයුම්කරුවන්ට එවැනි වස්තු-නැඹුරු මෝස්තරයකට සහාය විය නොහැක
රාජු yourPepe

@ රාජු ගුජරාටි එබැවින් හැකි වෙබ් සත්කාරක සමාගමක් සොයා ගන්න. ඔබගේ වෙබ් සත්කාරක සමාගම එසේ නොකරන්නේ නම්, ඔවුන්ගේ සේවාදායකයන්ට පහර දීමට ඔවුන් ගොදුරු වීමේ සම්භාවිතාව ඉතා වැඩිය.
අල්නිටැක්

106

තාක්ෂණික හේතූන් ගැන කථා කරන විට ඇත්තේ ඉතා ස්වල්පයක් පමණි, අතිශයින්ම නිශ්චිත හා කලාතුරකින් භාවිතා වේ. බොහෝ දුරට ඔබ ඒවා ඔබේ ජීවිතයේ කිසි විටෙකත් භාවිතා නොකරනු ඇත.
සමහර විට මම නොදැනුවත්කමින් සිටියත්, ඒවා වැනි දේවල් භාවිතා කිරීමට මට කිසි විටෙකත් අවස්ථාවක් නොලැබුණි

  • අවහිර නොකරන, අසමමුහුර්ත විමසුම්
  • ගබඩා කළ ක්‍රියා පටිපාටි බහු ප්‍රති .ල ලබා දෙයි
  • ගුප්තකේතනය (SSL)
  • සම්පීඩනය

ඔබට ඒවා අවශ්‍ය නම් - මේවා MySQL දිගුව වෙතින් වඩාත් ආකර්ෂණීය හා නවීන පෙනුමක් කරා ගමන් කිරීමට තාක්ෂණික හේතු වන බවට සැකයක් නැත.

එසේ වුවද, තාක්ෂණික නොවන ගැටළු කිහිපයක් ද ඇත, එමඟින් ඔබේ අත්දැකීම් ටිකක් අපහසු වේ

  • නවීන PHP අනුවාදයන් සමඟ මෙම කාර්යයන් තවදුරටත් භාවිතා කිරීමෙන් අවලංගු කළ මට්ටමේ දැන්වීම් මතු වේ. ඒවා සරලව නිවා දැමිය හැකිය.
  • future ත අනාගතයකදී, ඒවා සුපුරුදු PHP ගොඩනැගීමෙන් ඉවත් කළ හැකිය. Mydsql ext PECL වෙත ගෙන යන අතර සෑම සත්කාරකයෙක්ම PHP සමඟ එය සම්පාදනය කිරීමට සතුටු වනු ඇත. මන්ද දශක ගණනාවක් තිස්සේ වැඩ කළ වෙබ් අඩවි සේවාදායකයින් අහිමි කර ගැනීමට ඔවුන්ට අවශ්‍ය නැත.
  • Stackoverflow ප්‍රජාවෙන් දැඩි ප්‍රතිරෝධයක්. මෙම අවංක කාර්යයන් ගැන ඔබ සඳහන් කරන සෑම විටම, ඒවා දැඩි තහනම් බව ඔබට කියනු ලැබේ.
  • සාමාන්‍ය PHP භාවිතා කරන්නෙකු වීම, බොහෝ විට මෙම කාර්යයන් භාවිතා කිරීමේ ඔබේ අදහස දෝෂ සහිත සහ වැරදි විය හැකිය. ඔබට වැරදි මාර්ගයක් උගන්වන මෙම නිබන්ධන සහ අත්පොත් සියල්ලම නිසා. කාර්යයන් තමන් විසින්ම නොවේ - මට එය අවධාරණය කළ යුතුව ඇත - නමුත් ඒවා භාවිතා කරන ආකාරය.

මෙම අවසාන ගැටළුව ගැටළුවකි.
එහෙත්, මගේ මතය අනුව, යෝජිත විසඳුම ද වඩා හොඳ නැත. එම සියලු PHP භාවිතා කරන්නන් එකවර SQL විමසුම් නිසි ලෙස හැසිරවිය යුතු ආකාරය ඉගෙන ගනු ඇතැයි යන සිහිනය
මට පෙනේ . බොහෝ දුරට ඉඩ ඔවුන් හුදෙක් mysql_ * mysqli_ කිරීමට *, වෙනස් කිරීමට ඉඩ ඇත යාන්ත්රිකව එකම ප්රවේශය පිටත් . විශේෂයෙන් මයිස්ක්ලි විසින් සූදානම් කළ ප්‍රකාශ භාවිතය ඇදහිය නොහැකි තරම් වේදනාකාරී සහ කරදරකාරී වන බැවිනි. SQL එන්නත් වලින් ආරක්ෂා වීමට ස්වදේශික සූදානම් කළ ප්‍රකාශයන් ප්‍රමාණවත්
නොවන බව සඳහන් නොකල යුතු අතර, mysqli හෝ PDO විසින් විසඳුමක් ලබා නොදේ.

එබැවින්, මෙම අවංක දිගුව සමඟ සටන් කරනවා වෙනුවට, මම කැමතියි වැරදි පුරුදු සමඟ සටන් කිරීමට සහ නිවැරදි මාර්ගයෙන් මිනිසුන් දැනුවත් කිරීමට.

එසේම, වැනි ව්‍යාජ හෝ සැලකිය යුතු නොවන හේතු කිහිපයක් තිබේ

  • ගබඩා කළ ක්‍රියා පටිපාටිවලට සහය නොදක්වයි (අපි mysql_query("CALL my_proc");අවුරුදු ගණනාවක් තිස්සේ භාවිතා කරමින් සිටියෙමු )
  • ගනුදෙනු සඳහා සහය නොදක්වයි (ඉහත ආකාරයටම)
  • බහුවිධ ප්‍රකාශයන්ට සහය නොදක්වයි (ඒවා අවශ්‍ය කාටද?)
  • ක්‍රියාකාරී සංවර්ධනය යටතේ නොවේ (එසේනම් එය ඔබට ප්‍රායෝගික ආකාරයකින් බලපාන්නේ කුමක් ද?)
  • OO අතුරුමුහුණතක් නොමැති වීම (එකක් නිර්මාණය කිරීම පැය කිහිපයක කාරණයකි)
  • සකස් කළ ප්‍රකාශ හෝ පරාමිතිගත විමසුම් සඳහා සහය නොදක්වයි

අන්තිම එක සිත්ගන්නා කරුණකි. MySQL ext ස්වදේශීය සූදානම් කළ ප්‍රකාශයන්ට සහාය නොදක්වුවද , ඒවා ආරක්ෂාව සඳහා අවශ්‍ය නොවේ. අතින් හසුරුවන ස්ථාන දරන්නන් භාවිතයෙන් අපට පහසුවෙන් ව්‍යාජ සකස් කළ ප්‍රකාශ කළ හැකිය (PDO කරන ආකාරයටම):

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- විශේෂිත විශේෂාංග රැසකට සහය දක්වයි.
  • PHP පුද්ගලයින්ගෙන් බහුතරයක් මෙන්, ඔබ අමු කේත ඇමතුම් යෙදුම් කේතයේම භාවිතා කරන්නේ නම් (එය අත්‍යවශ්‍යයෙන්ම වැරදි පුරුද්දකි) - PDO එකම තේරීම වේ , මෙම දිගුව API පමණක් නොව අර්ධ DAL ලෙස මවා පෙන්වන බැවින්, තවමත් අසම්පූර්ණ නමුත් බොහෝ වැදගත් අංග ඉදිරිපත් කරයි, ඒවායින් දෙකක් PDO මයිස්ක්ලි වෙතින් විවේචනාත්මකව වෙන් කොට දක්වයි:

    • මයිස්ක්ලි මෙන් නොව, පීඩීඕ හට ස්ථාන දරන්නන් අගය අනුව බැඳ තැබිය හැකි අතර එමඟින් තරමක් අවුල් සහගත කේත තිර කිහිපයක් නොමැතිව ගතිකව සාදන ලද විමසුම් කළ හැකි ය.
    • MySQL මෙන් නොව PDO හට සෑම විටම සරල සුපුරුදු අරාවකින් විමසුම් ප්‍රති result ල ලබා දිය හැකි අතර mysqli හට එය කළ හැක්කේ mysqlnd ස්ථාපනයන් මත පමණි.

එබැවින්, ඔබ සාමාන්‍ය PHP භාවිතා කරන්නෙකු නම් සහ දේශීය සූදානම් ප්‍රකාශ භාවිතා කරන විට හිසරදයක් ඉතිරි කර ගැනීමට අවශ්‍ය නම්, PDO - නැවතත් - එකම තේරීම වේ.
කෙසේ වෙතත්, PDO ද රිදී උණ්ඩයක් නොවන අතර එහි දුෂ්කරතා ද ඇත.
එබැවින්, PDO ටැග් විකියේ ඇති සියලුම පොදු අන්තරායන් සහ සංකීර්ණ අවස්ථාවන් සඳහා මම විසඳුම් ලිව්වෙමි

කෙසේ වෙතත්, දිගු ගැන කතා කරන සෑම කෙනෙකුම සෑම විටම මිස්ක්ලි සහ පීඩීඕ පිළිබඳ වැදගත් කරුණු 2 මග හැරී ඇත:

  1. සකස් කළ ප්‍රකාශය රිදී උණ්ඩයක් නොවේ . සකස් කළ ප්‍රකාශ භාවිතා කර බැඳිය නොහැකි ගතික හඳුනාගැනීම් තිබේ. නොදන්නා පරාමිති ගණනක් සහිත ගතික විමසුම් ඇත, එමඟින් විමසුම් ගොඩනැගීම දුෂ්කර කාර්යයක් වේ.

  2. යෙදුම් කේතයේ mysqli_ * හෝ PDO කාර්යයන් නොතිබිය යුතුය. ඒවා සහ යෙදුම් කේතය අතර වියුක්ත ස්ථරයක්
    තිබිය යුතු අතර, එමඟින් බන්ධන, ලූප, දෝෂ හැසිරවීම යනාදී සියලු අපිරිසිදු කාර්යයන් සිදු කරනු ඇත, යෙදුම් කේතය ඩ්‍රයි සහ පිරිසිදු කරයි. විශේෂයෙන් ගතික විමසුම් ගොඩනැගීම වැනි සංකීර්ණ අවස්ථා සඳහා.

එබැවින්, PDO හෝ mysqli වෙත මාරු වීම පමණක් ප්‍රමාණවත් නොවේ. යමෙකුට ඔවුන්ගේ කේතයේ අමු API කාර්යයන් ඇමතීම වෙනුවට ORM, හෝ විමසුම් සාදන්නෙකු හෝ ඕනෑම දත්ත සමුදා සාරාංශ පන්තියක් භාවිතා කළ යුතුය.
ඊට පටහැනිව - ඔබගේ යෙදුම් කේතය සහ mysql API අතර වියුක්ත ස්ථරයක් තිබේ නම් - ඇත්ත වශයෙන්ම කුමන එන්ජිම භාවිතා කරන්නේද යන්න ගැටළුවක් නොවේ. සියලුම යෙදුම් කේත නොවෙනස්ව පවතින විට ඔබට mysql ext භාවිතා කර එය වියැකී යන තෙක් පහසුවෙන් ඔබේ වියුක්ත පන්තිය වෙනත් එන්ජිමකට නැවත ලිවිය හැකිය .

එවැනි වියුක්ත පංතියක් විය යුතු ආකාරය පෙන්වීමට මගේ සේෆ්මිස්ක්ල් පන්තිය මත පදනම් වූ උදාහරණ කිහිපයක් මෙන්න :

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

මෙම එක් පේළියක් ඔබට අවශ්‍ය කේත ප්‍රමාණය සමඟ PDO සමඟ සසඳන්න . අමු මිස්ක්ලි සකස් කළ ප්‍රකාශ සමඟ ඔබට අවශ්‍ය පිස්සු කේත
සමඟ සසඳන්න . දෝෂ හැසිරවීම, පැතිකඩ, විමසුම් ලොග් වීම දැනටමත් ගොඩනගා ඇති සහ ක්‍රියාත්මක වන බව සලකන්න.

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

සෑම ක්ෂේත්‍ර නාමයක්ම හයත් දහයත් වතාවක් පුනරාවර්තනය වන විට සුපුරුදු PDO ඇතුළු කිරීම් සමඟ සසඳන්න - මේ සියලු නම් කර ඇති ස්ථාන දරන්නන්, බන්ධන සහ විමසුම් අර්ථ දැක්වීම්.

තවත් උදාහරණයක්:

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

එවැනි ප්‍රායෝගික සිද්ධීන් හැසිරවීමට PDO සඳහා උදාහරණයක් ඔබට සොයාගත නොහැක.
තවද එය ඉතා නරක හා බොහෝ විට අනාරක්ෂිත වනු ඇත.

එබැවින්, නැවත වරක් - එය අමු ධාවකයා පමණක් නොව ඔබේ වියුක්ත පන්තිය විය යුතුය, එය ආරම්භක අත්පොතේ මෝඩ උදාහරණ සඳහා පමණක් නොව සැබෑ ජීවිතයේ ඕනෑම ගැටළුවක් විසඳීමට ප්‍රයෝජනවත් වේ.


20
mysql_*අනාරක්‍ෂිතතාවයන් පැමිණීම ඉතා පහසු කරයි. PHP නවක පරිශීලකයින් විශාල ප්‍රමාණයක් භාවිතා කරන බැවින්, mysql_*ප්‍රායෝගිකව ක්‍රියාකාරී ලෙස හානිකර වන අතර, න්‍යායිකව එය බාධාවකින් තොරව භාවිතා කළ හැකිය.
මදාරාගේ අවතාරය

4
everything is parameterized and safe- එය පරාමිතිකරණය කළ හැකි නමුත් ඔබේ ශ්‍රිතය සත්‍ය ලෙස සකස් කළ ප්‍රකාශ භාවිතා නොකරයි .
uınbɐɥs

6
Not under active development'0.01%' සෑදී ඇත්තේ කෙසේද ? ඔබ මෙම ස්ථාවර ක්‍රියාකාරිත්වය සමඟ යමක් ගොඩනඟන්නේ නම්, වසරක් තුළ ඔබේ mysql අනුවාදය යාවත්කාලීන කර වැඩ නොකරන පද්ධතියක් සමඟ සුළං හමන්නේ නම්, එම '0.01%' තුළ හදිසියේම විශාල පිරිසක් සිටින බව මට විශ්වාසයි. මම කියන්න කැමතියි deprecatedහා not under active developmentසමීපව සම්බන්ධ වේ. ඒ සඳහා “සුදුසු [හේතුවක්] නැත” යැයි ඔබට පැවසිය හැකිය, නමුත් කාරණය නම් විකල්ප අතර තේරීමක් ඉදිරිපත් කළ විට, මම කියන no active developmentතරම්ම නරකද deprecated?
නැනේ

1
Ad මාදරුචිහා: අනාරක්ෂිත බව ඉතා පහසුවෙන් පැමිණිය හැකි ආකාරය ඔබට පැහැදිලි කළ හැකිද? විශේෂයෙන් එම අවදානම් PDO හෝ MySQLi වලට බලපාන්නේ නැති අවස්ථාවන්හිදී ... ඔබ කතා කරන එක එකක් ගැන මා නොදන්නා හෙයිනි.
ircmaxell

4
HaShaquinTrifonoff: නිසැකවම, එය සූදානම් කළ ප්‍රකාශ භාවිතා නොකරයි. නමුත් බොහෝ දෙනා MySQLi හරහා නිර්දේශ කරන PDO ද නොකරයි. එබැවින් එය මෙහි සැලකිය යුතු බලපෑමක් ඇති කරන බව මට විශ්වාස නැත. ඉහත කේතය (තව ටිකක් විග්‍රහ කිරීම සමඟ) ඔබ පෙරනිමියෙන් ප්‍රකාශයක් පිළියෙල කරන විට PDO කරන්නේ කුමක්ද ...
ircmaxell

97

හේතු බොහෝමයක් ඇත, නමුත් සමහර විට වඩාත්ම වැදගත් දෙය නම්, එම කාර්යයන් අනාරක්ෂිත ක්‍රමලේඛන භාවිතයන් දිරිමත් කිරීමයි. සකස් කළ ප්‍රකාශ SQL එන්නත් කිරීමේ ප්‍රහාර වැළැක්වීමට උපකාරී වේ.

mysql_*කාර්යයන් භාවිතා කරන විට , පරිශීලක විසින් සපයනු ලබන පරාමිතීන් හරහා ධාවනය කිරීමට මතක තබා ගත යුතුය mysql_real_escape_string(). ඔබට එක් ස්ථානයක පමණක් අමතක වුවහොත් හෝ ආදානයෙන් කොටසක් පමණක් පැන ගියහොත්, ඔබේ දත්ත සමුදාය ප්‍රහාරයකට ලක්විය හැකිය.

සූදානම් කළ ප්‍රකාශ භාවිතා කිරීම PDOහෝ mysqliඑමඟින් මෙම ආකාරයේ ක්‍රමලේඛන දෝෂ සෑදීම වඩාත් අපහසු වේ.


3
අවාසනාවකට, විචල්‍ය පරාමිති සංඛ්‍යාවක් සම්මත කිරීම සඳහා MySQLi_ * හි ඇති දුර්වල සහයෝගය (ඔබට IN වගන්තියකින් පරීක්ෂා කිරීම සඳහා අගයන් ලැයිස්තුවක් සම්මත කිරීමට අවශ්‍ය විටදී වැනි) පරාමිතීන් භාවිතා නොකිරීමට දිරිගන්වයි, හරියටම එකම සංයුක්ත විමසුම් භාවිතා කිරීමට දිරිගන්වයි. MySQL_ * ඇමතුම් අවදානමට ලක් කරන්න.
කික්ස්ටාර්ට්

5
එහෙත්, නැවත වරක්, අනාරක්ෂිත භාවය යනු mysql_ * ශ්‍රිතයන්ගේ ආවේනික ගැටළුවක් නොව වැරදි භාවිතය පිළිබඳ ගැටළුවකි.
අගමෙම්නස්

2
GAgamemnus ගැටළුව වන්නේ mysql_ * මඟින් එම “වැරදි භාවිතය” ක්‍රියාත්මක කිරීම පහසු කිරීම, විශේෂයෙන් අද්දැකීම් අඩු ක්‍රමලේඛකයින් සඳහා ය. සූදානම් කළ ප්‍රකාශ ක්‍රියාත්මක කරන පුස්තකාල එම ආකාරයේ දෝෂයක් ඇති කිරීම දුෂ්කර කරයි.
ට්‍රොට්

75

මන්ද (වෙනත් හේතු අතර) ආදාන දත්ත සනීපාරක්ෂාව සහතික කිරීම වඩා දුෂ්කර ය. PDO හෝ mysqli සමඟ කරන ආකාරයට ඔබ පරාමිතිගත විමසුම් භාවිතා කරන්නේ නම් ඔබට සම්පූර්ණයෙන්ම අවදානම වළක්වා ගත හැකිය.

උදාහරණයක් ලෙස, යමෙකුට "enhzflep); drop table users"පරිශීලක නාමයක් ලෙස භාවිතා කළ හැකිය. පැරණි කාර්යයන් මඟින් විමසුමකට බහුවිධ ප්‍රකාශ ක්‍රියාත්මක කිරීමට ඉඩ දෙනු ඇත, එම නිසා එම නපුරු බග්ගර් වැනි දෙයකට සම්පූර්ණ වගුවක් මකා දැමිය හැකිය.

යමෙකු mysqli හි PDO භාවිතා කරන්නේ නම්, පරිශීලක නාමය අවසන් වනු ඇත "enhzflep); drop table users".

Bobby-tables.com බලන්න .


10
The old functions will allow executing of multiple statements per query- නැහැ, ඔවුන් එසේ කරන්නේ නැහැ. Ext / mysql සමඟ එවැනි එන්නත් කළ නොහැකිය - PHP සහ MySQL සමඟ මේ ආකාරයේ එන්නත් කළ හැකි එකම ක්‍රමය වන්නේ MySQLi සහ mysqli_multi_query()ක්‍රියාකාරිත්වය භාවිතා කරන විට පමණි . Ext / mysql සහ unescaped නූල් වලින් කළ හැකි කාරුණික එන්නත් කිරීම යනු ' OR '1' = '1දත්ත ගබඩාවෙන් දත්ත ලබා ගැනීම වැනි දේය . සමහර අවස්ථා වලදී උප විමසුම් එන්නත් කළ හැකිය, කෙසේ වෙතත් මේ ආකාරයෙන් දත්ත සමුදාය වෙනස් කිරීමට තවමත් නොහැකි ය.
ඩේව් රැන්ඩම්

64

මෙම පිළිතුර ලියා ඇත්තේ දුර්වල ලෙස ලියා ඇති PHP පරිශීලක වලංගු කිරීමේ කේතය මඟ හැරීම කෙතරම් සුළුද යන්න පෙන්වීමටය, මෙම ප්‍රහාර ක්‍රියාත්මක වන්නේ කෙසේද (සහ කුමක් භාවිතා කරන්නේද) සහ පැරණි MySQL ක්‍රියාකාරකම් ආරක්ෂිතව සකස් කළ ප්‍රකාශයකින් ප්‍රතිස්ථාපනය කරන්නේ කෙසේද - සහ මූලික වශයෙන්, StackOverflow භාවිතා කරන්නන් (බොහෝ විට බොහෝ නියෝජිතයින් සමඟ) නව පරිශීලකයින් ඔවුන්ගේ කේතය වැඩි දියුණු කිරීම සඳහා ප්‍රශ්න අසයි.

පළමුවෙන්ම, කරුණාකර මෙම පරීක්ෂණ 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 කේතය වෙත යා හැකිය.

වෙබ් අඩවියක පරිපාලකයෙකු සඳහා සත්‍යාපන ක්‍රියාවලිය පහත ස්ක්‍රිප්ට් යැයි උපකල්පනය කරමු (සරල කර ඇති නමුත් ඔබ එය පිටපත් කර පරීක්ෂා කිරීම සඳහා භාවිතා කරන්නේ නම් වැඩ කරයි):

<?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>

බැලූ බැල්මට නීත්‍යානුකූල බවක් පෙනේ.

පරිශීලකයාට පුරනය වීම සහ මුරපදය ඇතුළත් කළ යුතුය, නේද?

දීප්තිමත්, පහත සඳහන් දෑ ඇතුළත් නොකරන්න:

user: bob
pass: somePass

එය ඉදිරිපත් කරන්න.

ප්‍රතිදානය පහත පරිදි වේ:

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

සුපිරි! අපේක්ෂා කළ පරිදි වැඩ කිරීම, දැන් සත්‍ය පරිශීලක නාමය සහ මුරපදය උත්සාහ කිරීමට ඉඩ දෙයි:

user: Fluffeh
pass: mypass

අරුම පුදුම! හයි-ෆයිව්ස් වටය, කේතය නිවැරදිව පරිපාලකයෙකු සත්‍යාපනය කළේය. එය පරිපූර්ණයි!

හොඳයි, ඇත්තටම නොවේ. පරිශීලකයා දක්ෂ කුඩා පුද්ගලයෙක් යැයි කියමු. පුද්ගලයා මම බව කියමු.

පහත සඳහන් දෑ ඇතුළත් කරන්න:

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

ප්‍රතිදානය:

The check passed. We have a verified admin!

සුභ පැතුම්, ව්‍යාජ පරිශීලක නාමයක් සහ ව්‍යාජ මුරපදයක් ඇතුළත් කරමින් මා සමඟ පමණක් ඔබගේ සුපිරි ආරක්ෂිත පරිපාලක අංශයට ඇතුළු වීමට ඔබ මට අවසර දී ඇත. බරපතල ලෙස, ඔබ මාව විශ්වාස නොකරන්නේ නම්, මා ලබා දුන් කේතය සමඟ දත්ත සමුදාය නිර්මාණය කර මෙම PHP කේතය ක්‍රියාත්මක කරන්න - බැලූ බැල්මට ඇත්ත වශයෙන්ම පරිශීලක නාමය සහ මුරපදය මනාව සත්‍යාපනය වන බව පෙනේ.

ඉතින්, පිළිතුරක් වශයෙන්, ඔබ කෑගසන්නේ ඇයි?

ඉතින්, වැරැද්ද කුමක්දැයි සොයා බලමු, සහ මම ඔබේ සුපිරි පරිපාලක-පමණක්-වවුල්-ගුහාවට ඇතුළු වූයේ ඇයි. මම අනුමාන කළ අතර ඔබ ඔබේ යෙදවුම් ගැන සැලකිලිමත් නොවන බව උපකල්පනය කර ඒවා කෙලින්ම දත්ත ගබඩාවට ලබා දුන්නා. මම ආදානය ගොඩනඟා ගත්තේ ඔබ සැබවින්ම ක්‍රියාත්මක වන විමසුම වෙනස් කරන ආකාරයටයි. ඉතින්, එය කුමක් විය යුතුද? එය අවසන් වූයේ කුමක් ද?

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'

මුරපදය වටා ඇති තනි උපුටා දැක්වීම පළමුව වසා දමා සම්පූර්ණයෙන්ම නව සංසන්දනයක් හඳුන්වා දීම සඳහා මම මගේ "මුරපදය" සෑදූ ආකාරය බලන්න. ආරක්ෂාව සඳහා, මම තවත් "නූලක්" එකතු කළෙමි, එවිට අප මුලින් තිබූ කේතයේ අපේක්ෂිත පරිදි තනි උපුටා දැක්වීම වසා දැමෙනු ඇත.

කෙසේ වෙතත්, මෙය දැන් ඔබට කෑගසන අය ගැන නොවේ, මෙය ඔබේ කේතය වඩාත් ආරක්‍ෂිත කරන්නේ කෙසේදැයි පෙන්වීමයි.

හරි, ඉතින් මොකක්ද වැරැද්ද වෙලා තියෙන්නේ, අපි කොහොමද ඒක හදන්නේ?

මෙය සම්භාව්‍ය SQL එන්නත් කිරීමේ ප්‍රහාරයකි. ඒ කාරණය සඳහා සරලම එකක්. ප්‍රහාරක වාහකයන්ගේ පරිමාණයෙන්, මෙය කුඩා දරුවෙක් ටැංකියකට පහර දී ජයග්‍රහණය කරයි.

ඉතින්, අපි ඔබේ පරිශුද්ධ පරිපාලක අංශය ආරක්ෂා කර එය ලස්සන හා ආරක්ෂිත කරන්නේ කෙසේද? කළ යුතු පළමු දෙය නම්, පැරණි හා අතහැර දැමූ mysql_*කාර්යයන් භාවිතා කිරීම නැවැත්වීමයි . මම දන්නවා, ඔබ අන්තර්ජාලය හරහා සොයාගත් නිබන්ධනයක් අනුගමනය කළ අතර එය ක්‍රියාත්මක වේ, නමුත් එය පැරණි ය, එය යල් පැන ගිය එකක් වන අතර මිනිත්තු කිහිපයකින් මම දහඩිය බිඳීමකින් තොරව එය පසු කර ඇත්තෙමි.

දැන්, ඔබට mysqli_ හෝ PDO භාවිතා කිරීමට වඩා හොඳ විකල්ප තිබේ . මම පුද්ගලිකව PDO හි විශාල රසිකයෙක්, එබැවින් මෙම පිළිතුරේ ඉතිරි කොටසෙහි මම PDO භාවිතා කරමි. ප්‍රෝ සහ කෝන් ඇත, නමුත් පුද්ගලිකව මට පෙනී යන්නේ ගැති ප්‍රවීණයන්ට වඩා බොහෝ සෙයින් වැඩි බවයි. එය බහු දත්ත සමුදා එන්ජින් හරහා අතේ ගෙන යා හැකිය - ඔබ MySQL හෝ Oracle භාවිතා කරන්නේද නැතහොත් ලේවැකි කිසිවක් ගැනද - සම්බන්ධතා නූල වෙනස් කිරීමෙන් පමණක්, අපට භාවිතා කිරීමට අවශ්‍ය සියලුම විසිතුරු අංග එහි ඇති අතර එය ලස්සන හා පිරිසිදුයි. මම පිරිසිදුට කැමතියි.

දැන්, එම කේතය නැවත බැලීමට ඉඩ දෙන්න, මෙවර 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 වස්තුවක් හරහා සිදු වේ, දෙවනුව, එය සූදානම් ප්‍රකාශයක් භාවිතා කරයි. දැන්, ඔබ අසන පෙර ප්‍රකාශයක් කුමක්ද? විමසුමක් ක්‍රියාත්මක කිරීමට පෙර දත්ත සමුදායට පැවසීමට එය ක්‍රමයක් වන අතර, අප විසින් ක්‍රියාත්මක කිරීමට යන විමසුම කුමක්ද. මෙම අවස්ථාවේදී, අපි දත්ත සමුදායට කියමු: "හායි, මම තෝරාගත් ප්‍රකාශයක් ක්‍රියාත්මක කිරීමට යන්නේ හැඳුනුම්පත, පරිශීලක සහ පාස් අවශ්‍ය මේස භාවිතා කරන්නන්ගෙන් ය.

ඉන්පසුව, ක්‍රියාත්මක කිරීමේ ප්‍රකාශයේ දී, දත්ත සමුදාය දැන් අපේක්ෂා කරන සියලු විචල්‍යයන් සමඟ අරාවක් ලබා දේ.

ප්‍රති results ල අපූරු ය. පෙර සිටම එම පරිශීලක නාමය සහ මුරපද සංයෝජන උත්සාහ කරමු:

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...

ප්‍රශ්න පළ කිරීමේදී ඔබ කෑගසන්නේ මේ නිසා ය - එයට හේතුව ඔබගේ කේතය උත්සාහයෙන් තොරව මඟ හැරිය හැකි බව මිනිසුන්ට දැකිය හැකි බැවිනි. කරුණාකර, ඔබේ කේතය වැඩිදියුණු කිරීමට, එය වඩාත් ආරක්‍ෂිත කිරීමට සහ වර්තමාන කාර්යයන් භාවිතා කිරීමට මෙම ප්‍රශ්නය සහ පිළිතුර භාවිතා කරන්න.

අවසාන වශයෙන්, මෙය PERFECT කේතය යැයි කීමට නොවේ. එය වැඩිදියුණු කිරීම සඳහා ඔබට කළ හැකි තවත් බොහෝ දේ ඇත, උදාහරණයක් ලෙස හැෂ් මුරපද භාවිතා කරන්න, ඔබ සංවේදී දත්ත ගබඩාවේ ගබඩා කරන විට, ඔබ එය සරල පෙළෙහි ගබඩා නොකරන බවටත්, විවිධ මට්ටමේ සත්‍යාපන ඇති බවටත් සහතික වන්න - නමුත් ඇත්ත වශයෙන්ම, ඔබ ඔබේ පැරණි එන්නත් කිරීමේ කේතය මේ සඳහා වෙනස් කළහොත්, ඔබ හොඳ කේතයක් ලිවීමේ මාවත ඔස්සේ හොඳ වනු ඇත - තවද ඔබ මෙතරම් දුරට පැමිණ ඇති අතර තවමත් කියවමින් සිටින නිසා ඔබ මෙම වර්ගය පමණක් ක්‍රියාත්මක නොකරනු ඇතැයි යන බලාපොරොත්තුව මට ලබා දෙයි. ඔබේ වෙබ් අඩවි සහ යෙදුම් ලිවීමේදී කේතයේ, නමුත් ඔබ පිටතට ගොස් මා සඳහන් කළ වෙනත් දේවල් ගවේෂණය කිරීමට - සහ තවත්. ඔබට හැකි හොඳම කේතය ලියන්න, යන්තම් ක්‍රියාත්මක වන මූලික කේතය නොවේ.


2
ඔබගේ පිළිතුරට ස්තූතියි! මගේ +1 ගන්න! එය mysql_*අනාරක්ෂිත නොවන බව සඳහන් කිරීම වටී , නමුත් එය නරක නිබන්ධන හරහා අනාරක්ෂිත කේත ප්‍රවර්ධනය කරන අතර නිසි ප්‍රකාශයක් නොමැතිකම API සකස් කරයි.
මදාරාගේ අවතාරය

2
නොකැඩූ මුරපද, අපොයි! = oP එසේ නොමැතිනම් සවිස්තරාත්මක පැහැදිලි කිරීම සඳහා +1.
ගුප්ත ツ

33

MySQL දිගුව මෙම තුනෙන් පැරණිතම වන අතර සංවර්ධකයින් MySQL සමඟ සන්නිවේදනය කිරීමට භාවිතා කළ මුල් ක්‍රමය මෙයයි. PHP සහ MySQL යන දෙඅංශයේම නවතම නිකුතුවල වැඩි දියුණු කිරීම් නිසා මෙම දිගුව අනෙක් විකල්ප දෙක සඳහා දැන් ඉවත් කර ඇත .

  • MySQLi යනු MySQL දත්ත සමුදායන් සමඟ වැඩ කිරීම සඳහා වැඩි දියුණු කළ දිගුවකි. එය MySQL සේවාදායකයේ නවතම අනුවාද වලින් ලබා ගත හැකි විශේෂාංග වලින් වාසි ලබා ගනී, ක්‍රියාකාරී-නැඹුරු සහ වස්තු-නැඹුරු අතුරු මුහුණතක් යන දෙකම සංවර්ධකයාට නිරාවරණය කරයි.

  • PDO විසින් ප්‍රධාන දත්ත සමුදා ප්‍රවේශ දීර් ensions කිරීම්, එනම් MySQL, PostgreSQL, SQLite, MSSQL යනාදිය හරහා කලින් ව්‍යාප්ත කර ඇති බොහෝ ක්‍රියාකාරකම් ඒකාබද්ධ කරන API එකක් ඉදිරිපත් කරයි. දත්ත සමුදා සම්බන්ධතා, විමසුම් සහ ප්‍රති set ල කට්ටල, සහ පහත් මට්ටමේ රියදුරන් දත්ත සමුදා සේවාදායකය සමඟ සන්නිවේදනය සහ සම්පත් හැසිරවීම සිදු කරයි. බොහෝ සාකච්ඡා සහ වැඩ PDO තුළට යන අතර එය නවීන, වෘත්තීය කේතයන්හි දත්ත සමුදායන් සමඟ වැඩ කිරීමේ සුදුසු ක්‍රමය ලෙස සැලකේ.


21

සාරාංශගත කිරීම සඳහා ඉහත පිළිතුරු සැබවින්ම දිගු බව මට පෙනේ:

MySQL දිගුවෙහි වාසි ගණනාවක් ඇත, mysql දිගුවෙහි ප්‍රධාන වැඩි දියුණු කිරීම් වන්නේ:

  • වස්තු-නැඹුරු අතුරුමුහුණත
  • සකස් කළ ප්‍රකාශ සඳහා සහාය
  • බහුවිධ ප්‍රකාශ සඳහා සහාය
  • ගනුදෙනු සඳහා සහාය
  • නිදොස් කිරීමේ හැකියාවන් වැඩි දියුණු කිරීම
  • කාවැද්දූ සේවාදායක සහාය

මුලාශ්‍රය: MySQLi දළ විශ්ලේෂණය


ඉහත පිළිතුරු වල පැහැදිලි කර ඇති පරිදි, mysql සඳහා විකල්ප වන්නේ mysqli සහ PDO (PHP Data Objects) ය.

  • ඒපීඅයි සේවාදායකයේ පැත්තෙන් සූදානම් කළ ප්‍රකාශ සඳහා සහය දක්වයි: MYSQLi සහ PDO සහාය දක්වයි
  • ඒපීඅයි විසින් සේවාදායකයාගේ පැත්තෙන් සූදානම් කළ ප්‍රකාශ සඳහා සහය දක්වයි: සහාය දක්වන්නේ පීඩීඕ පමණි
  • API ගබඩා කළ ක්‍රියා පටිපාටි සඳහා සහය දක්වයි: MySQLi සහ PDO යන දෙකම
  • ඒපීඅයි බහුවිධ ප්‍රකාශ සහ සියලුම MySQL 4.1+ ක්‍රියාකාරීත්වයට සහය දක්වයි - MySQLi සහ බොහෝ විට PDO විසින් සහය දක්වයි

MySQLi සහ PDO යන දෙකම PHP 5.0 හි හඳුන්වා දී ඇති අතර PHP 3.0 ට පෙර MySQL හඳුන්වා දෙන ලදී. සැලකිල්ලට ගත යුතු කරුණක් නම්, පසු සංස්කරණ වලින් ඉවත් කළද, MySQL PHP5.x හි ඇතුළත් කර ඇත.


2
ඔබේ පිළිතුර ඉතා දිගු වන අතර සැබෑ සාරාංශය "mysql ext තවදුරටත් නැත" යන්නයි. එච්චරයි
ඔබේ පොදු හැඟීම

1
@YourCommonSense මගේ පිළිතුර වන්නේ mysql mysql වෙනුවට ආදේශ කළේ ඇයි යන්නයි. කාරණය වන්නේ අද මිස්ක්ලි පවතින බව පැවසීම නොවේ, එබැවින් එය භාවිතා කරන්න .. හැමෝම එය දනිති!
Ani Menon

1
හොඳයි, මයිස්ක්ලි මිස්ක්ල් වෙනුවට ආදේශ කළේ ඇයිදැයි කිසිවෙකු ඇසූ කාරණයට අමතරව, එය මෙම ප්‍රශ්නයට පිළිතුරු සපයන්නේද නැත. මයිස්ක්ලි හඳුන්වා දුන්නේ ඇයිද යන්න එයට පිළිතුරු සපයයි. නමුත් mysql සහ mysqli සමාන්තරව ජීවත් වීමට ඉඩ නොදුන්නේ මන්දැයි එය පැහැදිලි නොකරයි
Your Common Sense

OurYourCommonSense එසේම OP හි ප්‍රශ්නය වන්නේ "ඔවුන් මගේ වෙබ් අඩවියේ වැඩ කළත් වෙනත් දෙයක් භාවිතා කළ යුත්තේ ඇයි?" ඒ නිසා තමයි මම වෙනස්කම් සහ වැඩිදියුණු කිරීම් පෙන්වා දුන්නේ. ඔබට අනෙක් සියලුම පිළිතුරු දෙස බැලීමට හැකි බැවින් ඒවා සාරාංශගත කළ යුතු යැයි මම සිතුවෙමි.
Ani Menon

6

mysql_*MySQL හෝ PDO භාවිතා කරමින් සියලුම කාර්යයන් පාහේ අර්ථ දැක්විය හැකිය . ඔබගේ පැරණි PHP යෙදුමට ඉහළින් ඒවා ඇතුළත් කරන්න, එවිට එය PHP7 මත ක්‍රියා කරයි. මගේ විසඳුම මෙතන .

<?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;
}

ඔබේ විසඳුම සඳහා සබැඳිය පෙන්වීම වෙනුවට කරුණාකර ඒවා පිළිතුර ලෙස මෙහි එක් කරන්න.
අමර්නාත්

-9

mysql_ * ශ්‍රිත ඉවත් කරන ලදි (සිටවඩා හොඳ කාර්යයන් සහ කේත ව්‍යුහයන් සංවර්ධනය කර ඇති PHP 5.5 අනුව ) ඉවත් කරන ලදි. ශ්‍රිතය අවලංගු කර තිබීම යන්නෙන් අදහස් වන්නේ කාර්ය සාධනය සහ ආරක්ෂාව අනුව එය වැඩිදියුණු කිරීමට වැඩි උත්සාහයක් නොගන්නා බවයි, එයින් අදහස් වන්නේ එය අනාගත සාධනය අඩු බවයි.

ඔබට තවත් හේතු අවශ්‍ය නම්:

  • mysql_ * කාර්යයන් සකස් කළ ප්‍රකාශයන්ට සහාය නොදක්වයි.
  • mysql_ * ශ්‍රිතයන් සහාය නොදක්වයි.
  • mysql_ * ශ්‍රිතයට වස්තු ක්‍රියාකාරීත්වයක් නොමැත.
  • ලැයිස්තුව දිගටම ...

18
මෙම පිළිතුර යල්පැන ඇති ය. ඇරත්, එය දැනටමත් පවතින පිළිතුරු වලට ප්‍රයෝජනවත් කිසිවක් එකතු නොකරයි.
ඔබේ පොදු හැඟීම
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.