2011-12-23 16 views
5

मैं PHP/पीडीओ का उपयोग कर MySQL में मेरी पहली लेन-देन स्थापित करने के लिए कोशिश कर रहा हूँ ...पीएचपी पीडीओ MySQL लेन-देन कोड संरचना

मैं सिर्फ एक त्वरित सवाल है, सबसे अच्छा तरीका है, तो पहले की क्वेरी था निर्धारित करने के लिए है कि क्या सफल या नहीं? यहां मेरे पास अभी है, लेकिन मुझे एक कथन के साथ क्वेरी का परीक्षण करने का एक तरीका मिल जाएगा।

यह एक कामकाजी मॉडल प्राप्त करने के लिए बहुत अधिक नकली कोड है .. मुझे पता है कि कुछ भी अच्छा या बुरा होने पर $ परिणाम प्रभावी ढंग से परीक्षण नहीं कर रहे हैं .. मेरे पास असली सौदा के लिए एक जगह धारक के रूप में और अधिक है समय आता है जब ..

if ($_POST['groupID'] && is_numeric($_POST['groupID'])) { 
    $sql = "SET AUTOCOMMIT=0"; 
    $dbs = $dbo->prepare($sql); 
    $dbs->execute(); 

    $sql = "START TRANSACTION"; 
    $dbs = $dbo->prepare($sql); 
    $dbs->execute(); 

    $sql = "DELETE FROM users_priveleges WHERE GroupID=:groupID"; 
    $dbs = $dbo->prepare($sql); 
    $dbs->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT); 
    $dbs->execute(); 

    try { 
     $sql = "DELETE FROM groups WHERE GroupID=:groupID LIMIT 1"; 
     $dbs = $dbo->prepare($sql); 
     $dbs->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT); 
     $dbs->execute(); 

     $results["error"] = null; 
     $results["success"] = true; 

     try { 
      $sql = "DELETE FROM users WHERE Group=:groupID"; 
      $dbs = $dbo->prepare($sql); 
      $dbs->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT); 
      $dbs->execute(); 

      $results["error"] = null; 
      $results["success"] = true; 

      $sql = "COMMIT"; 
      $dbs = $dbo->prepare($sql); 
      $dbs->execute(); 
     } 
     catch (PDOException $e) { 
      $sql = "ROLLBACK"; 
      $dbs = $dbo->prepare($sql); 
      $dbs->execute(); 

      $results["error"] = "Could not delete associated users! $e"; 
      $results["success"] = false; 
     } 
    } 
    catch (PDOException $e) 
    { 
     $sql = "ROLLBACK"; 
     $dbs = $dbo->prepare($sql); 
     $dbs->execute(); 

     $results["error"] = "COULD NOT REMOVE GROUP! $e"; 
     $results["success"] = false; 
    } 
} 
+2

क्यों नहीं उपयोग पीडीओ के beginTransaction(), प्रतिबद्ध और() पद्धतियों? – GordonM

+0

एलओएल मैंने आज सुबह शुरूआत की प्रक्रिया के बारे में सीखा ... मुझे लगा कि दूसरे दो वहां थे, लेकिन उन्हें अभी तक नहीं देखा था। यह धन्यवाद TODO सूची पर है धन्यवाद! – guyfromfl

+0

इसके अलावा, आपको प्रत्येक कथन तैयार करने की ज़रूरत नहीं है, वास्तव में यह उन लोगों के लिए अपर्याप्त है जिनमें आप किसी भी चर डालने वाले नहीं हैं। बस इसके बजाय क्वेरी() के साथ चलाएं। कोड और अनावश्यक तैयार दोनों पंक्तियों पर बचाता है। – GordonM

उत्तर

3

पीडीओ वक्तव्य के execute() रिटर्न सफलता पर सही और, विफलता पर गलत तो आप अपने अगर बयान में पिछले execute() के रिटर्न मान परीक्षण कर सकते हैं।

$pdo_result = $dbs->execute(); 
if ($pdo_result) { 
    // handle success 
} else { 
    // handle failure 
    // you can get error info with $dbs->errorInfo(); 
} 

कहा, के रूप में @Bill Kerwin सही ढंग से बताते हैं (अपने जवाब है कि मैं पूरी तरह से upvoting हूं, क्योंकि यह वास्तव में सही है में), यह PDO::beginTransaction(), PDO::commit(), और PDO::rollback() उपयोग करने के लिए बेहतर होगा।

+0

मुझे कैसे पता चलेगा कि त्रुटि के कारण क्या हुआ? मैं इसे समस्या के प्रति उत्तरदायी बनाना चाहता हूं। क्षमा करें पहले लेनदेन अभी भी पीडीओ के लिए नया है ... प्रतिक्रिया – guyfromfl

+1

'$ dbs-> errorInfo() के लिए धन्यवाद, स्पष्टीकरण के लिए http://www.php.net/manual/en/pdostatement.errorinfo.php पर दस्तावेज़ देखें इसके वापसी मूल्य का। – Trott

+0

सुंदर धन्यवाद ... – guyfromfl

6

मैं & लेनदेन विवरण निष्पादित नहीं करता। मैं PDO::beginTransaction(), PDO::commit(), और PDO::rollback() का उपयोग करता हूं।

