MySQL में PHP एरे को सेव करें?


88

किसी एकल mysql फ़ील्ड में डेटा की एक सरणी को सहेजने का एक अच्छा तरीका क्या है?

एक बार जब मैंने mysql तालिका में उस सरणी के लिए क्वेरी की, तो इसे सरणी रूप में वापस लाने का एक अच्छा तरीका क्या है?

क्या सीरियलाइज़ करना और उत्तर को अनसुना करना है?

जवाबों:


87

किसी एकल फ़ील्ड में किसी सरणी को संग्रहीत करने का कोई अच्छा तरीका नहीं है ।

आपको अपने संबंधपरक डेटा की जांच करने और अपने स्कीमा में उचित बदलाव करने की आवश्यकता है। इस दृष्टिकोण के संदर्भ के लिए नीचे उदाहरण देखें।

आप तो चाहिए एक भी क्षेत्र में सरणी बचाने के तो serialize()और unserialize()कार्यों चाल करेंगे। लेकिन आप वास्तविक सामग्री पर प्रश्न नहीं कर सकते।

क्रमांकन समारोह के विकल्प के रूप में भी है json_encode()और json_decode()

निम्नलिखित सरणी पर विचार करें

$a = array(
    1 => array(
        'a' => 1,
        'b' => 2,
        'c' => 3
    ),
    2 => array(
        'a' => 1,
        'b' => 2,
        'c' => 3
    ),
);

डेटाबेस में इसे बचाने के लिए आपको इस तरह की एक तालिका बनाने की आवश्यकता है

$c = mysql_connect($server, $username, $password);
mysql_select_db('test');
$r = mysql_query(
    'DROP TABLE IF EXISTS test');
$r = mysql_query(
    'CREATE TABLE test (
      id INTEGER UNSIGNED NOT NULL,
      a INTEGER UNSIGNED NOT NULL,
      b INTEGER UNSIGNED NOT NULL,
      c INTEGER UNSIGNED NOT NULL,
      PRIMARY KEY (id)
    )');

अभिलेखों के साथ काम करने के लिए आप इन जैसे प्रश्नों को कर सकते हैं (और हाँ यह एक उदाहरण है, सावधान!)

function getTest() {
    $ret = array();
    $c = connect();
    $query = 'SELECT * FROM test';
    $r = mysql_query($query,$c);
    while ($o = mysql_fetch_array($r,MYSQL_ASSOC)) {
        $ret[array_shift($o)] = $o;
    }
    mysql_close($c);
    return $ret;
}
function putTest($t) {
    $c = connect();
    foreach ($t as $k => $v) {
        $query = "INSERT INTO test (id,".
                implode(',',array_keys($v)).
                ") VALUES ($k,".
                implode(',',$v).
            ")";
        $r = mysql_query($query,$c);
    }
    mysql_close($c);
}

putTest($a);
$b = getTest();

connect()समारोह एक mysql कनेक्शन संसाधन रिटर्न

function connect() {
    $c = mysql_connect($server, $username, $password);
    mysql_select_db('test');
    return $c;
}

26

आम तौर पर, हाँ, सीरियलाइज़ और अनसेरिज़ल जाने का रास्ता है।

यदि आपका डेटा कुछ सरल है, हालांकि, अल्पविराम-सीमांकित स्ट्रिंग के रूप में सहेजना संभवतः संग्रहण स्थान के लिए बेहतर होगा। यदि आप जानते हैं कि आपकी सरणी केवल संख्याओं की एक सूची होगी, उदाहरण के लिए, तो आपको इंप्कोड / विस्फोट का उपयोग करना चाहिए। यह बीच का अंतर है 1,2,3और a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}

यदि नहीं, तो सभी मामलों के लिए काम को क्रमबद्ध और गैर-व्यवस्थित करें।


23
जब से आप यहां हैं, पाठक, मैं सिर्फ यह घोषणा करने के लिए समय लेने जा रहा हूं कि मैंने अनुभव के वर्षों के माध्यम से खोजा है, यह वास्तव में जाने का तरीका नहीं है। स्वीकृत उत्तर अधिक मजबूत दृष्टिकोण है।
माचू

