Warnung: file_put_contents(/home/www/web1/html/php_dev/test.txt) [function.file-put-contents]: failed to open stream: Permission denied in /home/www/web1/html/php_dev/sys/lib.activity.php (Zeile 58)
php File Upload mit Progress Bar (AJAX) [Archiv] - PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

- Ad -
php-resource




Archiv verlassen und diese Seite im Standarddesign anzeigen :
php File Upload mit Progress Bar (AJAX)


 
Chrissi007
21-01-2009, 15:27 
 
Hi zusammen,

Ich bin gerade dabei einen Fileuplod mit Progressbalken auf Basis der PECL Extension uploadprogress zu realisieren.

Beim Start des Dateiuploads rufe ich per onSubmit-Ereignis eine Funktion auf.

<form onsubmit="UP.start('{$upload_id}');" action="index.php?cmd=news" method="post" enctype="multipart/form-data" name="upload_form" target="ifr2">

Intern ruft UP.start regelmäßig die Funktion
requestInfo: function() {
//ifr = document.getElementById("ifr");
ifr.src="info.php?ID="+upload_id+"&"+new Date();
},

Wie ihr erahnen könnt, handelt es sich bei ifr um ein iframe, bei dem bei jedem Update das src-Attribut neu angegeben wird und es dadurch zu einem Refresh des iframes kommt.
Im Internet Explorer entsteht dabei allerdings jedes mal dieses <Click>-Geräusch und auch im Firefox verwandelt sich kurzerhand der Mauszeiger in ein Lade-Symbol.

Ich würde es deswegen gerne so machen, dass nicht jedesmal ein iframe neu geladen wird, sondern sich das innerHTML eines DIVs ändert.
Die Seite http://talks.php.net/show/torkey06/24 ( Demo: http://progphp.com/progress.php ) demonstriert recht anschaulich, was ich erreichen möchte...

Ich steh aber leider total aufm Schlauch. Wie kann ich das innerHTML eines DIVs alle 2 Sekunden ändern? Wie kann ich aus Javascript heraus einen php-Script aufrufen?

Für jeden Denkanstoß bin ich echt dankbar... Ich weiß grad echt nicht weiter.

 
Chrissi007
22-01-2009, 20:44 
 
Kennt keiner eine Javascriptfunktion, die das Ergebnis einer php-Seite auslesen kann?

 
ghostgambler
22-01-2009, 20:51 
 
Google(AJAX).
AJAX macht genau was du willst - nur ggf. mit XML und JSON und was noch alles. Kann aber auch einfach nur plain text.

 
fireweasel
24-01-2009, 12:45 
 
Original geschrieben von Chrissi007
Kennt keiner eine Javascriptfunktion, die das Ergebnis einer php-Seite auslesen kann?

Es gibt keine einfache Funktion. Um Requests an Webserver zu schicken und die Antworten auszuwerten, gibt es das XMLHTTPRequest-Objekt. Das ist der Kern des modernen Remote-Scriptings, oder AJAX, wie es vom Marketing getauft wurde.

Wie man das XMLHTTPRequest-Objekt benutzt, erfährst du (unter Anderem) hier:
http://ajaxpatterns.org/XMLHttpRequest_Call
und hier:
http://developer.apple.com/internet/webcontent/xmlhttpreq.html