पीडीओ :: तैयार() और पीडीओ :: निष्पादित() कोई त्रुटि होने पर गलत लौटाएं, अन्यथा यदि आप setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) पर पीडीओएक्सप्शन फेंक देते हैं।

अपने अपवाद हैंडलर में, आपको PDO::errorInfo() जांचना चाहिए और त्रुटि की प्रकृति की रिपोर्ट करना चाहिए। सबसे अच्छा अभ्यास कच्चे त्रुटि की जानकारी लॉग करना है, लेकिन उपयोगकर्ता को एक और दोस्ताना संदेश देना है।

यूआई में शाब्दिक त्रुटि संदेश गूंज न करें - यह उपयोगकर्ता को आपकी SQL क्वेरी और स्कीमा के बारे में अनुचित ज्ञान दे सकता है।

+0

हाँ मैंने पहले लेनदेन विधियों के बारे में सीखा था।विशिष्ट कारण को पकड़ने के लिए, मेरे और मेरे सीमित अनुभव के लिए, यदि कथन बयान आसान है, तो मैं इसे नियंत्रित करना चाहता था। मैंने यह भी पढ़ा कि विभिन्न कारणों से मैं जो कर रहा हूं उसके लिए प्रयास आदर्श नहीं हैं। जानकारी के लिए धन्यवाद। देखने के लिए बहुत कुछ! – guyfromfl

+0

मैंने अभी दो बार चेक किया है, जब मैं $ dbo ऑब्जेक्ट को तुरंत चालू करता हूं, तो सेटएट्रिब्यूट विकल्प पारित किया जाता है, इसलिए हम वहां अच्छे हैं .. फ़ीड के लिए धन्यवाद – guyfromfl

20

कुछ सामान्य नोट: bindParam() का उपयोग जब तक आप एक प्रक्रिया है कि पैरामीटर का मान इसलिए, use bindValue() को संशोधित प्रयोग न करें। bindParam() एक संदर्भित चर के रूप में तर्क मान स्वीकार करता है। इसका मतलब है कि आप $stmt->bindParam(':num', 1, PDO::PARAM_INT); नहीं कर सकते - यह एक त्रुटि उठाता है। इसके अलावा, पीडीओ के लेनदेन को नियंत्रित करने के लिए अपने स्वयं के कार्य हैं, आपको मैन्युअल रूप से क्वेरी निष्पादित करने की आवश्यकता नहीं है।

मैं थोड़ा अपने कोड दुबारा लिखा कैसे पीडीओ इस्तेमाल किया जा सकता पर कुछ प्रकाश डाला करने के लिए:() रोलबैक

if($_POST['groupID'] && is_numeric($_POST['groupID'])) 
{ 
    // List the SQL strings that you want to use 
    $sql['privileges'] = "DELETE FROM users_priveleges WHERE GroupID=:groupID"; 
    $sql['groups']  = "DELETE FROM groups WHERE GroupID=:groupID"; // You don't need LIMIT 1, GroupID should be unique (primary) so it's controlled by the DB 
    $sql['users']  = "DELETE FROM users WHERE Group=:groupID"; 

    // Start the transaction. PDO turns autocommit mode off depending on the driver, you don't need to implicitly say you want it off 
    $pdo->beginTransaction(); 

    try 
    { 
     // Prepare the statements 
     foreach($sql as $stmt_name => &$sql_command) 
     { 
      $stmt[$stmt_name] = $pdo->prepare($sql_command); 
     } 

     // Delete the privileges 
     $stmt['privileges']->bindValue(':groupID', $_POST['groupID'], PDO::PARAM_INT); 
     $stmt['privileges']->execute(); 

     // Delete the group 
     $stmt['groups']->bindValue(":groupID", $_POST['groupID'], PDO::PARAM_INT); 
     $stmt['groups']->execute(); 

     // Delete the user 
     $stmt['users']->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT); 
     $stmt['users']->execute(); 

     $pdo->commit();  
    } 
    catch(PDOException $e) 
    { 
     $pdo->rollBack(); 

     // Report errors 
    }  
} 
+0

बिंदपाराम/वैल्यू जानकारी के लिए वाह धन्यवाद ... सभी पीडीओ ट्यूटोरियल मैंने पढ़ा है कि बाइंडपाराम का इस्तेमाल किया गया है .. वह कोड बहुत अच्छा लग रहा है, मैं आपके विचारों के साथ झुकाऊंगा, समझ में आता हूं। – guyfromfl

+0

मुझे उस त्रुटि में त्रुटि मिल रही है जब वह उस समूह के उपयोगकर्ताओं को हटाने का प्रयास करता है। त्रुटि समूह = 38 के पास कहती है ... अन्य दो प्रश्न अभी भी अन्य तालिकाओं में अन्य पंक्तियों को हटाते हैं, ऐसा लगता है कि लेनदेन ठीक से काम नहीं कर रहा है ... – guyfromfl

+0

'ग्रुप' एक एसक्यूएल आरक्षित शब्द है, इसलिए आपको इसे रखने की आवश्यकता हो सकती है यह बैक-कोट्स में है। लेकिन इसका नाम बदलना बेहतर होगा, इसलिए यह एक आरक्षित शब्द नहीं है, और इसलिए आपकी सभी टेबलें इसे 'GroupID' नाम देती हैं। –

संबंधित मुद्दे