4
साइन आप यहां हैं, पाठक मैं आपके साथ साझा करने जा रहा हूं कि यह बस आपकी आवश्यकताओं पर निर्भर करता है। यदि आपको अपने सरणी मानों से क्वेरी करने की कोई आवश्यकता नहीं है और कुछ ऐसा चाहिए जो बहुत तेज़ हो तो आप अपने डेटा को सुरक्षित रूप से इस तरह से एक ही फ़ील्ड में संग्रहीत कर सकते हैं (जो कि प्रश्न स्पष्ट रूप से कहा गया है), उस पर एक प्राथमिक कुंजी को थप्पड़ मारें और आप चले जाएं । यदि आपको आश्चर्य है कि आवेदन क्या है: डेटा को एक पंक्ति में धकेलना जो हर 5 मिनट में क्रोनहेड हो जाता है। एक अन्य क्रोन सरणियों का निर्माण करता है जिसमें अधिक समय लगता है। यह पंक्ति गणना किए गए डेटा को प्राप्त करती है और इसे 3rd पार्टी एपीआई में भेजती है। इसे करने का कोई बेहतर तरीका नहीं है।
Iculous

1
@ मुझे पता है कि आप भ्रमित हैं, क्या आप अपने निजी आवेदन या उस आवेदन के बारे में बात कर रहे हैं जिसके कारण प्रश्न पूछा गया था?
पीटर लिंडक्विस्ट

1
जब तक कि मेरे कथन के उपसर्ग के लिए अप्रासंगिक है "यदि आपको आश्चर्य है कि आवेदन क्या है" तो स्पष्टता प्रदान करनी चाहिए।
Iculous

10

बस क्रमबद्ध PHP फ़ंक्शन का उपयोग करें:

<?php
$myArray = array('1', '2');
$seralizedArray = serialize($myArray);
?>

हालाँकि, यदि आप सरल सरणियों का उपयोग कर रहे हैं, जैसे कि आप उपयोग कर सकते हैं और साथ ही विस्फोट भी कर सकते हैं। नए के बजाय एक रिक्त सरणी का उपयोग करें।


9

किसी DB में स्टोरेज के लिए सीरियलाइज़ / अनसेरीलाइज़ करें

Http://php.net/manual/en/function.serialize.php पर जाएं

PHP मैनुअल से:

पृष्ठ पर "वापसी" के तहत देखें

एक स्ट्रिंग देता है जिसमें बाइट-स्ट्रीम मूल्य का प्रतिनिधित्व होता है जिसे कहीं भी संग्रहीत किया जा सकता है।

ध्यान दें कि यह एक द्विआधारी स्ट्रिंग है जिसमें अशक्त बाइट्स शामिल हो सकते हैं, और इस तरह संग्रहीत और संभाला जाना चाहिए। उदाहरण के लिए, सीरियलाइज़ () आउटपुट को आम तौर पर एक डेटाबेस में एक BLAR फ़ील्ड में संग्रहीत किया जाना चाहिए, बजाय एक CHAR या पाठ फ़ील्ड के।

नोट: यदि आप html को एक ब्लॉब में स्टोर करना चाहते हैं, तो सुनिश्चित करें कि यह base64 को एन्कोड करें या यह क्रमबद्ध फ़ंक्शन को तोड़ सकता है।

उदाहरण एन्कोडिंग:

$YourSerializedData = base64_encode(serialize($theHTML));

$YourSerializedData अब बूँद में संग्रहित होने के लिए तैयार है।

बूँद से डेटा प्राप्त करने के बाद आपको base64_decode करने की आवश्यकता होती है तब उदाहरण डिकोडिंग को अनसुना करें:

$theHTML = unserialize(base64_decode($YourSerializedData));

8

सबसे अच्छा तरीका है, जो मैंने खुद से पाया है कि सरणी को विभाजक वर्णों के साथ डेटा स्ट्रिंग के रूप में सहेजा गया है

$array = array("value1", "value2", "value3", "...", "valuen");
$array_data = implode("array_separator", $array);

$query = "INSERT INTO my_tbl_name (id, array_data) VALUES(NULL,'" . $array_data . "');";

फिर आप साधारण क्वेरी के साथ अपने सरणी में संग्रहीत डेटा खोज सकते हैं

