• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

PHP gleichzeitiger Zugriff?

MaxG

Neues Mitglied
Guten Tag zusammen :)
Ich habe auf meinem FTP Server eine PHP Datei, welche eine XML Datei mit NEUEN Einträgen füttert. Das heisst, es wird nichts geladen sondern geschrieben!!
Jetzt ist meine Frage ob es da nicht zu Fehlern kommen kann, wenn zwei User die PHP Datei gleichzeitig ausführen.
Kann PHP mit doppelten zugriffen umgehen? Meine PHP Datei sieht ungefähr so aus:

PHP:
<?php
$xml = simplexml_load_file("datenbank.xml"); //This line will load the XML file. 
$sxe = new SimpleXMLElement($xml->asXML()); //In this line it create a SimpleXMLElement object with the source of the XML file. //The following lines will add a new child and others child inside the previous child created. 
$person = $sxe->addChild("Person"); $person->addChild("first_name", "Nairoby"); $person->addChild("last_name", "Del Rosario"); $person->addAttribute('type', 'stars');


$sxe->asXML("datenbank.xml");  //Überschreibt die alte Datenbank mit den Aktualisierungen

?>
 
Es ist relativ unwahrscheinlich, dass es zu einem 'Deadlock' kommt. Nur bei recht großem Traffic solltest du dir darum Gedanken machen müssen.

Wenn du dich vor Datenverlust gänzlich schützen möchtest, kannst du dir eine kleine Funktion implementieren. Das lässt sich beispielsweise umsetzen, indem ein Schreibprozess zunächst eine temporäre zweite Datei anlegt, die kennzeichnet, dass die Datei gerade bearbeitet wird. Die anderen Schreibprozesse sind durch eine Existenzabfrage informiert, dass sie nun nicht schreiben sollten. Nach einem Änderungsvorgang wird die temp. natürlich wieder gelöscht.
 
Oh Gott, das hört sich aufwendig an :D Ich programmiere eigentlich Windows Anwendungen und PHP ist ein noch sehr frisches Thema bei mir.
Es gibt also keine API o.ä. was diesen Fehler umgehen könnte?
 
Kurz und ungetestet:

PHP:
/**
 * @return int 0=error; 1=file in use; 2=success; 3=success but temp still exists
**/
function write_file($path, $content){
	if(file_exists($path.'_temp')){ // check whether temp deadlock file exists
		return 1;
	}
	$handle = fopen($path.'_temp', 'w'); // create temp file
	if(!$handle){
		return 0;
	}
	fclose($handle);
	if(!file_write_contents($content)){ // write contents to file
		return 0;
	}
	if(!unlink($path.'_temp')){ // delete temp file
		return 3;
	}
	return 2;
}

In deinem Code bspw.:
PHP:
 <?php
$xml = simplexml_load_file("datenbank.xml"); //This line will load the XML file. 
$sxe = new SimpleXMLElement($xml->asXML()); //In this line it create a SimpleXMLElement object with the source of the XML file. //The following lines will add a new child and others child inside the previous child created. 
$person = $sxe->addChild("Person"); $person->addChild("first_name", "Nairoby"); $person->addChild("last_name", "Del Rosario"); $person->addAttribute('type', 'stars');

function write_file($path, $content){
	if(file_exists($path.'_temp')){ // check whether temp deadlock file exists
		return 1;
	}
	$handle = fopen($path.'_temp', 'w'); // create temp file
	if(!$handle){
		return 0;
	}
	fclose($handle);
	if(file_put_contents($path, $content) === false){ // write contents to file
		return 0;
	}
	if(!unlink($path.'_temp')){ // delete temp file
		return 3;
	}
	return 2;
}

$trys = 0;
do{
    $return = write_file('datenbank.xml', $sxe->asXML());  //Überschreibt die alte Datenbank mit den Aktualisierungen
    if($return == 1){
        time_nanosleep(0, 10000);
    }
    $trys++;
}while($return != 2 && $trys < 10);

?>

Die Funktion erzeugt eine Datei mit der Endung _temp. Ist sie schon vorhanden, bricht die Funktion mit dem Fehlercode 1 ab, da scheinbar die Datei in Benutzung ist. Ansonsten wird die Datei regulär geschrieben. In der Implementierung in deinem Code wird bis höchstens 10 mal versucht, die Datei zu beschreiben. Ist die Datei in Benutzung, wird der Prozess zudem für 10.000 Nanosekunden pausiert (in der Hoffnung, dass die Datei dann wieder frei ist).
 
Zurück
Oben