मैं कैसे एक पैरामीटर का चयन करें क्वेरी के लिए पीडीओ ऑब्जेक्ट का ठीक से उपयोग कर सकता हूं


85

मैंने SELECTसवाल करने के लिए PHP.net निर्देशों का पालन करने की कोशिश की है, लेकिन मुझे यकीन नहीं है कि ऐसा करने के बारे में सबसे अच्छा तरीका है।

मैं एक पैरामीटर SELECTक्वेरी का उपयोग करना चाहूंगा , यदि संभव हो तो, IDउस तालिका में वापस करने के लिए जहां nameफ़ील्ड पैरामीटर से मेल खाती है। यह एक लौट आना चाहिए IDक्योंकि यह अद्वितीय होगा।

फिर मैं IDएक INSERTअन्य तालिका में उसका उपयोग करना चाहूंगा , इसलिए मुझे यह निर्धारित करने की आवश्यकता होगी कि यह सफल था या नहीं।

मैंने यह भी पढ़ा कि आप पुन: उपयोग के लिए प्रश्न तैयार कर सकते हैं लेकिन मुझे यकीन नहीं था कि यह कैसे मदद करता है।

जवाबों:


158

आप इस तरह डेटा का चयन करें:

$db = new PDO("...");
$statement = $db->prepare("select id from some_table where name = :name");
$statement->execute(array(':name' => "Jimbo"));
$row = $statement->fetch(); // Use fetchAll() if you want all results, or just iterate over the statement, since it implements Iterator

आप उसी तरह डालें:

$statement = $db->prepare("insert into some_other_table (some_id) values (:some_id)");
$statement->execute(array(':some_id' => $row['id']));

मेरा सुझाव है कि आप त्रुटि पर अपवाद फेंकने के लिए पीडीओ को कॉन्फ़िगर करें। PDOExceptionयदि कोई भी प्रश्न विफल हो जाता है तो आपको मिलेगा - स्पष्ट रूप से जांच करने की आवश्यकता नहीं है। अपवादों को चालू करने के लिए, $dbवस्तु बनाने के बाद इसे कॉल करें :

$db = new PDO("...");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

मुझे लगता है कि आप PDOStatement मतलब है जहाँ आप नए PDO (...), सही है?
जो फिलिप्स

1
नहीं। पीडीओ कनेक्शन-क्लास है (शायद इसकी जगह PdoConnection नाम दिया गया है)। कनेक्शन PdoStatements बना सकता है। आप कनेक्शन ऑब्जेक्ट पर setAttribute () कहते हैं - व्यक्तिगत कथन नहीं। (वैकल्पिक रूप से, आप इसे कंस्ट्रक्टर को पास कर सकते हैं)
troelskn

1
यह उपयोगी हो सकता है:$db = new PDO('mysql:dbname=your_database;host=localhost', 'junior', '444');
जूनियर Mayhé

2
लाइन के लिए $statement->execute(array(':name' => "Jimbo"));, क्या आप जिम्बो भाग की व्याख्या कर सकते हैं?
muttley91

1
@rar पिछली पंक्ति में, प्लेसहोल्डर के साथ क्वेरी शुरू की जाती है :nameexecuteयहां कॉल करना प्लेसहोल्डर -> मूल्य जोड़े के साहचर्य सरणी के साथ किया जाता है। तो इस मामले में, :nameप्लेसहोल्डर को स्ट्रिंग जिम्बो के साथ बदल दिया जाएगा। ध्यान दें कि यह केवल एक स्ट्रिंग-प्रतिस्थापित नहीं कर रहा है, क्योंकि मूल्य या तो बच जाता है या वास्तविक क्वेरी से अलग चैनल पर भेजा जाता है, इस प्रकार किसी भी तरह के इंजेक्शन हमलों को रोकता है।
troelskn

16

मैं हाल ही में पीडीओ के साथ काम कर रहा हूं और ऊपर दिया गया उत्तर पूरी तरह से सही है, लेकिन मैं सिर्फ यह दस्तावेज करना चाहता था कि निम्नलिखित काम भी करता है।

$nametosearch = "Tobias";
$conn = new PDO("server", "username", "password");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sth = $conn->prepare("SELECT `id` from `tablename` WHERE `name` = :name");
$sth->bindParam(':name', $nametosearch);
// Or sth->bindParam(':name', $_POST['namefromform']); depending on application
$sth->execute();

16
नहीं, यह नहीं है, जैसा आपने चुना है कि किस डेटाबेस का उपयोग करना है।
रापली आन्द्रा

3
यह वास्तव में "सर्वर" स्ट्रिंग में होना चाहिए, जो वास्तव में "{ड्राइवर}: dbname = {db_name}; मेजबान = {सर्वर}" के रूप में एक DSN होना चाहिए, जो आपके कनेक्शन की आवश्यकता के साथ घुंघराले ब्रेस मानों की जगह ले रहा है
thorne51

12

आप अपने कथन को तैयार करने में सहायता के लिए bindParamया bindValueविधियों का उपयोग कर सकते हैं । यह $check->execute(array(':name' => $name));विशेष रूप से यदि आप कई मान / चर बाँध रहे हैं, तो करने के बजाय पहली नज़र में चीजें अधिक स्पष्ट करती हैं।

नीचे दिए गए उदाहरण को स्पष्ट, आसान पढ़ने के लिए जांचें:

$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname LIMIT 1");
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname',  'Bloggs');
$q->execute();

if ($q->rowCount() > 0){
    $check = $q->fetch(PDO::FETCH_ASSOC);
    $row_id = $check['id'];
    // do something
}

