0

I am writing an application that can stream videos. It requires the filesize of the video, so I use this code:

$filesize = sprintf("%u", filesize($file));

However, when streaming a six gig movie, it fails.

Is is possible to get a bigger interger value in PHP? I don't care if I have to use third party libraries, if it is slow, all I care about is that it can get the filesize properly.

FYI, $filesize is currently 3017575487 which is really really really really far from 6000000000, which is roughly correct.

I am running PHP on a 64 bit operating system.

Thanks for any suggestions!

asked Aug 2, 2014 at 17:39
13
  • If you're using 64-bit PHP on a 64-bit operating system Commented Aug 2, 2014 at 17:40
  • @MarkBaker Yes I am using a 64 bit operating system. Commented Aug 2, 2014 at 17:42
  • @MarkBaker It says when I run phpinfo that it is using 86x architecture. I am running XAMPP. Commented Aug 2, 2014 at 17:44
  • Check the value of the PHP_INT_MAX or PHP_INT_SIZE constants Commented Aug 2, 2014 at 17:45
  • 1
    Or switch from using xampp (which shouldn't be used in production anyway) to a 64-bit Windows PHP binary.... if this isn't a production system, why worry about "experimental" Commented Aug 2, 2014 at 18:05

2 Answers 2

1

The issue here is two-fold.

Problem 1


The filesize function returns a signed integer, with a maximum value of PHP_INT_MAX. On 32-bit PHP, this value is 2147483647 or about 2GB. On 64-bit PHP can you go higher, up to 9223372036854775807. Based on the comments from the PHP filesize page, I created a function that will use a fseek loop to find the size of the file, and return it as a float, which can count higher that a 32-bit unisgned integer.

function filesize_float($filename)
{
 $f = fopen($filename, 'r');
 $p = 0;
 $b = 1073741824;
 fseek($f, 0, SEEK_SET);
 while($b > 1)
 {
 fseek($f, $b, SEEK_CUR);
 if(fgetc($f) === false)
 {
 fseek($f, -$b, SEEK_CUR);
 $b = (int)($b / 2);
 }
 else
 {
 fseek($f, -1, SEEK_CUR);
 $p += $b;
 }
 }
 while(fgetc($f) !== false)
 {
 ++$p;
 }
 fclose($f);
 return $p;
}

To get the file size of the file as a float using the above function, you would call it like this.

$filesize = filesize_float($file);

Problem 2


Using %u in the sprintf function will cause it to interpret the argument as an unsigned integer, thus limiting the maximum possible value to 4294967295 on 32-bit PHP, before overflowing. Therefore, if we were to do the following, it would return the wrong number.

sprintf("%u", filesize_float($file));

You could interpret the value as a float using %F, using the following, but it will result in trailing decimals.

sprintf("%F", filesize_float($file));

For example, the above will return something like 6442450944.000000, rather than 6442450944.

A workaround would be to have sprintf interpret the float as a string, and let PHP cast the float to a string.

$filesize = sprintf("%s", filesize_float($file));

This will set $filesize to the value of something like 6442450944, without trailing decimals.


The Final Solution


If you add the filesize_float function above to your code, you can simply use the following line of code to read the actual file size into the sprintf statement.

$filesize = sprintf("%s", filesize_float($file));
answered Aug 2, 2014 at 18:24
Sign up to request clarification or add additional context in comments.

2 Comments

I tested it out: The script terminated with a timeout error. Removing the timeout error makes it execute forever: I have tried up to one hour.
@Nathan How strange. Are you sure it is a problem with this code? That is the exact file size you are using it on?
0

As per PHP docuemnation for 64 bit platforms, this seems quite reliable for getting the filesize of files> 4GB

<?php 
$a = fopen($filename, 'r'); 
fseek($a, 0, SEEK_END); 
$filesize = ftell($a); 
fclose($a); 
?>
answered Aug 2, 2014 at 17:51

4 Comments

It returns 0, but thanks for the reply anyway. When you say 64 bit platforms does that include PHP, or just the os?
Its should work can you please check this link php.net/manual/en/function.filesize.php
Nope. However, for files smaller than that it does. Note that though my computer is 64 bit, my PHP version is 32 bit.
ftell() will still return an integer value: if that value falls outside of the 32-bit limit for a signed integer, then it won't work

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.