पीएचपी सीएसवी पार्सर. सीएसवी से आयात करें या सीएसवी में निर्यात करें। PHP सॉर्टिंग CSV फ़ाइलों का उपयोग करके CSV फ़ाइल को कैसे पार्स करें

💖क्या आपको यह पसंद है?लिंक को अपने दोस्तों के साथ साझा करें

काफी ऊंचा, ग्राहक ऐसा करने के लिए कहते हैं माल का आयातउनकी मूल्य सूची से. उन्हें न केवल साइट पर नए उत्पाद जोड़ने में सक्षम होना चाहिए, बल्कि मौजूदा उत्पादों के स्टॉक में कीमतों और मात्रा को भी अपडेट करना होगा।

PHP, जैसा कि आप जानते हैं, नहीं कर सकता एक्सेल फाइलों के साथ काम करेंमानक साधनों का उपयोग करना। बेशक, कई अलग-अलग वर्ग हैं जो एक्सेल में जानकारी पढ़ और लिख सकते हैं, लेकिन उनके साथ काफी समस्याएं हैं (हम इसके बारे में भविष्य के लेखों में लिखेंगे)।

बहुत आसान और अधिक सुविधाजनक सीएसवी फाइलों के साथ काम करें.

उदाहरण के लिए, चलिए एक छोटा सा प्रोग्राम बनाते हैं। यह OX2.ru कर्मचारियों की सीएसवी फ़ाइल को संसाधित करेगा।

आइए एक्सेल में एक नई तालिका बनाएं जिसमें निम्नलिखित फ़ील्ड हों:

आइए तालिका को फ़ील्ड विभाजक ";" के साथ एक सीएसवी फ़ाइल के रूप में सहेजें।

हमें इस तरह की फ़ाइल के साथ समाप्त करना चाहिए:

"इवानोव ए.ए."; ";"प्रबंधक OX2.ru";89031233333

विस्तृत विवरण के साथ स्रोत कोड नीचे दिया गया है।

कोड OOP में लिखा गया था कक्षाओं का उपयोग करना, और थोड़े से संशोधन के साथ विभिन्न अनुप्रयोगों में पुन: उपयोग किया जा सकता है। यदि आप कक्षाओं में प्रोग्रामिंग के आदी नहीं हैं, लेकिन फ़ंक्शंस या कुछ और का उपयोग करते हैं, तो हम दृढ़ता से पुनः सीखने की सलाह देते हैं))

कोड अपवाद पीढ़ी (एक्सेप्शन) का भी उपयोग करता है, उनके बारे में हमारे अगले लेखों में पढ़ें।

_csv_फ़ाइल = $csv_फ़ाइल; // फ़ाइल के पथ को एक वेरिएबल में लिखें) अन्यथा ( // यदि फ़ाइल नहीं मिली है, तो एक अपवाद फेंकें नया अपवाद फेंकें ("फ़ाइल "$csv_file" नहीं मिला"); ) ) सार्वजनिक फ़ंक्शन सेटसीएसवी (ऐरे) $csv) ( //प्री-रिकॉर्डिंग के लिए csv खोलें, //यदि आप w निर्दिष्ट करते हैं, तो csv में जो जानकारी थी वह ओवरराइट हो जाएगी $handle = fopen($this->_csv_file, "a"); foreach ($ सीएसवी $मूल्य के रूप में) ( //हम सरणी के माध्यम से जाते हैं // हम लिखते हैं, तीसरा पैरामीटर फ़ील्ड विभाजक fputcsv($हैंडल, विस्फोट(";", $मूल्य), ";"); fclose($ हैंडल); //बंद करें ) /** * सीएसवी-फ़ाइल से पढ़ने की विधि। सीएसवी से डेटा के साथ एक सरणी लौटाता है * @return array; */ सार्वजनिक फ़ंक्शन getCSV() ($हैंडल = fopen($this->_csv_file, "r"); // पढ़ने के लिए csv खोलें $array_line_full = array(); //एरे csv से डेटा संग्रहीत करेगा / /हम संपूर्ण सीएसवी फ़ाइल को देखते हैं, और पंक्ति दर पंक्ति पढ़ते हैं। तीसरा पैरामीटर फ़ील्ड विभाजक जबकि (($line = fgetcsv($handle, 0, ";")) !== FALSE) ( $array_line_full = $line; //सरणी में लाइनें लिखें) fclose($हैंडल); //फ़ाइल बंद करें $array_line_full; //पढ़ा हुआ डेटा लौटाएं) ) प्रयास करें ($csv = नया CSV("ox2.csv"); //हमारा खोलें सीएसवी /** * सीएसवी से पढ़ना (और एक सुंदर रूप में स्क्रीन पर आउटपुट) */ इको "

