php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger > PHP Tipps 2006

 
 
LinkBack Themen-Optionen Thema bewerten
Alt 11.10.2006, 00:30  
Erfahrener Benutzer
 
Registriert seit: 08.11.2004
Beiträge: 2.079
Der_Gerhard ist zur Zeit noch ein unbeschriebenes Blatt
Der_Gerhard eine Nachricht über ICQ schicken
Standard Bearbeitung großer Datenmengen aufteilen

Hallo,

ich habe vor, über ein Formular eine XML-Datei auf den Server hochzuladen, dort mit PEAR::Serializer zu parsen und die Daten mit einer Datenbank abzugleichen bzw. einzutragen.

Nun kann ich aber nicht unbedingt garantieren, dass das Parsen und Verarbeiten innerhalb der maximalen Ausführungszeit des Scripts erfolgen kann.
Daher möchte ich gerne die hochgeladene Datei mit move_uploaded_file() in ein Temp-Verzeichnis zu verschieben, wo es aber nach Beendigung des Scripts noch erhalten bleibt.
Danach möchte ich ein anderes Script wiederholt aufrufen, wobei ich Dateiname und Startpunkt für die Bearbeitung übergebe (z.B. per URL-Parameter)
Wenn das Ende erreicht ist, soll die Datei wieder gelöscht werden.

Etwas Kopfzerbrechen bereitet mir dabei der Verbleib der Datei und das wiederholte Aufrufen des Scripts.

Was passiert, wenn während der Bearbeitung der Browser geschlossen wird?

Wie realisiere ich den wiederholten Aufruf am besten?

Mit Header() könnte ich einfach nach Verarbeitung des nächsten Häppchens zum nächsten Abschnitt weiterleiten.
Bei einer Warnung ist die Sache aber erledigt.
Diese Variante würde auch verhindern, dass ich eine Statusmeldung ausgebe.

Mit refresh im HTML-Header muss ich vor der eigentlichen Verarbeitung der Daten ja schon den HTML-Header und damit die Zeitspanne ausgeben. Und das kann dann entweder zu lang oder zu kurz sein. Problematisch ist höchstens der zu kurze Fall. Zu lang ist halt einfach Wartezeit für den Benutzer.

Was mich außerdem etwas stört ist, dass ich zunächst jedesmal die gesamte Datei parsen muss. Danach suche ich mir die nächsten zu verarbeitenden Daten aus.
Einerseits dauert das eine ganze Weile, andererseits benötigt das dann natürlich ne ganze Menge Speicher.
Kann ich mit dem PEAR::Serializer eine bestehende XML-Datei verändern?
Oder muss ich die Daten im Speicher löschen und eine neue Datei erstellen?
__________________
**********************************
Nein, ich bin nicht die Signatur.
Ich putze hier nur.
**********************************
Der_Gerhard ist offline  
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 12.10.2006, 12:30  
Erfahrener Benutzer
 
Registriert seit: 10.09.2004
Beiträge: 339
mkl0815
Standard

hmm am besten wäre es den verarbeitungsprozess von der html-ausgabe zu entkoppeln. das hängt aber von deinem server ab. wenn du dort prozesse starten kannst, dann lass dein upload-script einen verarbeitungsprozess im hintergrund starten, der status-meldungen in eine datei schreibt. diese kannst du dann mit einem unabhängigen script, welches sich per refresh immer wieder selbst aufruft abfragen und als statusmeldung ausgeben. wird der browser geschlossen, geht die verabeitung trotzdem weiter.

wenn du keine prozesse direkt starten kannst, würde evtl. auch ein cronjob gehen, der alle 5 minuten ein script startet, welches schaut ob dateien zu verarbeiten sind.

mario.
__________________
Problems with Windows : REBOOT
Problems with Linux : BE ROOT
mkl0815 ist offline  
Alt 12.10.2006, 12:37  
Erfahrener Benutzer
 
Registriert seit: 08.11.2004
Beiträge: 2.079
Der_Gerhard ist zur Zeit noch ein unbeschriebenes Blatt
Der_Gerhard eine Nachricht über ICQ schicken
Standard

Hi Mario,

danke für den Hinweis.