Für eine Upload-Progress-Anzeige reicht es meistens, wenn das antwortende Server-Script einen zweizeiligen Text liefert: Erste Zeile "hochgeladene Bytes", zweite Zeile "insgesamt hochzuladene Bytes". XML- oder JSON (http://de.wikipedia.org/wiki/JSON)-formatierte Daten zu versenden, macht nur das Server-Script aufwändiger als nötig.

 
derHesse
25-01-2009, 10:55 
 
Warum wieder mal das Rad neu erfinden ...


http://swfupload.org/

oder mit Mootools:
http://digitarald.de/project/fancyupload/

nutzt zwar alles kein PECL, tut aber das was du im Endeffekt willst

 
fireweasel
26-01-2009, 18:37 
 
Original geschrieben von derHesse
Warum wieder mal das Rad neu erfinden ...

http://swfupload.org/

oder mit Mootools:
http://digitarald.de/project/fancyupload/

nutzt zwar alles kein PECL, tut aber das was du im Endeffekt willst

Nunja, Flash-Scripts einzuspannen um Dateien hochzuladen, ist wohl eher vom Typ "Rad neu erfinden". Schließlich können das Browser schon seit Jahrzehnten ohne Plugin[3].

Und was die JavaScript-Lösung angeht: Ich kenne MooTools zwar allenfalls oberflächlich, aber ES GIBT (BISHER[1]) KEINE REINE JAVASCRIPT-LÖSUNG für File-Uploads mit Progress-Bar, schlicht und ergreifend deshalb, weil der Server den Upload-Fortschritt ermitteln muss -- mit JavaScript kommt man da (bisher[1]) nicht ran. Und PHP ist so ein Sonderfall, da ist der Fileupload so verkorkst gelöst[2], da braucht es halt diese komische PECL-Erweiterung, die nur für diesen einen Zweck erfunden wurde. Mit Perl, Python oder anderen sinnvollen Server-Sprachen kommt man an die File-Upload-Daten wesentlich einfacher ran.

--
[1] Die Browser geben die Infos bisher nicht raus. Könnte sich aber ändern.
[2] Frei nach dem alten IT-Motto: "Unsere Lösung -- Ihr Problem!"
*und_nachschieb*
[3] Dass ein Flash-Script den Komfort beim Datei-Upload verbessern kann, ist klar.

 
unset
26-01-2009, 19:54 
 
Original geschrieben von fireweasel
[B]Nunja, Flash-Scripts einzuspannen um Dateien hochzuladen, ist wohl eher vom Typ "Rad neu erfinden". Schließlich können das Browser schon seit Jahrzehnten ohne Plugin.
Für die Flash-Lösung spricht im allgemeinen auch eher, dass man auf einen Wisch mehrere Dateien hochladen kann, ohne die vorher packen zu müssen.

Das dass ganze nur in bestimmten Browser/Betriebssystem-Kombinationen gut funktioniert, macht es dann aber auch wieder überflüssig.

 
ghostgambler
26-01-2009, 20:45 
 
Original geschrieben von unset
Das dass ganze nur in bestimmten Browser/Betriebssystem-Kombinationen gut funktioniert, macht es dann aber auch wieder überflüssig.
Nein. Es bricht es maximal auf ein Goodie runter.
Wer 200 Bilder hoch laden will, und das möglichst einfach, muss dann halt Flash haben - und wird sich dann über diese Lösung garantiert freuen. Man stelle sich jedoch mal vor man müsste 200 Bilder über ein normales HTML-Formular einzeln auswählen und hoch laden ... zumindest ich hab noch andere Dinge zutun...

Alternativ bieten sich noch Lösungen über z.B. ZIP-Datei an, mit dem Problem, dass wenn der Transfer in der Mitte des 500MB Files abbricht, man noch mal von ganz vorne anfangen kann...

in kurz: Ich würde nicht behaupten, dass die Flash-Lösungen überflüssig wären.

 
unset
26-01-2009, 20:47 
 
Original geschrieben von ghostgambler
Nein. Es bricht es maximal auf ein Goodie runter.
Wer 200 Bilder hoch laden will, und das möglichst einfach, muss dann halt Flash haben
Das reicht aber noch nicht aus ...

 
Chrissi007
01-02-2009, 21:56 
 
danke für eure hilfe - hat mir sehr geholfen! :)

ps: bin auch zwischenzeitlich noch über folgende seite gestoßen, vielleicht für den ein oder anderen noch interessant: http://ajax.frozenfox.at/

 
Chrissi007
01-02-2009, 22:00 
 
Eine Frage hätte ich noch diesbezüglich.