रिकॉर्डिंग से पहले सीएसवी:

"; $get_csv = $csv->getCSV(); foreach ($get_csv as $value) ( ​​//echo "Name: " . $value . " पंक्तियों के माध्यम से पुनरावृति करें।
"; प्रतिध्वनि "स्थिति:"। $मूल्य।"
"; प्रतिध्वनि "फ़ोन: " . $मूल्य ।"
"; प्रतिध्वनि "------------
"; ) /** * CSV में नई जानकारी लिखें */ $arr = array("Antonov B.A.;Admin OX2.ru;89031233333", "Kolobkov V.B.;Boss OX2.ru;89162233333"); $csv->setCSV( $arr); ) पकड़ो (अपवाद $e) ( //यदि सीएसवी फ़ाइल मौजूद नहीं है, तो एक संदेश प्रिंट करें "त्रुटि:"। $e->getMessage(); ) ?>

कक्षा मुख्य कार्य CSV फ़ाइलों के साथ करती है। सीएसवीइसकी निम्नलिखित विधियाँ हैं:

सेटसीएसवी(ऐरे $सीएसवी)- एक सीएसवी फ़ाइल में डेटा लिखता है। डेटा को एक सरणी में पारित किया जाना चाहिए। विधि एक सीएसवी फ़ाइल जोड़ सकती है और एक नई फ़ाइल बना सकती है (विवरण पढ़ें)।

तरीका सीएसवी प्राप्त करेंएक सीएसवी फ़ाइल से डेटा पढ़ता है, और इस तरह एक द्वि-आयामी सरणी लौटाता है:

ऐरे (=> ऐरे (=> इवानोव ए.ए. => कंपनी के प्रोग्रामर OX2.ru => 89255552332) => ऐरे (=> सिदोरोव ए.ई. => डिजाइन कंपनी OX2.ru => 89161231212) => ऐरे (=> पिरोजकोव ए.बी. => कला निर्देशक OX2.ru => 84951232121) => सारणी ( => कुलिबिन बी.ए. => प्रबंधक OX2.ru => 89031233333))

उदाहरण काफी सरल है, इस तथ्य के बावजूद कि इसमें बहुत सारे कोड हैं।

सीएसवी फ़ाइलों से डेटा आयात करनायह न केवल ऑनलाइन स्टोर में उत्पादों को अपडेट करने के लिए उपयोगी होगा, बल्कि नियमित वेबसाइट पर किसी भी जानकारी को लोड/अपडेट करने के लिए भी उपयोगी होगा।

उदाहरण के लिए, हम वेबसाइट विकसित कीप्रबंधन कंपनी, और उन्हें मासिक आधार पर गर्म और ठंडे पानी के मीटरों पर जानकारी प्रकाशित करने की आवश्यकता थी। सारा डेटा एक्सेल फाइलों में संग्रहीत है। और यहाँ सीएसवी प्रारूप बिल्कुल फिट बैठता है!

साथ ही, वेबसाइट बनाने की लागत अपरिवर्तित रहेगी, और वेबसाइट की कार्यक्षमता और स्वचालन प्रतिस्पर्धियों की तुलना में एक स्तर अधिक होगा।

