PHP का उपयोग करते हुए SQL सर्वर में तार से कैसे बचें?


89

मैं mysql_real_escape_string()SQL सर्वर के लिए विकल्प की तलाश कर रहा हूँ । क्या addslashes()मेरा सबसे अच्छा विकल्प है या कोई अन्य वैकल्पिक फ़ंक्शन है जिसका उपयोग किया जा सकता है?

के लिए एक विकल्प mysql_error()भी उपयोगी होगा।


2
मेरे लिए यह कोई डुप्लिकेट प्रश्न नहीं है क्योंकि यह विशिष्ट MSSQL केस की चिंता करता है जिसमें एक संबंधित आधिकारिक पीडीओ नहीं है
पियरे डे लेसपिन

जवाबों:


74

addslashes()पूरी तरह से पर्याप्त नहीं है, लेकिन PHP के mssql पैकेज कोई भी अच्छा विकल्प प्रदान नहीं करता है। बदसूरत, लेकिन पूरी तरह से सामान्य समाधान डेटा को हेक्स बायट्रस्टिंग के रूप में एन्कोडिंग है, अर्थात

$unpacked = unpack('H*hex', $data);
mssql_query('
    INSERT INTO sometable (somecolumn)
    VALUES (0x' . $unpacked['hex'] . ')
');

सार, यह होगा:

function mssql_escape($data) {
    if(is_numeric($data))
        return $data;
    $unpacked = unpack('H*hex', $data);
    return '0x' . $unpacked['hex'];
}

mssql_query('
    INSERT INTO sometable (somecolumn)
    VALUES (' . mssql_escape($somevalue) . ')
');

mysql_error()समतुल्य है mssql_get_last_message()


1
ओह, इसका चयन SCOPE_IDENTITY ()!
ब्रायन रेहबिन

4
@ जीनियो: मम्म, महान, वास्तव में इसे छोड़कर। मुझे नहीं लगता कि आप बताएंगे कि आप क्या समस्या मानते हैं?
अराजकता

3
क्या आपने इसे डेटाइम कॉलम के साथ आज़माया है? मुझे यह त्रुटि मिल रही है: SQLSTATE[22007]: Invalid datetime format: 210 [Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting datetime from binary/varbinary string.मेरा मानना ​​है कि यह विधि तभी सही हो सकती है जब यह प्रत्येक MSSQL डेटाटाइप के साथ काम करे।
एलेजांद्रो गार्सिया इग्लेसियस

1
mssql_escape()फंक्शन का कंटेंट मेरे लिए ऐसा नहीं कर रहा है। चयन करने के बाद पाठ प्रदर्शन इस 0x4a2761696d65206269656e206c652063686f636f6c6174तरह से अपठनीय है।
जेफ नोएल

3
@JeffNoel आपका शायद स्ट्रिंग सिंगल कोट्स या डबल कोट्स को लपेटता है। चूँकि आइटम हेक्स में बच गया है, उद्धरण neccesary नहीं हैं। एसक्यूएल सर्वर को माना जाता है कि डीबी को समझने के लिए हेक्स मूल्य को परिवर्तित करना है।
danielson317

40
function ms_escape_string($data) {
        if ( !isset($data) or empty($data) ) return '';
        if ( is_numeric($data) ) return $data;

        $non_displayables = array(
            '/%0[0-8bcef]/',            // url encoded 00-08, 11, 12, 14, 15
            '/%1[0-9a-f]/',             // url encoded 16-31
            '/[\x00-\x08]/',            // 00-08
            '/\x0b/',                   // 11
            '/\x0c/',                   // 12
            '/[\x0e-\x1f]/'             // 14-31
        );
        foreach ( $non_displayables as $regex )
            $data = preg_replace( $regex, '', $data );
        $data = str_replace("'", "''", $data );
        return $data;
    }

यहाँ कुछ कोड CodeIgniter से काट दिए गए थे। अच्छी तरह से काम करता है और एक साफ समाधान है।

EDIT: ऊपर कोड स्निपेट के साथ बहुत सारे मुद्दे हैं। कृपया उन टिप्पणियों को पढ़ने के बिना इसका उपयोग न करें कि वे क्या हैं। बेहतर अभी तक, कृपया इस का उपयोग न करें। पैरामीटरकृत प्रश्न आपके मित्र हैं: http://php.net/manual/en/pdo.prepared-statements.php


1
आपको इसकी आवश्यकता क्यों है preg_replace? str_replaceपर्याप्त नहीं है ?
गाबे

gabe: इस मामले में preg_replace मुझे नियमित अभिव्यक्ति चरित्र वर्गों में मेरे लिए वहन की गई सीमाओं का उपयोग करने की अनुमति देने के लिए था। अन्यथा इसमें बहुत अधिक स्ट्रिंग की जगह होगी।
जीनियो

7
-1। यह डेटा को मैन करने के लिए एक उद्धरण समारोह की जिम्मेदारी नहीं है - यह सब करना चाहिए सुनिश्चित करें कि स्ट्रिंग इस तरह के प्रारूप में है कि यह एक एसक्यूएल बयान में जोड़ा जा सकता है और असमान बच सकता है।
cHao

6
क्षमा करें, लेकिन यह कोड की पहली पंक्ति से गलत है - न केवल के लिए , बल्कि इसके लिए भी empty($value)लौटेगा , और ! आप उन सभी मामलों में एक खाली स्ट्रिंग लौटाएंगे। true''null0'0'
13:15

जब तक आप ऊपर के मुद्दों से पूरी तरह अवगत नहीं हैं, मुझे लगता है कि यह पूरी तरह से ठीक है। हालांकि मैं इसे ms_escape_and_strip_string कहूंगा, इसलिए इस पर काम करने वाला कोई भी व्यक्ति यह देखेगा कि यह दोनों कार्य करता है। जब तक आप इसके लिए खाते हैं, तब तक कई मामलों में खाली स्ट्रिंग लौटाया जाना ठीक है, जब तक कि मैं यहाँ एक बड़ा बिंदु याद नहीं कर रहा हूँ। यदि यह आपकी आवश्यकताओं के अनुकूल नहीं है, तो आप हमेशा उस लाइन को बाहर निकाल सकते हैं और इसे अपनी आवश्यकताओं के अनुरूप तर्क के साथ बदल सकते हैं।
14

16

जब आप अपनी क्वेरी में मापदंडों का उपयोग कर सकते हैं तो आप कुछ भी बचने से क्यों परेशान होंगे ?!

sqlsrv_query(
    $connection, 
    'UPDATE some_table SET some_field = ? WHERE other_field = ?', 
    array($_REQUEST['some_field'], $_REQUEST['id'])
)

यह चयन में सही काम करता है, हटाता है, चाहे आपके मान पैरामीटर हैं nullया नहीं , अपडेट । सिद्धांत की बात करें - एसक्यूएल को न बदलें और आप हमेशा सुरक्षित रहें और आपके प्रश्न बहुत बेहतर पढ़ें।

http://php.net/manual/en/function.sqlsrv-query.php


यह सही तरीका है। तदर्थ प्रश्नों के विपरीत आपको हमेशा मापदंडों का उपयोग करना चाहिए। हालांकि, ओपी sqlsrv ड्राइवरों का उपयोग नहीं कर रहा है। वह mssql ड्राइवरों का उपयोग कर रहा है। तो आप उन लोगों के लिए उपयोग करने के लिए लिंक जो sqlsrv ड्राइवरों का उपयोग करते हुए अटक गए हैं, http://php.net/manual/en/function.mssql-query.php है
smulholland2

1
@ smulholland2 क्या आपका मतलब है "या आप में से जो MSSQL ड्राइवरों का उपयोग कर रहे हैं "
कोंस्टेंटिन

एक परिदृश्य हो सकता है यदि आप डेटा माइग्रेशन परिदृश्य में उपयोग करने के लिए INSERT कथनों की फ़ाइल जनरेट करना चाहते हैं।
गैरी रेकॉर्ड

11

आप पीडीओ लाइब्रेरी में देख सकते हैं । आप पीडीओ के साथ तैयार किए गए कथनों का उपयोग कर सकते हैं, जो तैयार किए गए कथनों को सही ढंग से करने पर आपके तार में किसी भी खराब अक्षर से बच जाएंगे। यह केवल PHP 5 के लिए है जो मुझे लगता है।


मेरे द्वारा पीडीओ से बाहर किए गए कुछ आधे व्यवहार के साथ, मुझे सभी डेटा को सही ढंग से भागने के लिए भरोसा करने से पहले कुछ गंभीर परीक्षण करने होंगे।
अराजकता

@ सच में? मैं इस बात से अनजान हूँ .. क्या आपके पास किसी लेख का लिंक है?
एलेक्स

मैं क्या सोच रहा था कि इस आदमी को यहाँ पर कल पीडीओ के साथ होने वाली परेशानी थी। असंबंधित लेन-देन सामान, लेकिन अप्रभावी। गठबंधन करें कि PHP में अपर्याप्त डेटा से बचने के सभी इतिहास के साथ (php.net लोगों को Addlashes () का उपयोग करने के लिए कह रहा है!) और मुझे बहुत संदेह है।
अराजकता

2
मुझे पीडीओ से प्यार है और उसने पहले प्रयास किया, लेकिन MSSQL के लिए (Unix पर, dblib पर आधारित) कभी-कभी मुझ पर (विभाजन दोष) विफल हो जाता है, इसीलिए मैंने ऊपर परिभाषित mssql_escape का सहारा लिया।
लैपो

आपकी टिप्पणी के लिए धन्यवाद, @Iapo। मैं एक mssql परियोजना के लिए पीडीओ पर स्विच करने पर विचार कर रहा था - विशेष रूप से बचने के लिए - लेकिन आपने मुझे परेशानी से बचाया है।
विनफील्ड ट्रेल

4

सिंगल और डबल कोट्स को संभालने का दूसरा तरीका है:

function mssql_escape($str)
{
    if(get_magic_quotes_gpc())
    {
        $str = stripslashes($str);
    }
    return str_replace("'", "''", $str);
}

get_magic_quites_gpc को PHP 5.3.0 के रूप में और PHP 5.4.0 के रूप में बनाया गया है। देखें php.net/manual/en/info.configuration.php#ini.magic-quotes-gpc
जनवरी

2

सिंगल- और डबल-कोट्स से बचने के लिए, आपको उन्हें डबल करना होगा:

$value = 'This is a quote, "I said, 'Hi'"';

$value = str_replace( "'", "''", $value ); 

$value = str_replace( '"', '""', $value );

$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";

आदि...

और एट्रिब्यूशन: Microsoft SQL Server 2000 में चरित्र से बच


2

घंटों तक इससे जूझने के बाद, मैं एक ऐसा समाधान लेकर आया हूं जो लगभग सबसे अच्छा लगता है।

अराजकता के मानों को हेक्सस्ट्रिंग में बदलने का जवाब हर डेटाटाइप के साथ काम नहीं करता है, विशेष रूप से डेटाटाइम कॉलम के साथ।

मैं PHP का उपयोग करता हूं PDO::quote(), लेकिन जैसा कि यह PHP के साथ आता है, PDO::quote()एमएस SQL ​​सर्वर और रिटर्न के लिए समर्थित नहीं है FALSE। इसका काम करने का हल कुछ Microsoft बंडलों को डाउनलोड करना था:

उसके बाद आप निम्न उदाहरण जैसे DSN का उपयोग करके PHP को PDO के साथ जोड़ सकते हैं:

sqlsrv:Server=192.168.0.25; Database=My_Database;

का उपयोग करते हुए UIDऔर PWDDSN में पैरामीटर काम नहीं किया, इसलिए यूज़रनेम और पासवर्ड दूसरे और तीसरे पैरामीटर पीडीओ निर्माता के रूप में पारित कर रहे हैं जब कनेक्शन का निर्माण। अब आप PHP का उपयोग कर सकते हैं PDO::quote()। का आनंद लें।


1

उपयोगकर्ता अराजकता से 2009-02-22T121000 का एक उत्तर सभी प्रश्नों को फिट नहीं करता है।

उदाहरण के लिए, "सृजन लॉग [0x6f6c6f6c6f] विन्डोज़ से" आपको एक अपवाद देगा।

PS: PHP, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx और sqlsrv_prepare फ़ंक्शन के लिए SQL सर्वर ड्राइवर को देखें, जो मापदंडों को बांध सकता है।

PSS: जो आपको ऊपर दिए गए क्वेरी से भी मदद नहीं करता;)


0

चेतावनी: यह फ़ंक्शन PHP 7.0.0 में याद किया गया था।

http://php.net/manual/en/function.mssql-query.php

इन mssql_ * फ़ंक्शन का उपयोग करने वाले किसी भी व्यक्ति के लिए, ध्यान रखें कि उन्हें PHP से v7.0.0 के रूप में हटा दिया गया है। तो, इसका मतलब है कि आपको अंततः अपने मॉडल कोड को फिर से लिखना होगा या तो पीडीओ लाइब्रेरी, sqlsrv_ * आदि का उपयोग करना होगा। यदि आप "उद्धृत / भागने" विधि के साथ कुछ खोज रहे हैं, तो मैं पीडीओ की सिफारिश करूंगा।

इस फ़ंक्शन के विकल्प में शामिल हैं: पीडीओ :: क्वेरी (), sqlsrv_query () और odbc_exec ()



0

SQL आरक्षित शब्दों से बचना भी बेहतर है। उदाहरण के लिए:

function ms_escape_string($data) {
    if (!isset($data) or empty($data))
        return '';

    if (is_numeric($data))
        return $data;

    $non_displayables = array(
        '/%0[0-8bcef]/',        // URL encoded 00-08, 11, 12, 14, 15
        '/%1[0-9a-f]/',         // url encoded 16-31
        '/[\x00-\x08]/',        // 00-08
        '/\x0b/',               // 11
        '/\x0c/',               // 12
        '/[\x0e-\x1f]/',        // 14-31
        '/\27/'
    );
    foreach ($non_displayables as $regex)
        $data = preg_replace( $regex, '', $data);
    $reemplazar = array('"', "'", '=');
    $data = str_replace($reemplazar, "*", $data);
    return $data;
}

-1

मैं इसके विकल्प के रूप में उपयोग कर रहा हूं mysql_real_escape_string():

function htmlsan($htmlsanitize){
    return $htmlsanitize = htmlspecialchars($htmlsanitize, ENT_QUOTES, 'UTF-8');
}
$data = "Whatever the value's is";
$data = stripslashes(htmlsan($data));

-1

ASCII में SQL में हेक्साडेसिमल मान प्राप्त करने के लिए रूपांतरण के लिए, यहाँ समाधान है जो मुझे इस पर मिला ( उपयोगकर्ता अराजकता से फ़ंक्शन को हेक्साडेसिमल में एन्कोड करने के लिए)

function hexEncode($data) {
    if(is_numeric($data))
        return $data;
    $unpacked = unpack('H*hex', $data);
    return '0x' . $unpacked['hex'];
}

function hexDecode($hex) {
    $str = '';
    for ($i=0; $i<strlen($hex); $i += 2)
        $str .= chr(hexdec(substr($hex, $i, 2)));
    return $str;
}

$stringHex = hexEncode('Test String');
var_dump($stringHex);
$stringAscii = hexDecode($stringHex);
var_dump($stringAscii);

-2

आप mysql_real_escape_stringनिम्नलिखित नियमित अभिव्यक्ति के साथ अपने स्वयं के संस्करण को रोल कर सकते हैं , (और इसमें सुधार कर सकते हैं) [\000\010\011\012\015\032\042\047\134\140]:। निम्न वर्णों का ध्यान रखता है: अशक्त, बैकस्पेस, क्षैतिज टैब, नई पंक्ति, गाड़ी वापसी, स्थानापन्न, दोहरा उद्धरण, एकल उद्धरण, बैकस्लैश, गंभीर उच्चारण। बैकस्पेस और क्षैतिज टैब द्वारा समर्थित नहीं हैं mysql_real_escape_string

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.