13. august 2009 - 09:10Der er
20 kommentarer og 2 løsninger
gem evt. kopier i 21346 items (fra XML) i ny fil...
Jeg har en xml-fil med 21436 items. De items skal ind i en database, hvilket er nemt nok. Problemet er at der findes duplikater af nogle af de items og duplikaterne skal skrives til en fil.
Jeg har forsøgt at gøre det ved at gemme ID og Key for hver item i et array og kigge det igennem for at se om den aktuelle Key er brugt i forvejen og gemme alle oplysninger om det aktuelle item i et andet array. Det er der bare ikke hukommelse nok til..
Jeg har også forsøgt at gemme ID og Key i alm. variabler, men så vil det kun virke hvis duplikaterne er lige efter hinanden, hvilket ikke er tilfældet.
Jeg kunne også forsøge at skrive det direkte til en fil, hver gang jeg har et duplikat, men det er jeg ikke meget for..
for ($i=0,$j=count($a); $i<$j; $i++) { if (oHash[$a[$i]]) { // Denne værdi er allerede indsat i DB // Indsæt i stedet i ny fil } else { // Indsæt i DB oHash[$a[$i]] = 1; } }
Det er mange, mange gange hurtigere (og mindre hukommelseskrævende) end at bruge in_array ;o)
Nu viste jeg, at værdierne kom fra array'et $a - men i dit tilfælde kommer de jo fra en XML-fil. Det vigtige er at indsætte i - og teste mod - en hash tabel ($oHash)
$xmltemplate = simplexml_load_file($tmp); foreach($xmltemplate->Employees->Employee as $val) { $sql = "INSERT INTO temp_doctors SET KEY = '".$val->Key."', Username = '".$val->UserName."', eCode = '', RegionID = 3, Enabled = 'True', UserPermissions = (SELECT UserPermissions FROM sys_userroles WHERE UserRoleID = 15), HomePage = (SELECT HomePage FROM sys_userroles WHERE UserRoleID = 15), UserType = 15,"; $sq2 = "FirstName = '".mysql_escape_string(utf8_decode($val->FirstName))."', LastName = '".mysql_escape_string(utf8_decode($val->LastName))."', Email = '".$val->Mail."'"; $sq3 = "ON DUPLICATE KEY UPDATE "; mysql_query($sql.$sq2.$sq3.$sq2) or die("<pre>".$sql."</pre>".mysql_error()); $pass = ''; $length = 2; for($p=0;$p<$length;$p++) { $pass .= chr(97 + mt_rand(0,25)); } $sql = "UPDATE temp_doctors SET eCode = CONCAT('sj',LAST_INSERT_ID(),'". $Pass ."') WHERE DoctorID = LAST_INSERT_ID()"; mysql_query($sql) or die("<pre>".$sql."</pre>".mysql_error()); }
I den kode har jeg forsøgt at indsætte det her lige før den sidst } $done[$x]['KEY']=$val->Key; $done[$x]['ID']=$val->ID; $x++;
Gør jeg det for jeg følgende fejl: Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 24 bytes) in /var/www/rsj_parse/RSJ_XmlParser.php on line 20
#5 Fordi vi ikke ved hvilken en af kopierne er den rigtige.. Skulle nok have præciseret at det er Key som kan være genganger og ikke hele item.. Desuden vil det være sådan at XML-filen vil komme 1x dagligt og skal parses og databasen skal opdateres. For at kunne undgå at de samme Keys bliver ved med at have duplikater vil vi lave en fil med duplikaterne som vi kan sende tilbage til dem vi modtager XML'en fra
repox >> Der er gigantisk forskel på at teste ned i et array, du bladrer igennem element for element og tester på det (det er det, in_array gør) - og at teste på, om en key eksisterer i et array (hash tabel). Ikke kun i PHP ;o)
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.