Ich lass mir momentan per RequestObjekt php-seitig generierten HTML-Quelltext zurückgeben.


var content = request.responseText;
// den Inhalt des Requests in das <div> schreiben
document.getElementById('show_file_progress').innerHTML = content;


request.responseText ist der Inhalt, der dabei vom php-Script erzeugt und von Javascript empfnagen wird. Wie ihr seht speicher ich das ganze Zeug in der Variable $content ab und verändere dann das div dementsprechend, indem ich das innerHTML des divs den Inhalt aus content übergebe.

In diesem Content habe ich jetzt aber auch noch eine Javascript-Anweisung eingebaut.

[... hier weiter oben ist HTML-Quelltext...]
<script type="text/javascript">
rolldown_show("upload_in_progress");
</script>


kurz: dieser Codeschnippsel soll einfach eine Javascript-Funktion aufrufen.
Allerdings wird rolldown_show(); nie aufgerufen.

Ich hab auch schon so Sachen probiert wie ein eval() um den ganzen Bereich zu setzen, allerdings bringt das auch nichts.

Weiß jemand an was das liegen könnte, dass das Javascript nicht ausgeführt wird?

 
ghostgambler
01-02-2009, 22:56 
 
Google...
Bist 100%tig nicht der erste mit dem Problem.
(Das weiß ich weil ich es auch schon hatte...)

 
fireweasel
02-02-2009, 20:31 
 
Original geschrieben von Chrissi007
Eine Frage hätte ich noch diesbezüglich.

Ich lass mir momentan per RequestObjekt php-seitig generierten HTML-Quelltext zurückgeben.

Warum?
Hatte ich nicht schon erwähnt, dass es vollkommen genügt, nur die Daten zu übermitteln?
Ob als XML, JSON, CSV oder sonst wie ist egal, aber bitte NUR DIE DATEN und nicht die halbe Darstellungslogik (HTML + JavaScript)!



var content = request.responseText;
// den Inhalt des Requests in das <div> schreiben
document.getElementById('show_file_progress').innerHTML = content;


request.responseText ist der Inhalt, der dabei vom php-Script erzeugt und von Javascript empfnagen wird. Wie ihr seht speicher ich das ganze Zeug in der Variable $content ab und verändere dann das div dementsprechend, indem ich das innerHTML des divs den Inhalt aus content übergebe.

In diesem Content habe ich jetzt aber auch noch eine Javascript-Anweisung eingebaut.
Das ist noch schlimmer als bei jedem Request unnötig die HTML-Daten zu übertragen. Wo, zum Geier, hast du gelernt, dass man ausführbaren Code per Remote-Scripting zum Client schicken soll? Sagt dir das Wort "Code-Injection" nichts?


[... hier weiter oben ist HTML-Quelltext...]
<script type="text/javascript">
rolldown_show("upload_in_progress");
</script>


kurz: dieser Codeschnippsel soll einfach eine Javascript-Funktion aufrufen.
Allerdings wird rolldown_show(); nie aufgerufen.


Und was spricht dagegen, die Funktion, die die lustige Animation durchführt, schon beim erstmaligen Laden des HTML-Dokuments einzubinden? Und dann nur noch nach jedem Poll mit den passenden Parametern aufzurufen, anstatt das Ganze jedesmal per XMLHTTPRequest anzufordern in den DOM-Baum einzufügen und dann (in Unkenntnis der Sachlage) zu versuchen, darin eingebasteltes JavaScript auszuführen?

Weiß jemand an was das liegen könnte, dass das Javascript nicht ausgeführt wird?
Hmmm, der Browser ist sich anscheinend sicher, dass der von dir gewählte Weg keine gute Idee ist. Du solltest auf ihn hören ... ;-)

 
Chrissi007
03-02-2009, 00:29 
 
Das kommt dabei raus wenn ein Jscript Noob versucht ne AJAX-Anwendung zu bauen...

Ach schei... ich hab echt keinen blaßen Schimmer...

