PHP
PHP MySQLi
खोज…
परिचय
mysqli
इंटरफ़ेस , mysql
इंटरफ़ेस का एक सुधार (इसका अर्थ है "MySQL इम्प्रूवमेंट एक्सटेंशन") है, जिसे संस्करण 5.5 में हटा दिया गया था और इसे 7.0 संस्करण में हटा दिया गया है। Mysqli एक्सटेंशन, या जैसा कि यह कभी-कभी जाना जाता है, MySQL में सुधार हुआ विस्तार, MySQL सिस्टम संस्करणों 4.1.3 और नए में मिली नई सुविधाओं का लाभ उठाने के लिए विकसित किया गया था। Mysqli का विस्तार PHP के संस्करण 5 और बाद के संस्करण के साथ शामिल है।
टिप्पणियों
विशेषताएं
Mysqli इंटरफ़ेस में कई लाभ हैं, mysql एक्सटेंशन में महत्वपूर्ण वृद्धि:
- ऑब्जेक्ट-ओरिएंटेड इंटरफ़ेस
- तैयार स्टेटमेंट के लिए समर्थन
- एकाधिक विवरणों के लिए समर्थन
- लेन-देन के लिए समर्थन
- बढ़ी डिबगिंग क्षमताओं
- एंबेडेड सर्वर समर्थन
इसमें एक दोहरी इंटरफ़ेस है : पुरानी, प्रक्रियात्मक शैली और एक नई, वस्तु-उन्मुख प्रोग्रामिंग (ओओपी) शैली। हटाए गए mysql
में केवल एक प्रक्रियात्मक इंटरफ़ेस था, इसलिए ऑब्जेक्ट-ओरिएंटेड शैली अक्सर पसंद की जाती है। हालाँकि, OOP की शक्ति के कारण नई शैली भी अनुकूल है।
वैकल्पिक
डेटाबेस तक पहुँचने के लिए mysqli
इंटरफ़ेस का एक विकल्प नया PHP डेटा ऑब्जेक्ट्स (PDO) इंटरफ़ेस है। यह केवल ओओपी-शैली प्रोग्रामिंग की सुविधा देता है और केवल MySQL प्रकार के डेटाबेस से अधिक का उपयोग कर सकता है।
MySQLi कनेक्ट
वस्तु उन्मुख शैली
सर्वर से कनेक्ट करें
$conn = new mysqli("localhost","my_user","my_password");
डिफ़ॉल्ट डेटाबेस सेट करें: $conn->select_db("my_db");
डेटाबेस से कनेक्ट करें
$conn = new mysqli("localhost","my_user","my_password","my_db");
प्रक्रियात्मक शैली
सर्वर से कनेक्ट करें
$conn = mysqli_connect("localhost","my_user","my_password");
डिफ़ॉल्ट डेटाबेस सेट करें: mysqli_select_db($conn, "my_db");
डेटाबेस से कनेक्ट करें
$conn = mysqli_connect("localhost","my_user","my_password","my_db");
डेटाबेस कनेक्शन सत्यापित करें
वस्तु उन्मुख शैली
if ($conn->connect_errno > 0) {
trigger_error($db->connect_error);
} // else: successfully connected
प्रक्रियात्मक शैली
if (!$conn) {
trigger_error(mysqli_connect_error());
} // else: successfully connected
MySQLi क्वेरी
query
फ़ंक्शन एक मान्य SQL स्ट्रिंग लेता है और इसे डेटाबेस कनेक्शन $conn
खिलाफ सीधे निष्पादित करता है
वस्तु उन्मुख शैली
$result = $conn->query("SELECT * FROM `people`");
प्रक्रियात्मक शैली
$result = mysqli_query($conn, "SELECT * FROM `people`");
सावधान
यहां एक आम समस्या यह है कि लोग क्वेरी को निष्पादित करेंगे और इसे काम करने की उम्मीद करेंगे (यानी एक mysqli_stmt ऑब्जेक्ट लौटाएंगे)। चूंकि यह फ़ंक्शन केवल एक स्ट्रिंग लेता है, आप पहले स्वयं क्वेरी बना रहे हैं। यदि SQL में कोई गलतियाँ हैं, तो MySQL कंपाइलर विफल हो जाएगा, जिस बिंदु पर यह फ़ंक्शन false
वापस आ जाएगा ।
$result = $conn->query('SELECT * FROM non_existent_table'); // This query will fail
$row = $result->fetch_assoc();
उपरोक्त कोड E_FATAL
त्रुटि उत्पन्न करेगा क्योंकि $result
false
, और एक वस्तु नहीं है।
PHP घातक त्रुटि: एक गैर-ऑब्जेक्ट पर एक सदस्य फ़ंक्शन fetch_assoc () पर कॉल करें
प्रक्रियात्मक त्रुटि समान है, लेकिन घातक नहीं है, क्योंकि हम केवल फ़ंक्शन की अपेक्षाओं का उल्लंघन कर रहे हैं।
$row = mysqli_fetch_assoc($result); // same query as previous
आपको निम्न संदेश PHP से मिलेगा
mysqli_fetch_array () पैरामीटर 1 को mysqli_result होने की उम्मीद है, बूलियन दिया गया
पहले टेस्ट कराकर आप इससे बच सकते हैं
if($result) $row = mysqli_fetch_assoc($result);
MySQLi परिणामों के माध्यम से लूप
PHP आपके परिणाम से डेटा प्राप्त करना आसान बनाता है और while
कथन का उपयोग करके उस पर लूप करता है। जब यह अगली पंक्ति प्राप्त करने में विफल रहता है, तो यह false
, और आपका लूप समाप्त हो जाता है। इन उदाहरणों के साथ काम करते हैं
- mysqli_fetch_assoc - कुंजी के रूप में स्तंभ नामों के साथ साहचर्य सरणी
- mysqli_fetch_object -
stdClass
ऑब्जेक्ट को स्तंभ नामों के साथ चर के रूप में - mysqli_fetch_array - साहचर्य और संख्यात्मक सरणी (एक या दूसरे को प्राप्त करने के लिए तर्कों का उपयोग कर सकते हैं)
- mysqli_fetch_row - न्यूमेरिक सरणी
वस्तु उन्मुख शैली
while($row = $result->fetch_assoc()) {
var_dump($row);
}
प्रक्रियात्मक शैली
while($row = mysqli_fetch_assoc($result)) {
var_dump($row);
}
परिणामों से सटीक जानकारी प्राप्त करने के लिए, हम उपयोग कर सकते हैं:
while ($row = $result->fetch_assoc()) {
echo 'Name and surname: '.$row['name'].' '.$row['surname'].'<br>';
echo 'Age: '.$row['age'].'<br>'; // Prints info from 'age' column
}
निकट संबंध
जब हम डेटाबेस को क्वेरी करना समाप्त कर लेते हैं, तो संसाधनों को मुक्त करने के लिए कनेक्शन को बंद करने की सिफारिश की जाती है।
वस्तु उन्मुख शैली
$conn->close();
प्रक्रियात्मक शैली
mysqli_close($conn);
नोट : सर्वर के कनेक्शन को स्क्रिप्ट के निष्पादन के समाप्त होते ही बंद कर दिया जाएगा, जब तक कि यह क्लोज कनेक्शन फ़ंक्शन को स्पष्ट रूप से कॉल करके पहले बंद नहीं हो जाता है।
केस का उपयोग करें: यदि हमारी स्क्रिप्ट में परिणाम प्राप्त करने के बाद प्रदर्शन करने के लिए उचित मात्रा में प्रसंस्करण है और पूर्ण परिणाम सेट को पुनः प्राप्त किया है, तो हमें निश्चित रूप से कनेक्शन बंद करना चाहिए। यदि हम नहीं थे, तो एक मौका है जब वेब सर्वर भारी उपयोग के तहत MySQL सर्वर अपनी कनेक्शन सीमा तक पहुंच जाएगा।
MySQLi में तैयार स्टेटमेंट
कृपया तैयार किए गए बयानों की पूरी चर्चा के लिए पैरामीट्रीड क्वैरिज़ के साथ SQL इंजेक्शन को रोकना पढ़ें ताकि आप SQL इंजेक्शन के हमलों से अपने SQL स्टेटमेंट को सुरक्षित कर सकें।
यहाँ $conn
चर एक MySQLi ऑब्जेक्ट है। अधिक विवरण के लिए MySQLi कनेक्ट उदाहरण देखें।
दोनों उदाहरणों के लिए, हम मानते हैं कि $sql
है
$sql = "SELECT column_1
FROM table
WHERE column_2 = ?
AND column_3 > ?";
?
उन मूल्यों का प्रतिनिधित्व करता है जो हम बाद में प्रदान करेंगे। कृपया ध्यान दें कि हमें प्रकार की परवाह किए बिना, प्लेसहोल्डर्स के लिए उद्धरण चिह्नों की आवश्यकता नहीं है। हम केवल क्वेरी के डेटा भागों में प्लेसहोल्डर भी प्रदान कर सकते हैं, जिसका अर्थ है SET
, VALUES
और WHERE
। आप प्लेसहोल्डर को SELECT
या FROM
भागों में उपयोग नहीं कर सकते।
वस्तु उन्मुख शैली
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param("si", $column_2_value, $column_3_value);
$stmt->execute();
$stmt->bind_result($column_1);
$stmt->fetch();
//Now use variable $column_1 one as if it were any other PHP variable
$stmt->close();
}
प्रक्रियात्मक शैली
if ($stmt = mysqli_prepare($conn, $sql)) {
mysqli_stmt_bind_param($stmt, "si", $column_2_value, $column_3_value);
mysqli_stmt_execute($stmt);
// Fetch data here
mysqli_stmt_close($stmt);
}
$stmt->bind_param
का पहला पैरामीटर- $stmt->bind_param
या mysqli_stmt_bind_param
का दूसरा पैरामीटर SQL क्वेरी में संबंधित पैरामीटर के डेटा प्रकार द्वारा निर्धारित किया जाता है:
पैरामीटर | बाउंड पैरामीटर का डेटा प्रकार |
---|---|
i | पूर्णांक |
d | दोहरा |
s | तार |
b | बूँद |
आपकी क्वेरी में दिए गए क्रम में मापदंडों की आपकी सूची आवश्यक है। इस उदाहरण में si
अर्थ है पहला पैरामीटर ( column_2 = ?
) स्ट्रिंग है और दूसरा पैरामीटर ( column_3 > ?
) पूर्णांक है।
डेटा पुनर्प्राप्त करने के लिए, देखें कि तैयार स्टेटमेंट से डेटा कैसे प्राप्त करें
भागने के तार
बचने के तार एक क्वेरी में प्रविष्टि के लिए डेटा हासिल करने का एक पुराना ( और कम सुरक्षित ) तरीका है। यह MySQL के फ़ंक्शन mysql_real_escape_string () को संसाधित करने और डेटा को साफ करने के लिए (दूसरे शब्दों में, PHP पलायन नहीं कर रहा है) का उपयोग करके काम करता है। MySQLi API इस फ़ंक्शन के लिए सीधी पहुँच प्रदान करता है
$escaped = $conn->real_escape_string($_GET['var']);
// OR
$escaped = mysqli_real_escape_string($conn, $_GET['var']);
इस बिंदु पर, आपके पास एक स्ट्रिंग है जिसे MySQL प्रत्यक्ष क्वेरी में उपयोग के लिए सुरक्षित मानता है
$sql = 'SELECT * FROM users WHERE username = "' . $escaped . '"';
$result = $conn->query($sql);
तो यह तैयार बयानों जितना सुरक्षित क्यों नहीं है? MySQL को सुरक्षित बनाने के लिए स्ट्रिंग का उत्पादन करने के तरीके हैं। निम्नलिखित उदाहरण पर विचार करें
$id = mysqli_real_escape_string("1 OR 1=1");
$sql = 'SELECT * FROM table WHERE id = ' . $id;
1 OR 1=1
डेटा का प्रतिनिधित्व नहीं करता है जो MySQL से बच जाएगा, फिर भी यह अभी भी SQL इंजेक्शन का प्रतिनिधित्व करता है। अन्य उदाहरण भी हैं जो उन स्थानों का प्रतिनिधित्व करते हैं जहां यह असुरक्षित डेटा देता है। समस्या यह है कि MySQL का एस्केप फ़ंक्शन SQL सिंटैक्स के साथ डेटा का अनुपालन करने के लिए डिज़ाइन किया गया है। यह सुनिश्चित करने के लिए डिज़ाइन नहीं किया गया है कि MySQL SQL निर्देशों के लिए उपयोगकर्ता डेटा को भ्रमित नहीं कर सकता है ।
MySQLi Insert ID
किसी AUTO_INCREMENT कॉलम वाली तालिका पर INSERT
क्वेरी द्वारा बनाई गई अंतिम ID को पुनः प्राप्त करें।
वस्तु-उन्मुख शैली
$id = $conn->insert_id;
प्रक्रियात्मक शैली
$id = mysqli_insert_id($conn);
यदि कनेक्शन पर कोई पिछली क्वेरी नहीं थी या यदि किसी AUTO_INCREMENT मान को अपडेट नहीं किया था, तो शून्य रिटर्न देता है।
पंक्तियों को अपडेट करते समय आईडी डालें
आम तौर पर एक UPDATE
कथन एक सम्मिलित आईडी वापस नहीं करता है, क्योंकि एक AUTO_INCREMENT
आईडी केवल तभी वापस किया जाता है जब एक नई पंक्ति को सहेजा गया हो (या डाला गया हो)। नई आईडी के लिए अपडेट करने का एक तरीका INSERT ... ON DUPLICATE KEY UPDATE
का उपयोग करना है INSERT ... ON DUPLICATE KEY UPDATE
करने के लिए INSERT ... ON DUPLICATE KEY UPDATE
सिंटैक्स पर।
अनुसरण करने के लिए उदाहरणों के लिए सेटअप:
CREATE TABLE iodku (
id INT AUTO_INCREMENT NOT NULL,
name VARCHAR(99) NOT NULL,
misc INT NOT NULL,
PRIMARY KEY(id),
UNIQUE(name)
) ENGINE=InnoDB;
INSERT INTO iodku (name, misc)
VALUES
('Leslie', 123),
('Sally', 456);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
+----+--------+------+
| id | name | misc |
+----+--------+------+
| 1 | Leslie | 123 |
| 2 | Sally | 456 |
+----+--------+------+
IODKU का मामला एक "अपडेट" और LAST_INSERT_ID()
प्रासंगिक id
पुनः प्राप्त करने का कार्य कर रहा है:
$sql = "INSERT INTO iodku (name, misc)
VALUES
('Sally', 3333) -- should update
ON DUPLICATE KEY UPDATE -- `name` will trigger "duplicate key"
id = LAST_INSERT_ID(id),
misc = VALUES(misc)";
$conn->query($sql);
$id = $conn->insert_id; -- picking up existing value (2)
वह मामला जहां IODKU एक "इन्सर्ट" करता है और LAST_INSERT_ID()
नई id
पुनः प्राप्त करता है:
$sql = "INSERT INTO iodku (name, misc)
VALUES
('Dana', 789) -- Should insert
ON DUPLICATE KEY UPDATE
id = LAST_INSERT_ID(id),
misc = VALUES(misc);
$conn->query($sql);
$id = $conn->insert_id; -- picking up new value (3)
परिणाम तालिका सामग्री:
SELECT * FROM iodku;
+----+--------+------+
| id | name | misc |
+----+--------+------+
| 1 | Leslie | 123 |
| 2 | Sally | 3333 | -- IODKU changed this
| 3 | Dana | 789 | -- IODKU added this
+----+--------+------+
MySQLi में डीबगिंग एसक्यूएल
तो आपकी क्वेरी विफल हो गई है (देखें MySQLi कनेक्ट के लिए कि हमने $conn
कैसे बनाया)
$result = $conn->query('SELECT * FROM non_existent_table'); // This query will fail
हमें कैसे पता चलेगा कि क्या हुआ? $result
false
इसलिए कोई मदद नहीं है। शुक्र है कि कनेक्ट $conn
हमें बता सकते हैं कि MySQL ने हमें विफलता के बारे में क्या बताया
trigger_error($conn->error);
या प्रक्रियात्मक
trigger_error(mysqli_error($conn));
आपको इसके समान त्रुटि मिलनी चाहिए
तालिका 'my_db.non_existent_table' मौजूद नहीं है
तैयार स्टेटमेंट से डेटा कैसे प्राप्त करें
तैयार बयान
क्वेरी तैयार करने और निष्पादित करने के तरीके के लिए MySQLi में तैयार कथन देखें।
परिणामों की बाध्यता
वस्तु-उन्मुख शैली
$stmt->bind_result($forename);
प्रक्रियात्मक शैली
mysqli_stmt_bind_result($stmt, $forename);
bind_result
का उपयोग करने में समस्या यह है कि इसे उपयोग किए जाने वाले कॉलम को निर्दिष्ट करने के लिए कथन की आवश्यकता होती है। इसका मतलब यह है कि उपर्युक्त के लिए क्वेरी को काम करने के लिए ऐसा होना चाहिए जैसा कि SELECT forename FROM users
। अधिक कॉलम शामिल करने के लिए बस उन्हें bind_result
फ़ंक्शन के मापदंडों के रूप में जोड़ें (और सुनिश्चित करें कि आप उन्हें SQL क्वेरी में जोड़ते हैं)।
दोनों ही मामलों में, हम forename
कॉलम को $forename
वैरिएबल पर असाइन कर रहे हैं। ये फ़ंक्शंस उतने ही तर्क देते हैं जितने कॉलम आप असाइन करना चाहते हैं। असाइनमेंट केवल एक बार किया जाता है, क्योंकि फ़ंक्शन संदर्भ से बांधता है।
फिर हम निम्न प्रकार से लूप कर सकते हैं:
वस्तु-उन्मुख शैली
while ($stmt->fetch())
echo "$forename<br />";
प्रक्रियात्मक शैली
while (mysqli_stmt_fetch($stmt))
echo "$forename<br />";
इसका दोष यह है कि आपको एक ही बार में बहुत सारे वैरिएबल असाइन करने होंगे। इससे बड़े प्रश्नों पर नज़र रखना मुश्किल हो जाता है। यदि आपके पास MySQL मूल निवासी चालक ( mysqlnd
) स्थापित किया है, तुम सब करने की जरूरत है इस्तेमाल होता है get_result ।
वस्तु-उन्मुख शैली
$result = $stmt->get_result();
प्रक्रियात्मक शैली
$result = mysqli_stmt_get_result($stmt);
यह काम करना बहुत आसान है क्योंकि अब हमें mysqli_result ऑब्जेक्ट मिल रहा है। यह वही वस्तु है जो mysqli_query देता है । इसका मतलब है कि आप अपने डेटा को प्राप्त करने के लिए एक नियमित परिणाम लूप का उपयोग कर सकते हैं।
अगर मैं mysqlnd
स्थापित नहीं कर सकता तो क्या होगा?
अगर ऐसा है तो @Sophivorus ने आपको इस अद्भुत उत्तर के साथ कवर किया है।
यह फ़ंक्शन सर्वर पर इंस्टॉल किए बिना get_result
का कार्य कर सकता है। यह केवल परिणामों से गुजरता है और एक साहचर्य सरणी बनाता है
function get_result(\mysqli_stmt $statement)
{
$result = array();
$statement->store_result();
for ($i = 0; $i < $statement->num_rows; $i++)
{
$metadata = $statement->result_metadata();
$params = array();
while ($field = $metadata->fetch_field())
{
$params[] = &$result[$i][$field->name];
}
call_user_func_array(array($statement, 'bind_result'), $params);
$statement->fetch();
}
return $result;
}
हम इस तरह से परिणाम प्राप्त करने के लिए फ़ंक्शन का उपयोग कर सकते हैं, जैसे कि हम mysqli_fetch_assoc()
का उपयोग कर रहे थे
<?php
$query = $mysqli->prepare("SELECT * FROM users WHERE forename LIKE ?");
$condition = "J%";
$query->bind_param("s", $condition);
$query->execute();
$result = get_result($query);
while ($row = array_shift($result)) {
echo $row["id"] . ' - ' . $row["forename"] . ' ' . $row["surname"] . '<br>';
}
इसका वही आउटपुट होगा जैसे कि आप mysqlnd
ड्राइवर का उपयोग कर रहे थे, सिवाय इसके कि इसे इंस्टॉल न करना पड़े। यह बहुत उपयोगी है यदि आप अपने सिस्टम पर उक्त ड्राइवर को स्थापित करने में असमर्थ हैं। बस इस समाधान को लागू करें।