1

I have written a script that gives you ability to download the file with my maximum file speed that I allow, however when I allow 'unlimited' speed like 10000kB/s then the ftell works strange, it behaves like it downloads with 10000kBps speed, which is not true and I can not make calculations in database like time remaining, current download speed and so on...

So browser downloads file after some time, but in database it is already like 'downloaded', how could I make some precision calculations even I set the unlimited speed so user can download a file at the speed of the network and the database values are also counted by his network speed not by the ftell(); which depends on $download_rate; ...?

Thanks in advance!

<?php
    while(!feof($fopen)) {
      //echo fread($fopen, 4096);
        $this->get_allowed_speed_limit($download_rate);
      //$download_rate = 350;
        print fread($fopen, round($download_rate * 1024));

        sleep(1); //needed for download speed limit
        if(connection_status() != 0 || connection_aborted()) {
            $bytes_transferred = ftell($fopen);
            if($bytes_transferred < $bytes) { 
            //CANCELLED
                $this->download_unsuccessfull($file_name);
            } else {
            //CANCELLED (but gets executed only on strange networks like eduroam in CZE)
                $this->download_unsuccessfull($file_name);}
            flush();
            die;
        } else {
            $progress = ftell($fopen) / $bytes * 100;
            if($progress >= 100) {
            //DONE
                $this->download_successfull($file_name);
                flush();
            } else {
            //DOWNLOADING
                if(ftell($fopen) != 0) {
                    $bytes_transferred = ftell($fopen);
                    $time_end = microtime(true);
                    $time = $time_end - $time_start;
                    $dl_speed = floor(($bytes_transferred / $time) / 1000);
                    ///////HERE THE CALCULATIONS ARE TOTALLY WRONG, BECAUSE IT ALL DEPENDS ON THE INPUT OF $download_rate;
                    mysqli_query($con, "UPDATE `download_meter` SET `current_speed` = '".mysqli_real_escape_string($con, $bytes_transferred)."'");

                    $this->update_active_downloads($file_name, $bytes_transferred, $dl_speed);
                }   
              flush();
            }   
        }
            //Activate this for delay download.
            //flush();
            //sleep(1);
    }
?>
Wiggler Jtag
  • 669
  • 8
  • 23
  • I don't think the server can know the client's download speed. Maybe in the webserver, but not in PHP. Maybe check on the client with JS? – Rudie Aug 31 '13 at 12:22
  • How do fileshare servers then offer files to the client with speed limit? – Wiggler Jtag Aug 31 '13 at 16:58
  • You want to LIMIT the download speed? That shouldn't be hard. I thought you want to measure it. And you're really comparing your extensive PHP skills with a professional file sharing SERVER? Yes, they can do that. – Rudie Aug 31 '13 at 17:08
  • Well I want to LIMIT and MEASURE the speed, my php skills are not that bad, but I did not find anything simmilar on the net. Using webserver nginx under debian wheezy. – Wiggler Jtag Aug 31 '13 at 17:12
  • [How to get file download speed (transfer rate) with php?](https://stackoverflow.com/q/36527152/6521116) – LF00 Oct 24 '17 at 05:25

2 Answers2

1

Limiting download speed is up to your webserver. PHP is too high level. It knows nothing of the outgoing data.

The same goes for measuring: the webserver will know and might tell you somehow. Logs, unix socket, after-the-fact, I don't know. Those links will know.

Community
  • 1
  • 1
Rudie
  • 52,220
  • 42
  • 131
  • 173
  • Nginx is my choice, thanks, but how can I limit speed on the go? I wanted to do it via php because I wanted to write a robot that will adjust maximum download speed when its possible and optimize it with more simultaneous clients. – Wiggler Jtag Aug 31 '13 at 17:14
  • Maybe Nginx can do runtime change..? Probably not **during** download, but for every request differently. Whatever solution, it will be very webserver centered. – Rudie Aug 31 '13 at 17:15
  • And the next thing is: I can limit it via php, but I would like to trace it how many bytes were transferred, calculate estimated download time and play with database, which php lets me to do it fine if I knew the way. – Wiggler Jtag Aug 31 '13 at 17:16
  • Direct download feedback to PHP while downloading... No, I don't think so. Only PHP can do the database thing. Only Nginx can do the speed limit thing. You could write an Nginx module that talks to a UNIX socket that talks to PHP... – Rudie Aug 31 '13 at 17:17
  • Yes, that is possible, but there comes an idea in my head, php does not have any library to trace the http status? some PECL package or so, how does the server serve file then and knows when to stop sending it? – Wiggler Jtag Aug 31 '13 at 17:22
  • Even if you could have the webserver tell you when it's done, you'll only now when it's completely done. Nginx does have very useful 'onExit' hooks though, that you can use in PHP, which means you can detect when PHP was done SENDING all data. It doesn't mean that's when the last data was sent to the client. When to stop sending and what (Keep-Alive ftw!) is up to the webserver, not PHP. – Rudie Aug 31 '13 at 17:34
0

How about (re)adding that sleep(1); thing to the WHILE loop? From what I can see the script outputs the file almost all at once (as fast as it can) and there's nothing that pauses it so it can actually limit the download speed.

That way you will know that each second you send just 64kbytes (or whatever) and even though you can't be sure that the user can in fact recieve this much data/second (whoa, so fast!), it could be a bit more precise than what you have in there now.

Or am I getting this wrong?

Smuuf
  • 6,339
  • 3
  • 23
  • 35
  • Thanks for your reply! Doesnt look like it works, started downloading at 1000kBps it was fine, then modified speed on the go to 10000kBps and it showed like 50% of the file was downloaded, while in reality only 20 mb of 100 was downloaded, which tells me my calculations are wrong to client browsers details :/ – Wiggler Jtag Aug 31 '13 at 08:57
  • I am trying to set $download_rate to like 10mbps, but user's connection is just like 1mbps, so I dont want to get wrong calculations, would like to recalculate somehow clients download speed and set the limit for him, but I am unable to recalculate this, since it depends on $download_rate which I've set, humm... Jo ty jsi taky cech ^^ – Wiggler Jtag Aug 31 '13 at 08:59
  • So it's mainly from the other side of the download limit, you say. Well that's a tough one. I can't think of any way how to get to the actual download speed, from the user's point, 'cause the PHP is like .. server-side. I'll definitely try to dig something up. – Smuuf Aug 31 '13 at 09:03