Lade-Balken einblenden bei MySQL-Abfragen

webdoktor

Angesehenes Mitglied
Hallo zusammen

Ich habe 3 komplexe MySQL Abfragen welche zusammen etwa 20 Sekundne dauern.
Nun möchte ich in dieser Zeit einen Ladebalken einbleden resp. eine animierte Grafik.

Wie muss ich das machen, dass in dieser Zeit eine Lade-Grafik erscheint und sobald
die Abfrage zuende ist, diese Grafik wieder verschwindet.

Vielen Dank für eure Hilfe!

Marco
 
Ich würde es mit Javascript machen. Einen Div mit der Grafik drin, und nach der letzten Anfrage setzt du einfach mit JS die visibility:hidden.
 
Hallo zusammen

Danke für die prompte Antwort. Hat mir jemand ein konkretes Beispiel?
Wäre sehr sehr dankbar!

Liebe Grüsse
Marco
 
Ich würde vielleicht erstmal bei der mySQL-Abfrage ansetzen und schauen, ob es wirklich notwendig ist, das die Abfrage 20 Sekunden dauert.
Das scheint mir eine doch sehr unperformante Anfrage zu sein.
 
Hallo Heiko

Ja das ist ganz sicher notwendig da es eine LDAP Abfrage ist vom AD und ich
brauche alle Benutzer in einer Datei.

Nun ich habe jetzt folgendes gemacht aber der Balken wird beim laden der
Seite nicht angezeigt!

CSS-Code für den Layer:
CODE
#loading
{

position: relative;
left:350px;
top:200px;
visibility: hidden;
}




Im Body Teil der Layer inkl Loading Balken:

CODE
<div id="loading"><img src="images/gif/loading-balken.gif" width="220" height="19" alt="Loading" /></div>




Java-Script im Header um den Layer einzublenden:

CODE
<script language="Javascript">
<!--
document.getElementById("loading").style.visibility='visible';
//-->
</script>



Java-Script Code um den Layer auszublenden:

CODE
<BODY onLoad="document.getElementById('loading').style.visibility='hidden';">




Dann habe ich unter diesem Code die MySQL Abfrage. Trotzdem wir der Layer
nicht angezeigt. Wieso nicht?

Freue mich über eure Hilfe!
Marco
 
Ich weiss nicht wie Du das im Detail machst, aber hier im
CSS: hidden entfernen
Header: Script entfernen.

Weil das Div wird angezeigt, wenn die Seite noch nicht geladen ist, bis sie geladen wird.

Wieso nicht, vermute der Code im Header wird ausgeführt bevor der Div geladen wird. Meine Lösung behebt dies.
 
Das hört sich für mich schon seltsam an, wozu in einer Datei, dafür ist doch eigentlich das AD da...

Mir scheint aber eher, dass hier das Verständnis von PHP an sich zu fehlen scheint. Wenn nicht ein explizites flush() und ob_flush() erfolgt und diese Ausgabe dann auch nicht beim Browser wirklich ankommt, funktioniert es nicht. Ansonsten müsste eine Lösung gestützt auf AJAX her.


PS: In der EDV hat es sich als sehr sinnig erwiesen, Zeilenumbrüche nur bei einen Absatz einzufügen, nicht nach jeden Satz und erst recht nicht mitten in jedem Satz... Bei meinen momentanen Zoom von 250%, den ich brauche um hier überhaupt was zu lesen, ist das sehr störend...
 
QUOTE Mir scheint aber eher, dass hier das Verständnis von PHP an sich zu fehlen scheint. Wenn nicht ein explizites flush() und ob_flush() erfolgt und diese Ausgabe dann auch nicht beim Browser wirklich ankommt, funktioniert es nicht.

Möchte Widersprechen. output buffering war standardmässig deaktiviert als ich das letzte mal nachgeschaut habe.

Ich würde aber troztdem explizit flushen, da ich auch immer mit einem Output Layer arbeite, d.h. mein eigenes Buffering habe. Ausserdem sieht der Programmierer auch sofort was geht.
 
QUOTE (Alain Aubert @ Di 4.05.2010, 21:55)
QUOTE Mir scheint aber eher, dass hier das Verständnis von PHP an sich zu fehlen scheint. Wenn nicht ein explizites flush() und ob_flush() erfolgt und diese Ausgabe dann auch nicht beim Browser wirklich ankommt, funktioniert es nicht.

Möchte Widersprechen. output buffering war standardmässig deaktiviert als ich das letzte mal nachgeschaut habe.

[...]