$query = "SELECT * FROM my_tbl_name WHERE array_data LIKE '%value3%'";

"array_data" स्ट्रिंग को सरणी में बदलने के लिए विस्फोट () फ़ंक्शन का उपयोग करें

$array = explode("array_separator", $array_data);

ध्यान दें कि यह बहुआयामी सरणियों के साथ काम नहीं कर रहा है और सुनिश्चित करें कि आपका "array_separator" विशिष्ट है और सरणी मानों में मौजूद नहीं था।

सावधान रहे !!! यदि आप सिर्फ एक फॉर्म डेटा लेंगे और डेटाबेस में डालेंगे, तो आप ट्रैप में रहेंगे, फॉर्म का डेटा एसक्यूएल-सुरक्षित नहीं है! आपको mysql_real_escape_string या यदि आप MySQLi mysqli :: real_escape_string का उपयोग करते हैं या यदि मान पूर्णांक या बूलियन कास्ट (int) (उन पर बूलियन) का उपयोग करते हैं

$number = (int)$_POST['number'];
$checked = (boolean) $_POST['checked'];

$name = mysql_real_escape_string($db_pt, $_POST['name']);
$email = mysqli_obj->real_escape_string($_POST['email']);

मेरे मामले में, मुझे लगता है कि यह मेरे लिए सबसे अच्छा विकल्प है।
इम्तियाज

6

सीरियलाइज़ और अनसेरिज़ल उसके लिए बहुत आम हैं। आप JSON_encode और json_decode के माध्यम से JSON का उपयोग कम PHP-विशिष्ट प्रारूप के लिए भी कर सकते हैं।


5

जैसा कि पहले उल्लेख किया गया है - यदि आपको सरणी के भीतर डेटा की खोज करने की आवश्यकता नहीं है, तो आप क्रमबद्ध उपयोग कर सकते हैं - लेकिन यह "केवल php" है। इसलिए मैं json_decode / json_encode का उपयोग करने की सलाह दूंगा - न केवल प्रदर्शन के लिए, बल्कि पठनीयता और पोर्टेबिलिटी के लिए भी (जावास्क्रिप्ट जैसे अन्य भाषाएं json_encoded डेटा को संभाल सकती हैं)।


3

उह, मुझे नहीं पता कि हर कोई सरणी को क्रमबद्ध करने का सुझाव क्यों देता है।

मैं कहता हूं, सबसे अच्छा तरीका यह है कि आप इसे अपने डेटाबेस स्कीमा में फिट करें। मुझे आपके सरणी में डेटा के वास्तविक अर्थ अर्थ के बारे में कोई पता नहीं है (और आपने कोई सुराग नहीं दिया है), लेकिन आम तौर पर इस तरह के अनुक्रमों को संग्रहीत करने के दो तरीके हैं

create table mydata (
  id int not null auto_increment primary key,
  field1 int not null,
  field2 int not null,
  ...
  fieldN int not null
)

इस तरह से आप अपनी सरणी को एक पंक्ति में जमा कर रहे हैं।

create table mydata (
    id int not null auto_increment primary key,
    ...
)

create table myotherdata (
    id int not null auto_increment primary key,
    mydata_id int not null,
    sequence int not null,
    data int not null
)

पहली विधि का नुकसान, जाहिर है, कि अगर आपके पास अपने सरणी में कई आइटम हैं, तो उस तालिका के साथ काम करना सबसे सुरुचिपूर्ण चीज नहीं होगी। यह अव्यवहारिक (संभव है, लेकिन साथ ही काफी असाध्य है - बस कॉलम को अशक्त बनाने के लिए) चर लंबाई के दृश्यों के साथ काम करने के लिए।

दूसरी विधि के लिए, आपके पास किसी भी लम्बाई के अनुक्रम हो सकते हैं, लेकिन केवल एक प्रकार के। आप निश्चित रूप से, उस एक प्रकार की चरखी या कुछ बना सकते हैं और अपने सरणी की वस्तुओं को क्रमबद्ध कर सकते हैं। नहीं करने के लिए सबसे अच्छी बात है, लेकिन निश्चित रूप से बेहतर है, पूरे सरणी, सही serializing की तुलना में?

