progressbar bij downloaden

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

De Clercq Andy

De Clercq Andy

02/11/2013 16:35:17
Quote Anchor link
Hallo,
ik downloadde een bestaande class en probeer om deze in te sluiten in een bestand om een pdf te downloaden. Het bestand om te downloaden werkt zonder de class. Maar nu met de class krijg ik de foutmelding "headers already sent by". Ook weet ik dat dit komt omdat er in één van die functies van de class al output komt via de flush().
Maar hoe kan ik dit oplossen of omzeilen?
Het download bestand:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
include('ProgressBar.class.php');
$bar = new ProgressBar();
$elements = 10000;
 $bar->initialize($elements);
  for($i=0;$i<$elements;$i++)
    {

    //doe wat tijd kost, in dit geval downloaden
    $openen='http://www.ucro.be/hulpbestanden/folder.pdf';
    header('Content-type: application/pdf');
    header('Content-Disposition: attachment; filename="downloaded.pdf"');
    readfile($openen);
    $bar->increase();
    
    }

?>

Dit is de class die ik vond
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?php
class ProgressBar {

    /**
     * Constructor
     *
     * @param str $message Message shown above the bar eg. "Please wait...". Default: ''
     * @param bool $hide Hide the bar after completion (with JavaScript).
     * Default: false
     * @param int $sleepOnFinish Seconds to sleep after bar completion. Default: 0
     * @param int $barLength Length in pixels. Default: 200
     * @param int $precision Desired number of steps to show. Default: 20. Precision will become $numElements when greater than $numElements. $barLength will increase if $precision is greater than $barLength.
     * @param str $backgroundColor Color of the bar background
     * @param str $foregroundColor Color of the actual progress-bar
     * @param str $domID Html-Attribute "id" for the bar
     * @param str $stepElement Element the bar is build from
     */

    function ProgressBar($message='', $hide=false, $sleepOnFinish=0, $barLength=200, $precision=20,
                         $backgroundColor='#cccccc', $foregroundColor='blue', $domID='progressbar',
                         $stepElement='<div style="width:%spx;height:20px;float:left;"></div>'
                         ){

        //increase time limit
        if(!ini_get('safe_mode')){
            set_time_limit(0);
        }


        $this->hide = (bool) $hide;
        $this->sleepOnFinish = (int) $sleepOnFinish;
        $this->domID = strip_tags($domID);
        $this->message = $message;
        $this->stepElement = $stepElement;
        $this->barLength = (int) $barLength;
        $this->precision = (int) $precision;
        $this->backgroundColor = strip_tags($backgroundColor);
        $this->foregroundColor = strip_tags($foregroundColor);
        if($this->barLength < $this->precision){
            $this->barLength = $this->precision;
        }


        $this->StepCount = 0;
        $this->CallCount = 0;
    }


    /**
     * Print the empty progress bar
     * @param int $numElements Number of Elements to be processed and number of times $bar->initialize() will be called while processing
     */

    function initialize($numElements)
    {

        $numElements = (int) $numElements ;
        if($numElements == 0){
            $numElements = 1;
        }

        //calculate the number of calls for one step
        $this->CallsPerStep = ceil(($numElements/$this->precision)); // eg. 1000/200 = 100

        //calculate the total number of steps

        if($numElements >= $this->CallsPerStep){
            $this->numSteps = round($numElements/$this->CallsPerStep);
        }
else{
            $this->numSteps = round($numElements);
        }


        //calculate the length of one step
        $stepLength = floor($this->barLength/$this->numSteps);  // eg. 100/10 = 10

        //the rest is the first step

        $this->rest = $this->barLength-($stepLength*$this->numSteps);
        if($this->rest > 0){
            $this->firstStep = sprintf($this->stepElement,$this->rest);
        }


        //build the basic step-element
        $this->oneStep = sprintf($this->stepElement,$stepLength);

        //build bar background
        $backgroundLength = $this->rest+($stepLength*$this->numSteps);
        $this->backgroundBar = sprintf($this->stepElement,$backgroundLength);

        //stop buffering
        ob_end_flush();
        //start buffering
        ob_start();

        echo '<div id="'.$this->domID.'">'.
             $this->message.'<br/>'.
             '<div style="position:absolute;color:'.$this->backgroundColor.';background-color:'.$this->backgroundColor.'">'.$this->backgroundBar.'</div>' .
             '<div style="position:absolute;color:'.$this->foregroundColor.';background-color:'.$this->foregroundColor.'">';

        ob_flush();
        flush();
    }


    /**
     * Count steps and increase bar length
     *
     */

    function increase()
    {

        $this->CallCount++;

        if(!$this->started){
            //rest output
            echo $this->firstStep;
            ob_flush();
            flush();
        }


        if($this->StepCount < $this->numSteps
        &&(!$this->started || $this->CallCount == $this->CallsPerStep)){

            //add a step
            echo $this->oneStep;
            ob_flush();
            flush();

            $this->StepCount++;
            $this->CallCount=0;
        }

        $this->started = true;

        if(!$this->finished && $this->StepCount == $this->numSteps){

            // close the bar
            echo '</div></div><br/>';
            ob_flush();
            flush();

            //sleep x seconds before ending the script
            if($this->sleepOnFinish > 0){
                sleep($this->sleepOnFinish);
            }


            //hide the bar
            if($this->hide){
                echo '<script type="text/javascript">document.getElementById("'.$this->domID.'").style.display = "none";</script>';
                ob_flush();
                flush();
            }

            $this->finished = true;
        }
    }
}

?>
Gewijzigd op 02/11/2013 16:40:01 door De Clercq Andy
 
PHP hulp

PHP hulp

23/11/2024 09:31:54
 
Kris Peeters

Kris Peeters

04/11/2013 16:57:54
Quote Anchor link
Wil jij 10000 keer het zelfde bestand folder.pdf lezen? Waar is dat goed voor?

Een header (het woord zegt het zelf) is een hoofding. 1 hoofding volstaat.
Een header() die binnenin een lus zit ( een while, een for, een do, ... ), kan dus nooit de bedoeling zijn.
 
De Clercq Andy

De Clercq Andy

04/11/2013 18:44:35
Quote Anchor link
Wanneer ik het uit de lus haal krijg ik andere foutmeldingen.
Eigenlijk is het de bedoeling dat ik een pdf kan downloaden en ondertussen mijn bezoeker "bezig" houd.
Die class heb ik gevonden via google maar ik zoek hu hoe ik hem inpas.
Dt heb ik nu:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
include('ProgressBar.class.php');
$bar = new ProgressBar();
$elements = 10000;
 $bar->initialize($elements);
  for($i=0;$i<$elements;$i++)
    {

    //doe wat tijd kost, in dit geval downloaden
    $bar->increase();
    
    }

$openen='http://www.ucro.be/hulpbestanden/folder.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="downloaded.pdf"');
readfile($openen);
?>

Ook totaal andere oplossingen voor mijn probleem zijn welkom.
In ieder geval bedankt!
 
Eddy E

Eddy E

04/11/2013 21:58:01
Quote Anchor link
Doet de browser dit niet gewoon al voor je?

Stuur de browser de PDF, en die toont dan wel een balkje.
Tenslotte weet de browser (realtime) al hoeveel er binnen is en hoeveel er nog komt (door de headers van het bestand...).

Lijkt me veel veiliger, beter en makkelijker dan wat je nu doet.
Daarnaast: balkje-html, balkje-http-request, balkje-plaatje-tonen.... inmiddels is die PDF al lang binnen.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.