Ähm, was möchtest Du hier denn widersprechen? Ich habe nichts anderes behauptet...
Also widersprichst Du nun, dass ein flush() und ob_flush() gesendet werden muss, damit ein direktes Output Buffering erfolgt, oder widersprichst Du, dass PHP erst zum Schluss die Ausgabe an den Webserver sendet in der Standardeinstellung?

Irgendwie verstehe ich nicht Deinen Widerspruch nicht zu meiner Aussage.
 
Widerspreche bezogen auf den Schein fehlenden Verständnisses mit der Begründung das es nicht funktioniert weil der Buffer nicht gesendet wird
wink.gif


QUOTE Also widersprichst Du nun, dass ein flush() und ob_flush() gesendet werden muss, damit ein direktes Output Buffering erfolgt, oder widersprichst Du, dass PHP erst zum Schluss die Ausgabe an den Webserver sendet in der Standardeinstellung?

Beides. Ersteres i.d.R. und zweiteres wenn meine Annahme bzgl. Std (noch) stimmt.

Aber back to the point

QUOTE Trotzdem wir der Layer nicht angezeigt. Wieso nicht?

Wird das Layer nicht angezeigt oder wird nichts angezeigt?
 
QUOTE (Alain Aubert @ Mi 5.05.2010, 01:26) Widerspreche bezogen auf den Schein fehlenden Verständnisses mit der Begründung das es nicht funktioniert weil der Buffer nicht gesendet wird
wink.gif
[...]

<delete>Ok, ich merke gerade, dass ich vermutlich alten (vllt auch falschen) Wissen aufgesessen bin und nehme das zurück. Ich sollte wohl nach gewissen Dingen einfach nicht mehr vor'm PC sitzen, und meinen alles auseinander halten zu können.</delete>

<edit>
Sorry Alain, aber war wohl eher nun gerade etwas umnebelt, und nicht die geweideten Pupillen wegen dieser Augentropfen waren Schuld. Ich habe gerade zufällig noch folgendes nochmal gelesen:


QUOTE [...]
implicit_flush boolean

FALSE by default. Changing this to TRUE tells PHP to tell the output layer to flush itself automatically after every output block. This is equivalent to calling the PHP function flush() after each and every call to print() or echo() and each and every HTML block.

When using PHP within an web environment, turning this option on has serious performance implications and is generally recommended for debugging purposes only. This value defaults to TRUE when operating under the CLI SAPI.
[...]

Quelle: http://www.php.net/manual/en/outcontrol.configuration.php


Was ja heißt, dass "implicit_flush = Off" heißt, es erfolgt keine sofortige Ausgabe des Output Buffer, diese ist sowohl bei meiner Version "PHP 5.2.6.dfsg.1-1+lenny8" als auch in der produktiven php.ini des aktuellen PHP 5.3.2 Packets abgeschaltet. Daher gehe ich mal davon aus, dass kein direkte Ausgabe erfolgt. Hier nochmal der Text der php.ini:

CODE ; Implicit flush tells PHP to tell the output layer to flush itself
; automatically after every output block.  This is equivalent to calling the
; PHP function flush() after each and every call to print() or echo() and each
; and every HTML block.  Turning this option on has serious performance
; implications and is generally recommended for debugging purposes only.
implicit_flush = Off


Also müsste eigentlich zur Ausgabe des aktuellen Stands ein ob_flush() und flush() erfolgen. Wenn dies nicht so ist, landet erst die gesamte Seite (also der gesamte PHP Output Buffer) sofort zum Webserver, also auch ggf. ohne Verzögerung beim Browser, und genau der führt diese Dinge aus (JavaScript & Co), so dass ggf. kein Effekt sichtbar ist.
wink.gif


http://www.php.net/ob_flush
http://www.php.net/flush

Also bin ich doch nicht so durch den Wind, wie ich gerade meinte.


Getestet habe ich es nun natürlich auch (wieso Opera nicht nach den flushen aufbaut keine Ahnung, Firefox macht es entsprechend, wie erwartet):

CODE <html>
<head><title>test</title></head>
<body>
<pre><?php

echo "Start\n";
ob_flush();
flush();
sleep(5);
echo "Break\n";
sleep(5);
echo "Ende\n";

?></pre>
</body>
</html>


Ein Telnet bestätigt aber das Sendeverhalten.
</edit>

PS: CLI != CGI && CLI != Webserver_Module
 
Hallo zusammen

Nun ich habe das Beispiel von Sascha ausproniert und bei mir funktioniert es nur
im FF aber nicht im IE d.h. dort wird das ganze erst nach dem laden angezeigt.

Verstehe ich das richtig, wenn ich eine Datei mit der Endung .php starte dann
sendet er das alles zuerst zum Webserver um den Code auszuführen und erst
dann wird die Seite geladen?