Der Cronjob gefällt mir nicht sonderlich, weil ich den nicht bei Bedarf aktivieren kann. Einfach fest alle 5 Minuten ein Aufruf ist auch nicht besonders komfortabel. Ich könnte ja bei jedem der Aufrufe nur einen Teil bearbeiten und hätten dann bei größeren Datenmengen recht viele Aufrufe.
Um sicher unter der maximalen Ausführungszeit zu bleiben werde ich wohl mal auf 2/3 der Zeit einstellen. Ich hätte dann also alle 5 Minuten mal 20 Sekunden bearbeitung.
Und ein cronjob mit <1 Minute ist erst recht problematisch. Da muss dann auch sichergestelle sein, dass der vorherige wirklich komplett bearbeitet wurde.

Ein weiterer Nachteil der asynchronen Bearbeitung ist, dass der Benutzer dann nicht sieht, wann die Daten verarbeitet wurden. Ich müsste also eine extra Status-Seite einfügen, wo dann in der nächsten halben Stunde irgendwann mal steht, dass alles erledigt ist.

Eigentlich sollte die unnötige Wartezeit so gering wie möglich ausfallen.

Bei HTTP 1.1 ist es doch AFAIK möglich, nach jedem Chunk noch einmal Header/Footer-Infos zu verschicken. Man könnte also praktisch nachträglich einen Header verschicken.
PHP kann das aber vermutlich nicht, was ja die ständigen "cannot send header..." Meldungen belegen.
Was der Browser dann mit einem nachgeschobenen "Location:..." anstellen würde, weiß ich aber auch nicht.
__________________
**********************************
Nein, ich bin nicht die Signatur.
Ich putze hier nur.
**********************************
Der_Gerhard ist offline  
Alt 12.10.2006, 14:02  
Erfahrener Benutzer
 
Registriert seit: 10.09.2004
Beiträge: 339
mkl0815
Standard

zum cronjob: bei einem per cronjob gestarteten prozess gibt es keine maximale ausführungszeit, das wäre also nicht das problem. das die lösung nicht sonderlich schön ist weiss ich ja.
ein prozess der im hintergrund läuft (z.b. per system() oder exec()) ist da sicher die bessere wahl. die verarbeitung sollte aber meiner meinung nach schon unabhängig vom client laufen. zumal php auch so konfiguriert werden kann, dass ein script beendet wird sobald die verbindung zum client gekappt wird.

mario.
__________________
Problems with Windows : REBOOT
Problems with Linux : BE ROOT
mkl0815 ist offline  
Alt 12.10.2006, 14:33  
Erfahrener Benutzer
 
Registriert seit: 08.11.2004
Beiträge: 2.079
Der_Gerhard ist zur Zeit noch ein unbeschriebenes Blatt
Der_Gerhard eine Nachricht über ICQ schicken
Standard

Mit Cronjob meinte ich jetzt einen externen Dienst, der die Seite zyklisch aufruft.

Einen lokalen Cronjob habe ich nicht zur Verfügung.

Ob ich einen neuen Prozess generieren kann, weiß ich grad nicht. Das ist ein Server von allinkl.com

Was die Trennung vom Client betrifft:
Dass der Benutzer den Browser schließt kann ich durch geeignete Hinweise verhindern. Es betrifft nicht sehr viele Leute.
Aber das Ergebnis bzw. der Fortschritt soll auf jeden Fall unmittelbar sichtbar sein.
Und das Ende soll auch sofort angezeigt werden.
__________________
**********************************
Nein, ich bin nicht die Signatur.
Ich putze hier nur.
**********************************
Der_Gerhard ist offline  
Alt 12.10.2006, 14:44  
Erfahrener Benutzer
 
Registriert seit: 10.09.2004
Beiträge: 339
mkl0815
Standard

ok, ich meinte schon lokale cronjobs.

wenn es ein shared-server ist, wird das wohl nicht gehen (muesste man ausprobieren).

das problem bei der "stückweise" verarbeiten sehe ich in einer vernünftgigen ablaufkontrolle, damit sich nicht parallel laufende verarbeitungen beeinflussen, abbrüche und fehler erkannt und korrekt behandelt werden. weiterhin musst du ja dafür sorgen, dass keine "dateileichen" übrigbleiben, wenn doch mal was schief geht. diese logik abzubilden halte ich für recht aufwendig.
weiterhin kommt dazu, dass die übergebenen daten sich auch schrittweise verarbeiten lassen, sonst gibts da noch viel größere probleme.