यदि आप उम्मीद कर रहे हैं कि कई पंक्तियाँ हटा LIMIT 1दी जाएँगी और लाने का तरीका बदल जाएगा fetchAll:

$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname");// removed limit 1
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname',  'Bloggs');
$q->execute();

if ($q->rowCount() > 0){
    $check = $q->fetchAll(PDO::FETCH_ASSOC);
    //$check will now hold an array of returned rows. 
    //let's say we need the second result, i.e. index of 1
    $row_id = $check[1]['id']; 
    // do something
}

निश्चित नहीं। मेरे लिए एक मान्य उत्तर की तरह लगता है। मुझे लगता है कि 'नाम' के बजाय 'myname' का उपयोग करने से फायदा होगा और सिर्फ एक के बजाय कई params का उपयोग करने से।
जो फिलिप्स

@ गिलियनलॉन्ग क्या करता $check = $q->fetch(PDO::FETCH_ASSOC); if (!empty($check)){ $row_id = $check['id']; // do something }है?
अब्दुल

1
Hi @abdul, मैंने सरणी पर गिनती / खाली चेक को बदल दिया है। यह देखना था कि क्या कोई परिणाम वापस आया है या नहीं। लेकिन pdo में एक फ़ंक्शन भी होता है जिसे rowCount () कहा जाता है जो आपको यह जाँचने देता है कि क्या कोई पंक्तियाँ प्रभावित / लाई गई थीं। डेटा प्राप्त करने का कोई मतलब नहीं है यदि आप यह भी नहीं जानते हैं कि क्या कोई पंक्तियों का चयन किया गया था, इसलिए मैंने लाने के बयान को if rowCount () स्टेटमेंट में स्थानांतरित कर दिया। :)
गिली

@Gillian ला वोंग धन्यवाद अपने स्वच्छ bindValue की क्वेरी के लिए कई जहाँ क्वेरी के लिए। कि मेरी परियोजना को बचाओ।
php-coder

6

एक लिट्ल बिट पूरा उत्तर यहां उपयोग के लिए तैयार है:

    $sql = "SELECT `username` FROM `users` WHERE `id` = :id";
    $q = $dbh->prepare($sql);
    $q->execute(array(':id' => "4"));
    $done= $q->fetch();

 echo $done[0];

यहाँ $dbhपीडीओ डीबी कनेक्टर है, और idतालिका से usersहम usernameउपयोग कर रहे हैं पर आधारित हैfetch();

मुझे आशा है कि यह किसी की मदद, आनंद लें!


या जरूरत fetchColumn()से बचने के लिए उपयोग करें [0]। इसके अलावा, LIMIT 1SQL में उपयोग करना याद रखें ।
rybo111

3

विधि 1: USE PDO क्वेरी विधि

$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

पंक्ति गणना हो रही है

$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$row_count = $stmt->rowCount();
echo $row_count.' rows selected';

विधि 2: पैरामीटर के साथ विवरण

$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->execute(array($name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

विधि 3: बाइंड मापदंडों

$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

**bind with named parameters**
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

or
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->execute(array(':name' => $name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

इस लिंक पर और अधिक जानना चाहते हैं


4
कृपया विधि 1 हटा दें। यह mysql इंजेक्शन की अनुमति देता है।
टॉमहॉक

-2

अगर आप सिंगल पेज में इनलाइन कोडिंग का उपयोग कर रहे हैं और इस पूरे उदाहरण के साथ जाने के बजाय ऊप्स का उपयोग नहीं कर रहे हैं, तो यह निश्चित रूप से मदद करेगा

//connect to the db
$dbh = new PDO('mysql:host=localhost;dbname=mydb', dbuser, dbpw); 

//build the query
$query="SELECT field1, field2
FROM ubertable
WHERE field1 > 6969";

//execute the query
$data = $dbh->query($query);
//convert result resource to array
$result = $data->fetchAll(PDO::FETCH_ASSOC);

//view the entire array (for testing)
print_r($result);

//display array elements
foreach($result as $output) {
echo output[field1] . " " . output[field1] . "<br />";
}

हालांकि यह कोड स्निपेट समस्या को हल कर सकता है, यह इस बात की व्याख्या नहीं करता है कि यह प्रश्न का उत्तर क्यों या कैसे देता है। कृपया अपने कोड के लिए एक स्पष्टीकरण शामिल करें , क्योंकि यह वास्तव में आपके पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और वे लोग आपके कोड सुझाव के कारणों को नहीं जान सकते हैं। फ्लैगर्स / समीक्षक: कोड-ओनली उत्तर जैसे कि यह एक, डाउनवोट, डिलीट न करें!
स्कॉट वेल्डन

तो क्या मैं इसे अपने आप को नष्ट कर दूं
शिव सिंह

नहीं, बिल्कुल विपरीत। मैं कम गुणवत्ता वाले पोस्ट कतार में इस पोस्ट पर आया , और इसलिए मेरी टिप्पणी का उत्तरार्द्ध लोगों को यह बताने के लिए था कि वे वोट न दें । (इसके बजाय डाउनवोट करने का सुझाव अनंतिम डाउनवोट्स को संकेत देने के लिए था, जिसे आपके पोस्ट को संपादित किए जाने के बाद हटा दिया जाएगा।) जैसा कि मेरी पिछली टिप्पणी में बताया गया है, यदि आपने जो कोड सुझाया है, उसके लिए स्पष्टीकरण जोड़ा जाए तो बेहतर होगा। । साथ ही, यह प्रश्न पैरामीटर किए गए प्रश्नों के बारे में पूछता है, लेकिन field > 6969पैरामीटर के बजाय कठोर-कोडित दिखता है।
स्कॉट वेल्डन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.