MySQL में गतिशील WHERE क्लॉज बनाएं

मेरे पास यह कोड है और यह बहुत अच्छा काम करता है, अगर मैं सिर्फ कार्यालय के नाम से खोजना चाहता हूं। हालांकि मुझे तीनों के किसी भी संयोजन, "कार्यालय और/या पहला नाम और/या अंतिम नाम" द्वारा खोज करने में सक्षम होना चाहिए।

$firstName      = $_POST["firstName"];
$lastName       = $_POST["lastName"];
$officeName     = $_POST ["officeName"];

$query = "SELECT 
e.*,
e.id emp_id,
o.*
";
$query .= "FROM 
employee_data e,
office o,
employee_office_pivot p
"; 
$query .= "WHERE 
1=1
AND e.id=p.employee_id
AND p.office_id=o.id
AND o.office_name= '".$officeName."'
";

मैं WHERE क्लॉज कैसे बना सकता हूं, ताकि यह तीन कॉलम में से किसी एक को स्वीकार कर सके, या कोई भी शून्य न हो।

धन्यवाद, रिचर्ड

2
सबसे पहले आप एसक्यूएल इंजेक्शन हमलों के बारे में पढ़कर शुरू करते हैं और सीखते हैं कि आपका कोड खतरनाक क्यों है।
जोड़ा लेखक Marc B, स्रोत

3 उत्तर

कुछ इस तरह?

$query .= "WHERE 
    1=1
    AND e.id=p.employee_id
    AND p.office_id=o.id
    AND (o.office_name= '".mysqli_real_escape_string($officeName)."'
        OR o.office_name= '".mysqli_real_escape_string($firstName)."'
        OR o.office_name= '".mysqli_real_escape_string($lastName)."')
    ";

मैंने उदाहरण के रूप में mysqli_real_escape_string() का उपयोग किया है, आपको अपने सिस्टम में SQL इंजेक्शन से बचने के लिए सही और आवश्यक सावधानी बरतनी चाहिए।

2
जोड़ा
यह काम करता है, लेकिन केवल अगर मैं mysqli_real_escape_string निकालता हूं
जोड़ा लेखक rwrogers, स्रोत
यह मेरा कनेक्शन स्ट्रिंग है। $ कनेक्शन = mysqli_connect ($ dbhost, $ dbuser, $ dbpass, $ dbname);
जोड़ा लेखक rwrogers, स्रोत
नहीं, कुछ भी नहीं, कोई त्रुटि नहीं और कोई परिणाम नहीं लौटा।
जोड़ा लेखक rwrogers, स्रोत
ऐसा शायद इसलिए है क्योंकि आप mysqli एक्सटेंशन का उपयोग नहीं कर रहे हैं। डीबी से कनेक्ट करने के लिए आप किसका उपयोग कर रहे हैं?
जोड़ा लेखक Aioros, स्रोत
क्या तुम्हें कोई त्रुटि का संदेश मिला है?
जोड़ा लेखक Aioros, स्रोत
क्या आप अपनी स्क्रिप्ट की शुरुआत में इन दो लाइनों को जोड़ सकते हैं और पुनः प्रयास कर सकते हैं? error_reporting (E_ALL); ini_set ('display_errors', 1);
जोड़ा लेखक Aioros, स्रोत
यह नहीं जानता कि किस कनेक्शन का उपयोग करना है। आपको या तो mysqli_real_escape_string ($ कनेक्शन, $ officeName) या $ कनेक्शन-> real_escape_string ($ officeName) का उपयोग करना होगा, जहां बाद वाला संभवतः आपकी स्पष्ट ऑब्जेक्ट उन्मुख शैली के साथ बेहतर फिट बैठता है । स्रोत: php.net/manual/de/mysqli.real-escape- string.php
जोड़ा लेखक Christian, स्रोत

आप अपने एसक्यूएल को गतिशील रूप से बनाने के लिए सरणी का उपयोग कर सकते हैं:

/**
 *  The items you expect to receive from $_POST. I prefer defining these ahead of time - when feasible - 
 *  so that you can reference them without worrying about throwing an error if they are not set.
 */
$options = array_fill_keys(array('firstName', 'lastName', 'officeName'), false);
$post = array_merge($options, $_POST);
/**
 *  Your base SQL query.
 */
$sql = 'SELECT ...columns... FROM ...tables... WHERE 1 = 1';
$where = array();
/**
 *  If $_POST items are present, sanitize and create SQL
 */