mario.
__________________
Problems with Windows : REBOOT
Problems with Linux : BE ROOT
mkl0815 ist offline  
Alt 12.10.2006, 14:52  
Erfahrener Benutzer
 
Registriert seit: 08.11.2004
Beiträge: 2.079
Der_Gerhard ist zur Zeit noch ein unbeschriebenes Blatt
Der_Gerhard eine Nachricht über ICQ schicken
Standard

Ja, das ist so ein Shared-Server für 50 oder 100 Kunden. Da werde ich solche Sachen vermutlich nicht machen können.

Die Probleme bei der Aufteilung und mit den Dateileichen sind mir durchaus bewusst.
Ich könnte einfach in einer DB-Tabelle die vorhandenen Dateien und deren Bearbeitungsstand ablegen. Wenn das Script irgendwann mal aufgerufen wird und feststellt, dass eine Datei schon komplett abgearbeitet wurde, kann es diese ja auch noch löschen.

Die Daten kann ich schon in einzelne Häppchen packen und dann anhand des aktuellen Verarbeitungsschrittes den nächsten Teil davon haranziehen. Dumm ist dabei nur, dass ich jedesmal die gesamte XML-Datei parsen muss und immer nur einen kleinen Teil davon verarbeite.
__________________
**********************************
Nein, ich bin nicht die Signatur.
Ich putze hier nur.
**********************************
Der_Gerhard ist offline  
Alt 12.10.2006, 15:04  
Erfahrener Benutzer
 
Registriert seit: 10.09.2004
Beiträge: 339
mkl0815
Standard

du stösst da gerade an die grenzen dessen was man in deiner webumgebung noch mit vertretbarem aufwand machen kann. alle lösungen die du baust werden nicht die eigentliche verarbeitung der daten zum ziel haben, sondern vorwiegend dazu da sein, die unzulänglichkeiten der laufzeitumgebung auszugleichen.
das ist doppelt nachteilig, da zum einen der aufwand sehr viel größer ist und zum anderen die fehleranfälligkeit durch komplexere abläufe zunimmt.

mario.

p.s. ich wünsche dir auf alle fälle viel erfolg bei der lösung des problems. evtl. gibt es ja ein möglichkeit die verarbeitung in einen eigenen prozess zu packen.
__________________
Problems with Windows : REBOOT
Problems with Linux : BE ROOT
mkl0815 ist offline  
Alt 12.10.2006, 15:05  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Ne andere Idee wegen der Geschwindigkeit: Wenn du keine Binär-Felder hast, könntest du statt XML einfach CSV verwenden. Für Text-Felder einfach urlencode() drüberlaufen lassen. Ist allemal schneller, denn soweit ich weiß wird XML immer geparsed -meintest du ja auch schon-, in CSV kannst du ja aber hinspringen wo du möchtest, ohne die Datei komplett einzulesen (das ist aber nur eine Vermutung, ich weiß nicht ob die Datei nicht trotzdem komplett eingelesen werden muss. Trotzdem hat CSV ja eine viel einfachere Struktur als XML.

Und die Ausführungszeit sollte dich ja auch nicht jucken, die kannst du schließlich abschalten oder ist das vom Hoster gesperrt?
Zergling-new ist offline  
Alt 12.10.2006, 15:09  
Erfahrener Benutzer
 
Registriert seit: 10.09.2004
Beiträge: 339
mkl0815
Standard

aua ... xml kann nicht in jedem fall einfach nach CSV gewandelt werden, da XML ein Baumstruktur abbildet und CSV eine flacherer Sturktur ist (Matrix).

mario.
__________________
Problems with Windows : REBOOT
Problems with Linux : BE ROOT
mkl0815 ist offline  
 


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php während der bearbeitung ausgabe, php daten aufteilen, bearbeitung großer datenmengen, eine xml datei aufteilen, php move_uploaded_file stückweise

Alle Zeitangaben in WEZ +2. Es ist jetzt 14:17 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.