किसी भी तरह से, इस तरीके में से किसी को भी अनुक्रम के एक मनमाने तत्व तक पहुंचने में सक्षम होने का स्पष्ट लाभ मिलता है और आपको धारावाहिक सरणियों और इस तरह की बदसूरत चीजों के बारे में चिंता करने की आवश्यकता नहीं है।

वापस पाने के लिए के रूप में। ठीक है, एक पंक्ति के साथ पंक्तियों की उपयुक्त पंक्ति / अनुक्रम प्राप्त करें और, ठीक है, एक लूप का उपयोग करें .. सही?


कभी-कभी एक सरणी वास्तव में उपयुक्त है। यदि आप इसे केवल पहली वस्तु की विशेषता के रूप में एक्सेस करने जा रहे हैं, तो यह समझ में आता है।
माचिस

1
मुझे सबसे गंभीर शब्दों में असहमत होना पड़ता है - यह यादृच्छिक, स्टोर करने के लिए मेरे लिए अनुचित लगता है, असंरचित (php "arrays" वास्तव में सरणियां नहीं हैं, ठीक है?), रिलेशनल डेटाबेस में डेटा के अनप्लग ब्लब्स । वैसे भी आप विभाजक के लिए क्या उपयोग करने जा रहे हैं, अगर आपके सरणी में कोई तार हो सकता है? यह सिर्फ कई अलग-अलग तरीकों से परेशानी पूछ रहा है। 99,9% मामलों में, एक और प्राकृतिक तरीका है। मैं यहां एक जंगली अनुमान लगाता हूं और सुझाव देता हूं, कि प्रश्नकर्ता का मामला शेष 0.1% में नहीं आता है।
संकोची

2
दरअसल, कभी-कभी किसी डीबी में एक क्षेत्र में एक सरणी को स्टोर करना बहुत उपयुक्त होता है। उदाहरण मेटाडेटा एक वैश्विक 'चर' तालिका की तरह होगा जिसमें एक सिस्टम प्लगइन्स और मॉड्यूल अपनी मिश्रित सेटिंग्स को स्टोर कर सकते हैं। एक तालिका जो मनमाने ढंग से 'सेशन' डेटा स्टोर करती है, को एक ऐसे क्षेत्र का उपयोग करके सर्वोत्तम रूप से लागू किया जा सकता है, जिसमें कुंजियों / मूल्यों की एक सहयोगी सरणी होती है। क्रमबद्ध और अचिह्नित करें (जो सही उत्तर है) विभाजकों का ध्यान रखें। कई सफल और लोकप्रिय ओपन सोर्स प्रोजेक्ट्स की जाँच करें, जैसे कि वर्डप्रेस या ड्रुपल - और आप देखेंगे कि सरणियों को कभी-कभी डीबी में इस तरह संग्रहीत किया जाता है
स्कॉट एवरडेन

@ स्वॉट एवरनडेन: मुझे लगता है कि आप बिल्कुल सही हैं। php मेरी "मुख्य" भाषा नहीं है, इसलिए मैं डेटाबेस डिजाइन के नजरिए से समाधान को जज कर रहा था। यदि आप जो वर्णन करते हैं वह वास्तव में ऐसी चीजों को करने का सामान्य तरीका है (php में), तो ऐसा ही हो। हालांकि मुझे यह पसंद नहीं है :)
संकोची

5
यह एक DB में एक क्षेत्र में एक सरणी स्टोर करने के लिए उपयुक्त नहीं है। यह चौथे सामान्य रूप का उल्लंघन है, तीसरा सामान्य रूप या दूसरा सामान्य रूप भी नहीं है: यह FIRST NORMALMM का उल्लंघन है। यदि आप पहले सामान्य रूप में भी पालन नहीं कर सकते हैं तो आपके आवेदन में कुछ गंभीर गड़बड़ है। जो Drupal और Wordpress के लिए जाता है; अगर वे ऐसा करते हैं तो निश्चित रूप से ऐसा नहीं है क्योंकि उनके ऐप्स के पहलू अच्छी तरह से डिज़ाइन किए गए हैं। मेरे पास अपनी पिछली नौकरी में यह तर्क था, और क्योंकि XCart इस बकवास कर रहा था, इसने कुछ ऐसा किया जो संभव होना चाहिए था, इसके बजाय बेहद मुश्किल।
डेक्सिजन डेस