Aus diesem Grund benutzt man ob_flush(); und flush(); um zuerst eine Ausgabe
zu machen?

Nun nichts desto trotz sollte es auch im IE gehen. Gibt es vielleicht eine andere
Lösung mit AJAX?

Freue mich auf eure Hilfe & Antworten.
Marco
 
Lieber Alain

Danke für Dein Feedback. Leider funktioniert es mit dem entfernen im CSS
und im Header nicht.

Gruss Marco
 
CODE

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style type="text/css">
#loading { position:relative;left:350px;top:200px;z-index:1002; }
</style>
</head>
<body onload="document.getElementById('loading').style.visibility='hidden';">
<h2>Generierte Liste</h2>
Hier vielleicht ein Absatz mit sinnlosem Text...<br />
Noch mehr Text?<br /><br />
<img id="loading" src="/images/loading.gif" alt="Loading" /><!-- Lade-Animation (direkt vor dem langen Query -->
<?php
// hier dein Query mit der anschließenden Ausgabe
sleep(20);
for($i = 1; $i <= 100; $i++) {
echo 'Automatische Liste<br />';
}
?>
</body>
</html>



 
Hi,

ich vermute, es liegt an der HTML-Engine, denn ein Telnet arbeitet sauber, der Ablauf ist eigentlich wie folgt:

PHP Buffer ---> Webserver (Buffer) ---> Browser

PHP buffert grundsätzlich alles und übergibt erst am Ende des Programms die Ausgabe an den Webserver, mit flush() wird dies vorher erzwungen. Dies beinhaltet halt aber nur die Übergabe vom PHP Buffer Richtung Webserver, hat der noch einen Buffer dazwischen, muss man mit einen weiteren Befehl nachhelfen. Leider konnte ich bisher in der Doku noch nicht finden, ob das ob_flush() wirklich ist und ob es nun vor den flush() oder nach den flush() kommen muss, laut Benutzerkommentaren wird es vor den flush() gesetzt.


Ich würde Dir hier wirklich zu AJAX raten, inbesondere wegen der wohl gegebenen Renderproblematik bei den unterschiedlichen Browsern. Ob der Webserver vorher eine Ausgabe macht, sieht man ja bereits mit Firefox, bzw. Telnet. Bleibt so gesehen nur der Client.


PS: @webdokter bitte lasse diese selbst gesetzen Zeilenumbrüche mitten in den Sätzen, siehe den Wink mit den Zaunpfahl weiter oben. Mich nervt es extrem, da ich auch bei normaler Auflösung immer noch diese Stücksätze habe. Anhang anzeigen 2

 
Hallo Heiko

Danke für Dein Code. Bei mir funktioniert das leider nicht. Es wartet einfach 20 Sekunden und zeigt dann den Text an. Dies sowohl in FF auch im IE :-(

@Sascha: Irgendwie bin ich mir das gewohnt mit den Enter-Schlägen. Werde das aber versuchen zu unterlassen.

Marco
 
QUOTE Nun ich habe das Beispiel von Sascha ausproniert und bei mir funktioniert es nur
im FF aber nicht im IE d.h. dort wird das ganze erst nach dem laden angezeigt.

Das beantwortet meine Frage, es wurde nicht der Layer, es wurde nichts angezeigt. Die Antwort ist wichtig - weil unabhängig davon was die Standardeinstellung ist - Du wie Sascha sagt flushen musst. Dann müsstest Du auch bei Heikos Lösung.
Zeig uns bitte mal die ganze Seiten-Struktur. IE hatte in früheren Versionen z.B. Tabellen erst gerendert, wenn sie vollständig geladen waren. Wie das in den neueren Versionen ist, weiss ich zwar nicht, aber Browser könnten nur schon ein Problem damit haben, dass ein Tag nicht geschlossen ist. Das es im FF geht deutet darauf hin, dass es nur Details sein könnten, bis es auch im IE läuft.

@Sascha, Du hast recht, ich hab nur in meine lokalen php.ini nachgeschaut
wink.gif
, und da hab ich es offensichtlich irgendwann mal geändert... Outputbuffering ist zwar std false, aber implicitflush auch...


QUOTE Ich würde Dir hier wirklich zu AJAX raten, inbesondere wegen der wohl gegebenen Renderproblematik bei den unterschiedlichen Browsern

Bin auch dieser Meinung. Begründe es aber stärker mit Modulierbarkeit und Design.

PS:
QUOTE ob_flush...laut Benutzerkommentaren wird es vor den flush() gesetzt.

imho Ja!
 
Zurück
Oben