if ( $post['firstName'] ) {
    $where[] = "employee_first_name = '".mysqli_real_escape_string($post['firstName'])."'";
}
if ( $post['lastName'] ) {
    $where[] = "employee_last_name = '".mysqli_real_escape_string($post['lastName'])."'";
}
if ( $post['officeName'] ) {
    $where[] = "office_name = '".mysqli_real_escape_string($post['officeName'])."'";
}
/**
 *  One or more $_POST items were found, so add them to the query
 */
if ( sizeof($where) > 0 ) {
    $sql .= ' AND '.implode(' AND ', $where);   
}

एसक्यूएल में कॉलम, टेबल में शामिल इत्यादि को गतिशील रूप से जोड़ने के लिए आप उसी तकनीक का उपयोग कर सकते हैं। (संकेत: एक सरणी का उपयोग करके संपूर्ण SQL कथन बनाएं।) आप AND और OR के संयोजनों का उपयोग करने के लिए इसे आसानी से संशोधित भी कर सकते हैं।

1
जोड़ा
$values = array(
    'firstName'  => 'someFirstName',
    'lastName'   => 'someLastName',
    'officeName' => 'someOfficeName'
);

foreach( $values as $col => $val )
{
    $where .= "$key = '$balue' ";
}

हालांकि यह एसक्यूएल इंजेक्शन कमजोर है।

0
जोड़ा
इस तरह से कुछ भी गलत है?
जोड़ा लेखक Virus721, स्रोत
चूंकि डेटा सैनिटाइजिंग इस बात पर निर्भर करता है कि लेखक क्या उपयोग कर रहा है (यानी पीडीओ या माइस्क्ल या जो भी हो)।
जोड़ा लेखक Virus721, स्रोत
जैसा कि आपने कहा था, "9 0% प्रश्नों में एसक्यूएल इंजेक्शन भेद्यताएं आ रही हैं", जिसका अर्थ है कि किसी को ऐसे प्रश्नों के 90% उत्तरों में उसी स्वच्छता कोड को फिर से लिखना होगा, वाह, आप एक कुशल प्रोग्रामर प्रतीत होते हैं। .. मैंने इसे बोल्ड में लिखा है, यह कमजोर है। यदि लड़का वास्तव में इसके बारे में परवाह करता है, तो उसे इसके बारे में बात करने वाले हजारों प्रश्नों में से एक में आसानी से इसके बारे में अधिक जानकारी मिल जाएगी। यदि नहीं, तो मैं sanitizing कोड लिख सकता हूं, वह इस पर ध्यान नहीं देगा।
जोड़ा लेखक Virus721, स्रोत
"हालांकि यह एसक्यूएल इंजेक्शन कमजोर है।" अगर आपको पता है कि यह बेहद असुरक्षित है तो जवाब क्यों दें?
जोड़ा लेखक Snowburnt, स्रोत
एसक्यूएल इंजेक्शन भेद्यता में आने वाले 9 0% प्रश्नों में से केवल एक नज़र है। मैं डर दूंगा कि आप लोगों के समूह के 1% में हैं जो यह भी जानते हैं कि एसक्यूएल इंजेक्शन क्या है और यह एक मुद्दा क्यों है। कुछ ज्ञान फैलाएं और लोगों को दिखाएं कि डाटाबेस ड्राइवरों के पीछे छिपाने के बजाय खुद को कैसे सुरक्षित रखें।
जोड़ा लेखक Snowburnt, स्रोत
वास्तव में यह नहीं है कि हर प्रश्न के लिए एक तैयार कथन लिखने या real_escape_string पर टाइल लिखना मुश्किल हो और वास्तव में यह सभी स्वच्छता है जो SQL इंजेक्शन के लिए होने की आवश्यकता है। एसक्यूएल इंजेक्शन एक बहुत खतरनाक भेद्यता है और यह बहुत ही आम है और केवल आपके कोड में कुछ वर्ण जोड़ने के लिए बहुत आसान है। जाहिर है, ऐसा होना चाहिए जो अधिक होना चाहिए, लेकिन यह अधिक व्यक्तिपरक है, एसक्यूएल इंजेक्शन को ठीक करना सरल और सीधा-आगे है। आपने टिप्पणी अनुभाग में बहुत अधिक समय बर्बाद कर दिया है, इससे पहले कि आप एसक्यूएल इंजेक्शन भेद्यता को नहीं छोड़ पाएंगे।
जोड़ा लेखक Snowburnt, स्रोत
यह उद्धरण में तुलना मूल्यों के साथ इंजेक्शन कमजोर नहीं है और मूल्य इस बिंदु पर पहुंचने से पहले "sanitized" हो सकता है ....
जोड़ा लेखक G-Man, स्रोत