webForumDet fria alternativet

Hämta data från massor av xml filer.

PHP

5 svar · 288 visningar · startad av UrMe

Medlem sedan apr. 2001762 inlägg
Frågan#1

Hej,

Jag har gjort ett script som ska hämta en massa data från en xml fil först.. som heter 10.xml.

Men nu till problemet jag vill hämta data från fler xml filer samtidigt och föra in detta in en mysql databas.. men nånstans brister det ;) .. det är ungeför 2000-3000 xml-filer jag vill hämta data ifrån genom en loop :)
Det börjar på 10 och slutar nånstans på 2000.

Här kommer koden.. den fungerar men efter ett tag blir det sidan kan inte visas... jag vet inte om server eller vad det är som inte pallar med riktigt.

Koden är ju inte direkt optimerad kanske.. men nån som vet om det går och isåfall kan peka mig i rätt riktning vart felet ligger?

Det är på olika ställen som scriptet stannar .. den hinner ungefär med mellan 60-110 xml filer.. och det blir ungefär 2500-3300 rader/inlägg i mysql.

<?php
set_time_limit(0);
if(!IsSet($guildidnr))
{
	$guildidnr = 10;
}
include("databaskoppling.php");

$indexnr = 0;
$indexnr2 = 0;
$in_char = 0;
$in_alliance = 0;
$in_crafting = 0;
$indexnr3 = 0;
$indexnr4 = 0;
$indexnr5 = 0;
function startElement($parser, $name, $attrs=''){
    global $current_tag, $thenames, $indexnr, $indexnr2, $in_char, $theguild, $indexnr5;
    $current_tag = $name;
    switch($name){
		case 'GUILD':
		$theguild[$indexnr5]['guildname']=$attrs['NAME'];
		$theguild[$indexnr5]['realm']=$attrs['REALM'];
		break;
    	case 'CHARACTER':
		$in_char = 1;
		$thenames[$indexnr]['name']=$attrs['NAME'];
		$forefternamn = explode(' ',$thenames[$indexnr]['name']);
		$thenames[$indexnr]['firstname'] = $forefternamn[0];
		$thenames[$indexnr]['lastname'] = $forefternamn[1];
    	 break;
        default:
        break;
    }
}
function endElement($parser, $name, $attrs=''){
    global $current_tag, $in_char, $indexnr, $in_alliance, $indexnr2, $indexnr3, $in_crafting, $in_crafting2, $indexnr4;
    switch($name){
		case 'GUILD':
		$indexnr5++;
		break;
        case 'CHARACTER':
		  $indexnr++;
		  $in_char = 0;
        default:
        break;
    }
}

function characterData($parser, $data)
{
    global $current_tag, $indexnr, $thenames, $in_char, $in_alliance, $indexnr2, $thealliance, $in_crafting, $indexnr3, $thecraft;
	
	if (($in_char == 1) && ($current_tag == 'RACE')) {
            $thenames[$indexnr]['race'] .= $data;
	}
	if (($in_char == 1) && ($current_tag == 'CLASS')) {
            $thenames[$indexnr]['class'] .= $data;
	}
	if (($in_char == 1) && ($current_tag == 'LEVEL')) {
            $thenames[$indexnr]['level'] .= $data;
	}
	if (($in_char == 1) && ($current_tag == 'TOTALRP')) {
            $thenames[$indexnr]['totalrp'] .= $data;
	}
	if (($in_char == 1) && ($current_tag == 'LASTWEEKRP')) {
            $thenames[$indexnr]['lastweekrp'] .= $data;
	}

}

$filen1 = "http://camelot-europe.goa.com/herald/servers/Excalibur/guilds/";
$filen2 = $guildidnr.".xml";
$filen3 = $filen1.$filen2;

$xml_file = $filen3;
$type = 'UTF-8';
$xml_parser = xml_parser_create($type);
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
xml_set_element_handler($xml_parser, 'startElement','endElement');
xml_set_character_data_handler($xml_parser, 'characterData');

if (!($fp = fopen($xml_file, 'r'))) {
    die("Could not open $xml_file for parsing!\n");
}

$xmldata="";
while ($data = fread($fp, 4096)) {
    if (!($data = utf8_encode($data))) {
        echo 'ERROR'."\n";
    }
	$xmldata.=$data;
}
if (!xml_parse($xml_parser, $xmldata, true)) {
  die("XML error".xml_error_string(xml_get_error_code($xml_parser)));
}
xml_parser_free($xml_parser);

if(!IsSet($forsta))
{
	mysql_query("DELETE FROM excalibur_xml_members");
}
	for($j=0;$j<$indexnr;$j++)
	{
		mysql_query("INSERT INTO excalibur_xml_members (name, firstname, lastname, race, class, level, totalrp, lastweekrp, guild, guildid, realm) VALUES('".$thenames[$j]['name']."','".$thenames[$j]['firstname']."','".$thenames[$j]['lastname']."','".$thenames[$j]['race']."','".$thenames[$j]['class']."','".$thenames[$j]['level']."','".$thenames[$j]['totalrp']."','".$thenames[$j]['lastweekrp']."','".$theguild[0]['guildname']."','".$guildidnr."','".$theguild[0]['realm']."')");
	}

$guildidnr = $guildidnr + 1;

header("Location: excaliburchars.php?guildidnr=$guildidnr&forsta=1");
?>

Jag kör med header location för att hoppa till nästa xml fil.. kanske finns nåt bättre? :)

Medlem sedan apr. 2002830 inlägg
#2

Det kanske är så att du överbelastar servern lite. Kan du inte köra 100 eller något åt gången? Måste alla läsas samtidigt?

// Nippe

Medlem sedan apr. 2001762 inlägg
#3

jo jag har tänkt på det.. men får kanske köra 50 eller nåt då.. men då måste jag ju göra 3000/50 = 60 php filer :( .. som jag måste lägga in i cronjob som ska köras 1 gång / dygn...

Om ingen har nåt bättre alternativ? Så att man bara behöver 1 php fil men inte belastar servern lika mycket.

Medlem sedan apr. 2002830 inlägg
#4

Hm, du skulle ju kunna göra så att den refreshar så fort den är färdig och påbörjar de övriga 50 filerna..

Medlem sedan apr. 2001762 inlägg
#5

Jao.. jag fick till det med refresh ;) ..

Det var typ 2100 xml filer i varierande storlek och tog typ 40-45min att köra igenom men servern pallade det ;)
Kanske finns nåt bättre sätt men detta får duga tills vidare.

Tack igen!

Medlem sedan apr. 2002830 inlägg
#6

nemas problemas! :)

258 ms totalt · 4 externa anrop · v20260731065814-full.e96017d9
120 ms — deklarationer (db)
0 ms — hämta statistik (cache)
135 ms — hämta tråd, inlägg och bilagor (db)
120 ms — ändringar (db)