Könntest du mir vielleicht noch eine kleine Info mir mit auf den Weg geben: Wie ich mit php json-enkodierte Dinge erstelle und an Javascript sende ist mir soweit klar, aber wie krieg ich intern in Javascript dieses Json-Zeugs in eine Variable rein? Also ich muss die json-enkodierte Zeichenkette, die von php kommt, in Javascript ja irgendwie ausführen, oder?


Das ist noch schlimmer als bei jedem Request unnötig die HTML-Daten zu übertragen. Wo, zum Geier, hast du gelernt, dass man ausführbaren Code per Remote-Scripting zum Client schicken soll? Sagt dir das Wort "Code-Injection" nichts?
Ich versteh deine Besorgnis und Code-Injection sagt mir schon was. Nur wusste ich nicht, dass das im Zusammenhang mit Javascript auch ne Rolle spielen kann. Ich mein... hmm... ich seh nicht so genau, an welcher Stelle hier ein Angriff möglich wäre? Der Client empfängt ja nur Daten aus einem Script. Und das Script könnte ich ja genauso gut auch per Browser aufrufen.

 
PHP-Desaster
03-02-2009, 10:17 
 
Schau dir doch mal die Element.update (http://www.prototypejs.org/api/element/update)-Methode von Prototype an, die kann genau, was du suchst.
Btw: Ich finde das direkte Übergeben von HTML an den Browser nicht komplett daneben. Klar, eine saubere JSON - oder wie auch immer - Schnittstelle ist eindeutig sauberer, aber das direkte übergeben von HTML hat den Charm, das ich diese gerenderten Abschnitte auch direkt ohne Ajax verwenden kann und nicht zwei verschiedene Formate unterstützen muss. Gerade für etwas kurzfristige oder zeitkritische Projekte eine einfache Alternative, um trotzdem den Ajax-Vorteil nutzen zu können.

 
fireweasel
03-02-2009, 14:59 
 
Original geschrieben von Chrissi007
[B]Das kommt dabei raus wenn ein Jscript Noob versucht ne AJAX-Anwendung zu bauen...

Ach schei... ich hab echt keinen blaßen Schimmer...

Es stellt sich erstmal die Frage, ob du überhaupt deine Daten in JSON kodieren musst. Soweit ich das überblicken kann, ist die Auswahl an Informationen, die die UploadProgressInfo-Erweiterung liefert, eher dürftig. Du bekommst:
* die hochgeladenen Bytes,
* die insgesamt hochzuladenden Bytes (POST-Request-Rohdaten-Menge),
* und eventuell die Nummer der gerade hochgeladenen Datei
Diese Daten würde ich vom PHP-Script einfach als Text in drei Zeilen (mit CRLF getrennt) ausgeben lassen. Eine JavaScript-Funktion, die diese drei Zeilen in ein (assoziatives) Array aufsplittet, dürfte da keine große Hürde darstellen.

Außerdem ruft das Client-Script, das Server-Script mit der "Progress-Info" mehrmals auf. Bei deiner Lösung sendet nun das Server-Script bei jeder Anfrage den ganzen Kram (die drei Zahlen + HTML + JavaScript) an den Client -- das summiert sich (http://forum.de.selfhtml.org/archiv/2008/12/t181127/#m1197787).

Und eigentlich ist doch der HTML+JavaScript-Teil immer derselbe. Es sollte also genügen, die Anzeige-Logik einmalig zu laden, und nach Drücken des Submit-Buttons nur noch die reinen Daten abzufragen.


Könntest du mir vielleicht noch eine kleine Info mir mit auf den Weg geben: Wie ich mit php json-enkodierte Dinge erstelle und an Javascript sende ist mir soweit klar, aber wie krieg ich intern in Javascript dieses Json-Zeugs in eine Variable rein? Also ich muss die json-enkodierte Zeichenkette, die von php kommt, in Javascript ja irgendwie ausführen, oder?


mein_objekt = eval( "(" + http_request.responseText + ")" );


Klar, prinzipiell kannst du eval() verwenden -- aber eval() ist eine sehr leistungsfähige Funktion. Damit kann man viel Unfug anstellen, beispielsweise existierende Variablen komplett überschreiben -- und von ausführbarem Code reden wir da noch gar nicht. ;-)

Es gibt aber fertige JSON-Decoder, die das für dich erledigen -- musst du mal Google beätigen. Je nach Code-Umfang des Decoders sind dabei auch Sicherheitsmechanismen eingebaut, die Schlimmeres verhindern:

http://code.google.com/p/json-sans-eval/
http://www.json.org/json_parse.js

Die diversen Frameworks haben auch eingebaute JSON-Parser/-Decoder-Funktionen.

Eine interessante Alternative stellt parseJSON() (http://json.org/json2.js) dar Diese Funktion könnte irgendwann mal "native" in JavaScript eingebaut werden. (http://en.wikipedia.org/wiki/JSON#JavaScript_eval.28.29)


(...) ich seh nicht so genau, an welcher Stelle hier ein Angriff möglich wäre? Der Client empfängt ja nur Daten aus einem Script.

Ja gut, im Prinzip sorgt die Same-Origin-Policy (http://de.wikipedia.org/wiki/Same_Origin_Policy#Grenzen_und_Probleme) und die soliden JavaScript-Implementierungen der Browserhersteller und natürlich auch dein sicherheitslücken-freies Server-Script und die komplett sichere Konfiguration deines Webservers dafür, dass nichts passieren kann. Im Prinzip ...

Original geschrieben von PHP-Desaster:

Btw: Ich finde das direkte Übergeben von HTML an den Browser nicht komplett daneben. Klar, eine saubere JSON - oder wie auch immer - Schnittstelle ist eindeutig sauberer, aber das direkte übergeben von HTML hat den Charm, das ich diese gerenderten Abschnitte auch direkt ohne Ajax verwenden kann und nicht zwei verschiedene Formate unterstützen muss.
Siehe meine obigen Bedenken wegen mehrfacher Übertragung unnötiger Daten.
Aber das mit dem "ohne AJAX verwenden" versteh ich jetzt nicht -- erklär mal genauer.

 
PHP-Desaster
03-02-2009, 16:32 
 
Ich habe das Thema gar nicht von Anfang gelesen, als ich geantwortet habe. Jetzt sehe ich gerade, dass es ja lediglich um eine Progressbar geht, da ist eine direkte Übergabe der entsprechenden Parameter natürlich sinnvoller und mehr als ausreichend.

Siehe meine obigen Bedenken wegen mehrfacher Übertragung unnötiger Daten.
Aber das mit dem "ohne AJAX verwenden" versteh ich jetzt nicht -- erklär mal genauer.Damit meine ich Content-Bereiche in der Seite, die durch Ajax aktualisiert werden sollen und gleichzeitig - zum Beispiel für Nicht-Ajax-Browser - statisch gerendert werden soll. Wenn diese durch eine PHP-Routine direkt in HTML gerendert werden, so kann dieses Ergebnis entweder direkt in der statischen Ausgabe sowie in der Ajax-Variante verwendet werden, ohne eine weitere Routine für ein weiteres Format erstellen zu müssen. Als Beispiel kann man dazu vielleicht die "zufällige User"-Anzeige im StudiVZ nennen. Die nutzen bestimmt kein direktes HTML als Format, aber das wäre so ein Kandidat.
Wie gesagt, wenn es richtig sauber sein soll, natürlich per JSON oder sonstwie übertragen und beim Client im JavaScript neu rendern bzw. die Inhalte auswechseln.

 
Chrissi007
05-02-2009, 00:53 
 
Danke noch mals - Ich hab eure Vorschläge beherzigt :)

Ihr habt mich - glaube ich - auf den richtigen Weg gebracht.

Viele Grüße,
Chrissi

- -

Alle Zeitangaben in WEZ +2. Es ist jetzt 03:51 Uhr.