समारोह Fgetcsvकिसी फ़ाइल से एक पंक्ति पढ़ता है और डेटा को पार्स करता है सीएसवी.
सरणी fgetcsv(संसाधन $हैंडल [, int $length = 0 [, स्ट्रिंग $delimiter = "," [, स्ट्रिंग $enclosure = """ [, स्ट्रिंग $escape = "\" ]]]]) फ़ंक्शन Fgetcsv Fgets फ़ंक्शन के समान, इस अंतर के साथ कि यह प्रारूप में प्रविष्टियों के लिए एक स्ट्रिंग को पार्स करता है सीएसवीऔर पाए गए फ़ील्ड को एक सरणी के रूप में लौटाता है।

पैरामीटर सँभालना Fopen का उपयोग करके सफलतापूर्वक खोली गई फ़ाइल के लिए एक वैध फ़ाइल सूचक है, पोपेनया Fsockopen.

पैरामीटर लंबाईसीएसवी फ़ाइल में पाई जाने वाली सबसे लंबी पंक्ति (वर्णों में) से अधिक होनी चाहिए (पंक्ति के अंत के अंतिम वर्ण सहित)। अन्यथा, डोरी लंबाई के टुकड़ों में विभाजित हो जाएगी लंबाईवर्ण जब तक कि ब्रेक मार्जिन सीमांकक के अंदर न हो ( दीवार).

वैकल्पिक पैरामीटर सीमान्तकफ़ील्ड विभाजक (केवल एक वर्ण) सेट करता है।

वैकल्पिक पैरामीटर दीवारफ़ील्ड सीमांकक वर्ण (केवल एक वर्ण) सेट करता है।

वैकल्पिक पैरामीटर पलायनएस्केप कैरेक्टर (केवल एक कैरेक्टर) सेट करता है।

समारोह Fgetcsvपढ़े गए फ़ील्ड के साथ एक अनुक्रमित सरणी लौटाता है, या व्यर्थ, यदि कोई अमान्य पैरामीटर पारित किया गया है सँभालना, या असत्यअन्य त्रुटियों के लिए, जिसमें फ़ाइल के अंत तक पहुँचने का समय भी शामिल है।

एक खाली CSV फ़ाइल स्ट्रिंग को एक एकल तत्व वाले सरणी के रूप में लौटाया जाएगा व्यर्थ, इस मामले में कोई त्रुटि नहीं होगी.

बहुत सारी कंपनियाँ, संगठन आदि हैं। अपने काम में वे माइक्रोसॉफ्ट ऑफिस एक्सटेंशन - EXEL का उपयोग करते हैं। कुछ में, उत्पाद Excel में सहेजे जाते हैं, अन्य में, उत्पादों, उपयोगकर्ताओं, कीमतों या यहां तक ​​कि केवल फ़ोन नंबरों के बारे में जानकारी। उदाहरण के लिए, इस डेटा को किसी अन्य डेटाबेस में स्थानांतरित करने की आवश्यकता हो सकती है वेब.

सबसे पहले, आपको अपनी फ़ाइल खोलनी होगी एक्सेलविस्तार के साथ .XLS. फिर इसे इस रूप में सेव करें .सीएसवी. अब इसका उपयोग वेब एप्लिकेशन में किया जा सकता है। उदाहरण के लिए, वही फ़ाइल आपके पसंदीदा संपादक के साथ खोली जा सकती है कुल कमांडर, और आप इसकी सामग्री देखेंगे। अगर आप भी खोलते हैं एक्सएलएसफ़ाइल, तभी बहुत सारे अस्पष्ट और समझ से परे कोड दिखाई देंगे।

में परिवर्तित भी किया जा सकता है सीएसवीफ़ाइलें और तालिकाएँ माइक्रोसॉफ्ट ऑफिसऔर ओपनऑफिस राइटर.

के लिए ओपनऑफिस राइटरयह अग्रानुसार होगा:

1. एक तालिका बनाएं.

2. मेनू से "टेबल" -> "कन्वर्ट" -> "टेबल टू टेक्स्ट" चुनें।

3. टेक्स्ट विभाजक निर्दिष्ट करें, उदाहरण के लिए "@" और ओके बटन पर क्लिक करके कार्रवाई की पुष्टि करें।

5. आखिरी काम है नाम बदलना test.txtवी test.csv.

अब हमने एक फ़ाइल बनाई है जो PHP स्क्रिप्ट में आयात के लिए उपलब्ध है:
// पढ़ने के लिए फ़ाइल खोलें
$fh = fopen('test.csv', 'r');
// किसी फ़ाइल से एक पंक्ति पढ़ें और CSV डेटा को पार्स करें
$जानकारी = fgetcsv($fh, 1000, "@");
// परिणामों की एक श्रृंखला आउटपुट करें
print_r($जानकारी);
// फ़ाइल बंद करें
fclose($fh); निष्पादन परिणाम तालिका की पहली पंक्ति होगी.

पूरी फ़ाइल पढ़ने के लिए सीएसवी, आप While लूप का उपयोग कर सकते हैं:
// पढ़ने के लिए फ़ाइल खोलें
$fh = fopen('test.csv', 'r');

// परिणामों की एक श्रृंखला आउटपुट करें
print_r($जानकारी);
}
// फ़ाइल बंद करें
fclose($fh); प्रत्येक व्यक्तिगत तत्व तक पहुँचने के लिए, आप सूची भाषा निर्माण का उपयोग कर सकते हैं:
// पढ़ने के लिए फ़ाइल खोलें
$fh = fopen('test.csv', 'r');
जबकि (($जानकारी = fgetcsv($fh, 1000, "@")) !== गलत) (
// सरणी मानों को वेरिएबल्स में सहेजें
सूची($var1, $var2) = $जानकारी;
}
// फ़ाइल बंद करें
fclose($fh); समारोह के लिए धन्यवाद Fgetcsvआप तालिकाओं से बड़ी मात्रा में डेटा संसाधित कर सकते हैं।

साथ PHP में बड़ी CSV फ़ाइलों को संसाधित करने में समस्याहाल ही में मेरा पहली बार इसका सामना हुआ। सामान्य तौर पर, मैं PHP में ज्यादा प्रोग्राम नहीं करता, केवल तभी जब इस भाषा में विशेष रूप से कुछ लिखने का कार्य आता है।

पिछले लेख में चर्चा की गई। मैंने वहां यह भी नोट किया कि बड़ी फ़ाइलों के साथ काम करने के लिए एक विशेष दृष्टिकोण की आवश्यकता होती है। बड़ी मात्रा में डेटा आयात करने के लिए मुख्य सीमा स्क्रिप्ट निष्पादन समय है, जो होस्टर द्वारा निर्धारित किया जाता है (आमतौर पर 30 सेकंड)।

मुझे संपूर्ण आयात प्रक्रिया को स्वचालित करने की आवश्यकता थी। तालिका में सम्मिलित करने से पहले, एससीवी फ़ाइल से प्राप्त फ़ील्ड मानों को विश्लेषण और अतिरिक्त प्रसंस्करण की आवश्यकता होती है।

जब मैंने बिगडम्प उपयोगिता के विवरण में ऑपरेशन के सिद्धांत के बारे में पढ़ा (मैंने पिछले लेख में इसका उल्लेख किया था):

स्क्रिप्ट विशाल डंप का केवल एक छोटा सा हिस्सा निष्पादित करती है और स्वयं को पुनरारंभ करती है। अगला सत्र वहीं से शुरू होता है जहां पिछला रोका गया था। (अनुवाद: स्क्रिप्ट फ़ाइल से SQL कमांड का केवल एक छोटा सा हिस्सा निष्पादित करती है और स्वयं को पुनरारंभ करती है। अगली बार आयात उस स्थान से शुरू होता है जहां स्क्रिप्ट ने अपना काम बाधित किया था।)

मुझे एहसास हुआ कि मुझे निश्चित रूप से इस समाधान को आज़माने की ज़रूरत है। ऐसी ही किसी चीज़ के लिए इंटरनेट पर खोजें सफलतापूर्वक समाप्त हो गईं।

$file_name = $_GET["पथ"];

$conn = mysql_connect('लोकलहोस्ट', 'उपयोगकर्ता नाम', 'पास')
या मरें ("कनेक्शन स्थापित नहीं हुआ!");
@mysql_select_db('db_name') या मरो('कनेक्शन स्थापित नहीं हुआ!');

यदि (($handle_f = fopen($file_name, "r")) !== FALSE)
{
// जाँचता है कि क्या किसी निश्चित स्थान से आयात जारी रखना आवश्यक है
// यदि हाँ, तो सूचक को इस स्थान पर ले जाया गया है
अगर(जारी($_GET["ftell"]))(
fseek($handle_f,$_GET["ftell"]);
}
$i=0;
अगर(जारी($_GET["x"]))(
$x=$_GET["x"];
) अन्य (
$x = 0;
}

// किसी फ़ाइल से पंक्ति-दर-पंक्ति पढ़ना और पार्स करना
जबकि (($data_f = fgetcsv($handle_f, 1000, ";"))!== FALSE) (
$insert_q = "temp1 (कोड, अनुबंध, मूल्य, राशि, dat_time, is_op) मान में डालें"।
" (\"".$data_f."\",\"".$data_f."\",\"".$data_f."\",\"".$data_f."\",\""। $data_f."\",\"0\"");
@mysql_query($insert_q);

यदि(!strstr($i/5000,""))(
प्रिंट करें "रिकॉर्ड आयात #: ".$x।"
";
फ्लश();
ob_flush();
}

यदि($i==20000)(
प्रिंट करें" ";
बाहर निकलना;
}
$x++;
$i++;

Fclose($handle_f);
) अन्य ($त्रुटि = 1; प्रतिध्वनि "फ़ाइल खोलने में विफल";)

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

मैंने इस स्क्रिप्ट का 60 एमबी फ़ाइल पर परीक्षण किया। इसने सही ढंग से काम किया और सब कुछ आयात किया। लेकिन मैं फिर भी परिचालन समय कम करना चाहूंगा।

उसी फ़ोरम थ्रेड में जहाँ से मैंने यह समाधान चुराया था, यह चर्चा की गई थी कि आप डेटाबेस में डेटा आयात करते समय एकल आवेषण को समूह आवेषण के साथ बदलकर स्क्रिप्ट के काम को तेज़ कर सकते हैं।

VALUES का उपयोग करके INSERT कमांड का उपयोग एक साथ कई पंक्तियाँ सम्मिलित करने के लिए किया जा सकता है। ऐसा करने के लिए, उन मानों के सेट को सूचीबद्ध करें जिन्हें आपको सम्मिलित करना है। उदाहरण:

tbl_name में डालें (ए,बी,सी) मान(1,2,3),(4,5,6),(7,8,9);


स्क्रिप्ट को ग्रुप इंसर्शन में अपग्रेड करने के बाद, मुझे वास्तव में एक परिणाम मिला जो प्रदर्शन के मामले में अधिक उपयुक्त था। लेकिन मुझे लगता है कि वहां रुकना जल्दबाजी होगी, मैं देखता रहूंगा।

पिछली पोस्ट पर मैक्सनाग की टिप्पणी को नज़रअंदाज़ करना और संभावना का उल्लेख न करना अनुचित होगा

मैं कुछ असमर्थित PHP क्लास का उपयोग किए बिना उसी चीज़ की तलाश में था। एक्सेल सीएसवी हमेशा उद्धरण विभाजकों का उपयोग नहीं करता है और "" का उपयोग करने वाले उद्धरणों से बचता है क्योंकि एल्गोरिदम संभवतः 80 या उसके जैसा कुछ लौटाता है। PHP.NET पर टिप्पणी अनुभाग में कई .csv पार्सर्स को देखने के बाद, मैंने ऐसे पार्सर्स देखे जो कॉलबैक या eval"d कोड का भी उपयोग करते थे और वे या तो आवश्यकतानुसार काम नहीं करते थे या बिल्कुल भी काम नहीं करते थे। इसलिए मैंने एक लिखा मेरे लिए उनकी दिनचर्या, और वे सबसे बुनियादी PHP कॉन्फ़िगरेशन में काम करते हैं, ऐरे कुंजियाँ या तो संख्यात्मक हो सकती हैं या शीर्षक पंक्ति में निर्दिष्ट फ़ील्ड के रूप में नामित की जा सकती हैं। आशा है कि इससे मदद मिलेगी।

फ़ंक्शन SW_ImplodeCSV(सरणी $rows, $headerrow=true, $mode='EXCEL', $fmt='2D_FIELDNAME_ARRAY'' // SW_ImplodeCSV - सीएसवी की स्ट्रिंग के रूप में 2D सरणी लौटाता है (MS Excel .CSV समर्थित) // लेखक: [ईमेल सुरक्षित]// जारी: 9/21/13 बीटा ($r=1; $row=array(); $fields=array(); $csv=''; $escapes=array('\r', '\n' , "\t", "\\", "\""); //दो बाइट एस्केप कोड $escapes2=array("\r", "\n", "\t", "\\", "\ ""); //वास्तविक कोड if($mode=='EXCEL")// एस्केप कोड = "" ( $delim='', $enclos='''; ) अन्यथा //मोड=मानक सभी फ़ील्ड संलग्न हैं ( $delim=''; $enclos=''''; $rowbr='\r\n'; ) $csv=''; $i=-1; $i2 =0; $imax=गिनती($पंक्तियाँ);< $imax) { // get field names if($i == -1) { $row=$rows; if($fmt=="2D_FIELDNAME_ARRAY") { $i2=0; $i2max=count($row); while(list($k, $v) = each($row)) { $fields[$i2]=$k; $i2++; } } else //if($fmt="2D_NUMBERED_ARRAY") { $i2=0; $i2max=(count($rows)); while($i2<$i2max) { $fields[$i2]=$i2; $i2++; } } if($headerrow==true) { $row=$fields; } else { $i=0; $row=$rows;} } else { $row=$rows[$i]; } $i2=0; $i2max=count($row); while($i2 < $i2max)// numeric loop (order really matters here) //while(list($k, $v) = each($row)) { if($i2 != 0) $csv=$csv.$delim; $v=$row[$fields[$i2]]; if($mode=="EXCEL") //EXCEL 2quote escapes { $newv = """.(str_replace(""", """", $v))."""; } else //STANDARD { $newv = """.(str_replace($escapes2, $escapes, $v))."""; } $csv=$csv.$newv; $i2++; } $csv=$csv."\r\n"; $i++; } return $csv; } function SW_ExplodeCSV($csv, $headerrow=true, $mode="EXCEL", $fmt="2D_FIELDNAME_ARRAY") { // SW_ExplodeCSV - parses CSV into 2D array(MS Excel .CSV supported) // AUTHOR: [ईमेल सुरक्षित]// जारी: 9/21/13 बीटा //SWMessage('SW_ExplodeCSV() - यहां कॉल किया गया -'); $पंक्तियाँ=सरणी(); $पंक्ति=सरणी(); $fields=array();// पंक्तियाँ = सारणियों की सारणी //एस्केप कोड = "\" $escapes=array("\r", "\n", "\t", "\\", "\" "); //दो बाइट एस्केप कोड $escapes2=array("\r", "\n", "\t", "\\", "\""); //वास्तविक कोड if($mode=='EXCEL'' (// एस्केप कोड = ''$delim='', $enclos='''; $esc_enclos=''''; $rowbr='\r \n"; ) अन्यथा //मोड=मानक (// सभी फ़ील्ड संलग्न $delim='',"; $enclos=''''; $rowbr='\r\n'; ) $indxf=0; $indxl=0; $encindxf=0; $encindxl=0; $enc=0; $enc1=0; $enc2=0; $brk1=0; $rowindxf=0; $rowindxl=0; $encflg=0; $rowcnt=0; $colcnt=0; $rowflg=0; $colflg=0; $ सेल = ""; $headerflg=0; $quotedflg=0; $i=0; $i2=0; $imax=strlen($csv); जबकि($indxf< $imax) { //find first *possible* cell delimiters $indxl=strpos($csv, $delim, $indxf); if($indxl===false) { $indxl=$imax; } $encindxf=strpos($csv, $enclos, $indxf); if($encindxf===false) { $encindxf=$imax; }//first open quote $rowindxl=strpos($csv, $rowbr, $indxf); if($rowindxl===false) { $rowindxl=$imax; } if(($encindxf>$indxl)||($encindxf>$rowindxl)) ( $quoteflg=0; $encindxf=$imax; $encindxl=$imax; if($rowindxl<$indxl) { $indxl=$rowindxl; $rowflg=1; } } else { //find cell enclosure area (and real cell delimiter) $quoteflg=1; $enc=$encindxf; while($enc<$indxl) //$enc = next open quote {// loop till unquoted delim. is found $enc=strpos($csv, $enclos, $enc+1); if($enc===false) { $enc=$imax; }//close quote $encindxl=$enc; //last close quote $indxl=strpos($csv, $delim, $enc+1); if($indxl===false) { $indxl=$imax; }//last delim. $enc=strpos($csv, $enclos, $enc+1); if($enc===false) { $enc=$imax; }//open quote if(($indxl==$imax)||($enc==$imax)) break; } $rowindxl=strpos($csv, $rowbr, $enc+1); if($rowindxl===false) { $rowindxl=$imax; } if($rowindxl<$indxl) { $indxl=$rowindxl; $rowflg=1; } } if($quoteflg==0) { //no enclosured content - take as is $colflg=1; //get cell // $cell=substr($csv, $indxf, ($indxl-$indxf)-1); $cell=substr($csv, $indxf, ($indxl-$indxf)); } else// if($rowindxl >$encindxf) ( // सेल संलग्न $colflg=1; //सेल प्राप्त करें - सेल सामग्री को डीकोड करें $सेल=substr($csv, $encindxf+1, ($encindxl-$encindxf)-1); यदि($मोड= = "EXCEL") //EXCEL 2quote एस्केप हटाएं ($ cell=str_replace($esc_enclos, $enclos, $ cell); ) अन्यथा // मानक esc हटाएं ($ cell=str_replace($escapes, $escapes2, $ cell ); ) ) if($colflg) (// सेल को सरणी में पढ़ें if(($fmt=='2D_FIELDNAME_ARRAY'' && ($headerflg==1)) ( $row[$fields[$colcnt]]=$सेल ; ) अन्यथा यदि(($fmt=='2D_NUMBERED_ARRAY''||($headerflg==0)) ( $row[$colcnt]=$सेल; ) //$rows[$rowcnt][$colcnt] = $ सेल; $colcnt++; $indxf=$indxl+1;//strlen($delim); =0)) ( $fields=$row; $row=array(); $headerflg=1; ) अन्यथा ( $rows[$rowcnt]=$row; $row=array(); $rowcnt++; ) $colcnt= 0; $ सेल = ""; $ रोविंडxl+2;//strlen($rowbr); //SWMessage("SW_ExplodeCSV() - colcnt = ".$colcnt।" rowcnt = ".$rowcnt." indxf = ".$indxf." indxl = ".$indxl." rowindxf = ".$rowindxf); //if($i>20) ब्रेक; ) $पंक्तियाँ लौटाएँ; )

बॉब अब अपने भाषणों पर वापस आ सकते हैं

10948|पुस्तक|प्रकार1

SHA512||0||10948

0|10948|SHA512|

काश ऐसा होता

C3884fbd7fc122b5273262b7a0398e63|SHA512|टाइप1|पुस्तक

मेरे पास वास्तविक डेटाबेस तक पहुंच नहीं है, क्या ऐसा करने का कोई तरीका है? मूल रूप से $id = $file1; की तलाश करता है। अगर($फ़ाइल3 == $आईडी) $आईडी = $फ़ाइल1; if($file3 == $id) या कुछ और भी अधिक कुशल।

प्रत्येक CSV फ़ाइल 100k-300k लाइनों से कहीं भी स्थित होती है। अगर इसमें कुछ समय लगता है तो मुझे इसकी परवाह नहीं है, मैं इसे कुछ समय के लिए EC2 पर चलने दे सकता हूँ।

$डेटा = सरणी(); $fh = fopen("फ़ाइल1") या मरें("फ़ाइल1 खोलने में असमर्थ"); while(list($id, $val1, $val2) = fgetcsv($fh, 0, "|")) ( $data[$id]["val1"] = $val1; $data[$id][" val2"] = $val2; ) fclose($fh); $fh = fopen("फ़ाइल2") या मरें("फ़ाइल2 खोलने में असमर्थ"); जबकि(सूची($विधि, शून्य, शून्य, शून्य, $आईडी) = fgetcsv($fh, 0, "|")) ( $डेटा[$id]["विधि"] = $विधि; ) fclose($fh ); $fh = fopen("file3") याdie("file3 खोलने में असमर्थ"); जबकि(सूची(शून्य, $आईडी, शून्य, $हैश) = fgetcsv($fh, 0, "|")) ( $डेटा[$आईडी]["हैश"] = $हैश; ) fclose($fh);

यह आवश्यक है, लेकिन आपको अपने इच्छित डेटा के साथ एक सरणी प्राप्त करनी होगी। इसे किसी अन्य सीएसवी के रूप में आउटपुट करना पाठक के लिए एक अभ्यास के रूप में छोड़ दिया गया है (संकेत: fputcsv() देखें)।

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

उदाहरण के लिए:

$परिणाम = सरणी(); // फ़ाइल 1 $fh = fopen('फ़ाइल1'); जबकि (($डेटा = fgetcsv($fh, 0, "|")) !== गलत) $परिणाम[$डेटा] = $डेटा; fclose($fh); // फ़ाइल 2 $fh = fopen("file2") जबकि ($data = fgetcsv($fh, 0, "|")) !== FALSE) $result[$data] = array_merge($result[$data ], $डेटा); fclose($fh); // फ़ाइल 3 $fh = fopen("file3") जबकि ($data = fgetcsv($fh, 0, "|")) !== FALSE) $result[$data] = array_merge($result[$data ], $डेटा); fclose($fh);

मैं बुनियादी यूनिक्स टूल का उपयोग करके मर्ज-सॉर्ट करने का सुझाव दूंगा:
a) .CSV फ़ाइलों को प्रत्येक फ़ाइल के लिए सामान्य कॉलम के आधार पर क्रमबद्ध करें, क्रमबद्ध करें -d "" -K? -को? -को?
बी) .CSV फ़ाइलों के जोड़े के बीच साझा किए गए रिकॉर्ड को सूचीबद्ध करने के लिए यूनिक्स "जॉइन" कमांड का उपयोग करना। "ज्वाइन" कमांड एक समय में केवल दो फाइलों पर काम करता है, इसलिए आपको कई डेटा स्रोतों में परिणामों को "चेन" करना होगा:

# जहां "x" फ़ाइल A से फ़ील्ड नंबर है, और "y" फ़ाइल B से फ़ील्ड नंबर है sort -kx "fileA" sort -ky "fileB" join -1x -2y "fileA" "fileB" > file1 sort -kx "fileC" जुड़ें -1x -2y "file1" "fileC" > फ़ाइल2 सॉर्ट -kx "फ़ाइलD" जुड़ें -1x -2y "फ़ाइल2" "फ़ाइलD" > फ़ाइल3 आदि...

यह बहुत तेज़ है और आपको अपनी .CSV फ़ाइलों को फ़िल्टर करने की अनुमति देता है जैसे कि कोई अचानक डेटाबेस कनेक्शन हो।

यदि आपको php में अपनी स्वयं की मर्ज-सॉर्ट विधि लिखने की आवश्यकता है: (यहां पढ़ें: मर्ज सॉर्ट)

.CSV फ़ाइलों को मर्ज करने का सबसे सरल कार्यान्वयन दो चरणों वाली प्रक्रिया है: a) यूनिक्स आपकी फ़ाइलों को सॉर्ट करता है, फिर B) सभी स्रोतों को समानांतर में "विलय" करता है, प्रत्येक से रिकॉर्ड पढ़ता है, ऐसे मामले की तलाश करता है जहां आपका मान आपके सामान्य में हो फ़ील्ड अन्य सभी स्रोतों से मेल खाते हैं (डेटाबेस शब्दावली में शामिल हों):
नियम 1) जो प्रविष्टि छोटी हो उसे छोड़ें (<) ВСЕХ других источников.
नियम 2) जब किसी रिकॉर्ड का कुल मूल्य (==) के बराबर होता है, तो अन्य सभी स्रोतों का मिलान होता है।
नियम 3) जब किसी प्रविष्टि का कुल मान (==) हो, किसी अन्य स्रोत से कुछ हो, तो आप चाहें तो "LEFT-JOIN" तर्क का उपयोग कर सकते हैं, अन्यथा सभी स्रोतों से उस प्रविष्टि को छोड़ दें।

एकाधिक फ़ाइलों को मर्ज करने के लिए स्यूडोकोड

प्रत्येक डेटा स्रोत से पहला रिकॉर्ड पढ़ें; जबकि "रिकॉर्ड सभी डेटा स्रोतों से मौजूद है"; प्रत्येक डेटा-स्रोत में ए के लिए करें; प्रत्येक डेटा-स्रोत में B के लिए cntMissMatch=0 सेट करें; यदि ए.फ़ील्ड करें तो करें< B.field then cntMissMatch+=1 end if end for if cntMissMatch == count(Data-Sources) then # found record with lowest values, skip it read next record in current Data-source; break; # start over again looking for lowest else if cntMissMatch == 0 then we have a match, process this record; read in next record from ALL data-sources ; break; # start over again looking for lowest else # we have a partial match, you can choose to have # "LEFT-JOIN" logic at this point if you choose, # where records are spit out even if they do NOT # match to ALL data-sources. end if end if end for done

उम्मीद है ये मदद करेगा।



मित्रों को बताओ