2

आप एक एरर के रूप में अपने एरे को सेव कर सकते हैं।
json डेटा प्रकार के लिए प्रलेखन है: https://dev.mysql.com/doc/refman/5.7/en/json.html
मुझे लगता है कि यह सबसे अच्छा समाधान है, और पागल कार्यों से बचकर आपके कोड को अधिक पठनीय बनाए रखने में आपकी मदद करेगा। ।
मुझे उम्मीद है कि यह आपके लिए उपयोगी है।


0

हाँ, सीरियलाइज़ / अनसेरिज़ल वह है जो मैंने कई ओपन सोर्स प्रोजेक्ट्स में देखा है।


0

मैं एक ऐसे चरित्र के साथ निहित / विस्फोट का उपयोग करने का सुझाव दूंगा जिसे आप जानते हैं कि किसी भी व्यक्तिगत सरणी आइटम में निहित नहीं होगा। फिर इसे SQL में एक स्ट्रिंग के रूप में संग्रहीत करें।


3
यह प्रश्न 3 साल पहले पूछा गया था और इसका एक स्वीकृत उत्तर है। आपको नए प्रश्नों या प्रश्नों के उत्तर देने में अधिक मददगार हो सकता है।
एमडीरोल

0

इनकोड फ़ंक्शन की जाँच करें, क्योंकि मान किसी सरणी में हैं, आप सरणी के मानों को एक mysql क्वेरी में डालना चाहते हैं जो मानों को तालिका में सम्मिलित करता है।

$query = "INSERT INto hardware (specifications) VALUES (".implode(",",$specifications).")";

यदि सरणी में मान पाठ मान हैं, तो आपको उद्धरण जोड़ने की आवश्यकता होगी

$query = "INSERT INto hardware (specifications) VALUES ("'.implode("','",$specifications)."')";

mysql_query($query);

इसके अलावा, यदि आप डुप्लिकेट मान नहीं चाहते हैं, तो "INto" को "IGNORE" पर स्विच करें और केवल अनन्य मानों को तालिका में डाला जाएगा।


यदि आपके पास एक प्राथमिक कुंजी है, तो आपको वैसे भी INSERT INTO के साथ कोई डुप्लिकेट नहीं मिलता है। यदि आपके पास कोई प्राथमिक कुंजी या सूचकांक नहीं है, तो IGNORE को कोई फर्क नहीं पड़ता है।
पीटर लिंडक्विस्ट

0

आप mysql के लिए क्रमबद्ध ऑब्जेक्ट (सरणी) सम्मिलित कर सकते हैं, उदाहरण serialize($object)और आप ऑब्जेक्ट उदाहरण को अनजाने कर सकते हैंunserialize($object)


-5

इसे डेटाबेस में सहेजने के बजाय, इसे किसी फ़ाइल में सहेजें और फिर बाद में कॉल करें।

कई php ऐप्स क्या करते हैं (जैसे कि गन्ने की) बस var_export का उपयोग करके फ़ाइल के एरे के सभी डेटा को इको करना है। अपने कॉन्फ़िगरेशन डेटा को बचाने के लिए मैं इसका उपयोग करता हूं:

private function saveConfig() {
    file_put_contents($this->_data['pathtocompileddata'],'<?php' . PHP_EOL . '$acs_confdata = ' . var_export($this->_data,true) . ';');        
}

मुझे लगता है कि यह आपके डेटा को बचाने का एक बेहतर तरीका है!


यह एक और तरीका है, जरूरी नहीं कि बेहतर हो।
पीटर लिंडक्विस्ट

वास्तव में। मुझे लगता है कि फ़ाइल को एक्सेस करना डेटाबेस डेटा को क्वेरी करने की तुलना में सरणी डेटा को पुनः प्राप्त करने की तुलना में बहुत आसान है और फिर सरणी को आरंभीकृत करता है। इस तरह से आप बस फ़ाइल को शामिल करते हैं और यह हो चुका है।
एंटोनियोसीएस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.