The php filesize() method is used to determine the size of a file in bytes. One example would be to determine the size of an image file. If the method gets its data from an images metadata, is it possible this could be spoofed by modifying the image metadata somehow, or does the method actually calculate file size based on the true contents of the image file?
<?php filesize(); ?>
The function filesize
Returns the size of the file in bytes, or FALSE (and generates an error of level E_WARNING) in case of an error.
http://php.net/manual/en/function.filesize.php
It does not in any way try to interpret image metadata.
Related
I'm using GD to create jpegs from files that a user uploads.
What is the best way to validate that the image the user has uploaded is valid?
By valid I mean that the file is not a corrupt image that GD won't like, I do extension testing client side so they can only upload jpegs/gifs/pngs.
Thanks
You could use getimagesize. It will return FALSE if the image could not be loaded. It has support for most image types.
getImageSize would be your best choice but, be careful, if the file results are not valid you will get a warning. Using # before built in imagesize function will be ideal.
I really can't understand why GD has different function for loading images such like:
imagecreatefromjpeg()
imagecreatefrompng()
imagecreatefromgif()
While there is a single function if the image is string?
imagecreatefromstring()
Indeed it's much better to read the image into the string and pass it to the function, something like:
$imgBlob = file_get_contents($imagePath);
imagecreatefromstring($imageBlob);
unset($imgBlob); //> Free memory, but I am not interested in memory consumpation
? Or I am missing something ? This could led to potential confusion for new users
Maybe they just forgot to create a function imageCreateFromFile()?
Ps. Of course I am not interested about memory consumation using the file_get_contents method
imagecreatefromstring() runs a switch against the passed image type, checks if your system has support for that image type, and then actually runs the correct imagecreatefrom* function.
You can check out the source code to see this: https://github.com/php/php-src/blob/master/ext/gd/gd.c?source=cc (line 2280 for the function, line 2301 where it switches on the image type and calls the correct function).
So, the imagecreatefromstring() function is really just a helper wrapper. You'll get a very slight benefit from not running _php_image_type (line 2217) if you call the actual image type function.
imagecreatefromjpeg()
imagecreatefrompng()
imagecreatefromgif()
create image resource from a file - you pass file path as parameter and that's the only acceptable input.
imagecreatefromstring()
creates image resource from string, not file - it could be virtually anything, you can even type in a content. For example you can use
imagecreatefromstring(base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw=='));
to get 1x1 pixel transparent gif (useful for tracking gifs)
Granted, you could pass everything through imagecreatefromstring, but it would not be memory efficient - handling large images takes a lot of memory and with low memory limit that makes a huge difference.
I have moved my images to Rackspace Cloud Files and am using their PHP API. I am trying to do the following:
Get an image from my "originals" container
Resize it, sharpen it, etc.
Save the resized image to the "thumbs" container
My problem is with #2. I was hoping to resize without having to copy the original to my server first (since the images are large and I'd like to resize dynamically), but can't figure out how. This is what I have so far (not much):
$container = $conn->get_container("originals");
$obj = $container->get_object("example.jpg");
$img = $obj->read();
Part of the problem is I don't fully understand what is being returned by the read() function. I know $img contains the object's "data" (which I was able to print out as gibberish), but it is neither a file nor a url nor an image resource, so I don't know how to deal with it. Is it possible to convert $img into an image resource somehow? I tried imagecreatefromjpeg($img) but that didn't work.
Thanks!
First, you cannot resize an image without loading it into memory. Unless the remote server offers some "resize my image for me, here are the parameters" API, you have to load the image in your script to manipulate it. So you'll have to copy the file from the CloudFiles container to your server, manipulate it, then send it back into storage.
The data you receive from $obj->read() is the image data. That is the file. It doesn't have a file name and it's not saved on the hard disk, but it is the entire file. To load this into gd to manipulate it, you can use imagecreatefromstring. That's analogous to using, for example, imagecreatefrompng, only that imagecreatefrompng wants to read a file from the file system by itself, while imagecreatefromstring just accepts the data that you have already loaded into memory.
You can try to dump the content of the $img variable into a writable file as per the below:
<?php
$filename = 'modifiedImage.jpg';
/*
* 'w+' Open for reading and writing; place the file pointer at the beginning of the file and truncate
* the file to zero length. If the file does not exist, attempt to create it.
*/
$handle = fopen($filename, 'w+');
// Write $img to the opened\created file.
if (fwrite($handle, $img) === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
echo "Success, wrote to file ($filename)";
fclose($handle);
?>
More details:
http://www.php.net/manual/en/function.fopen.php
http://www.php.net/manual/en/function.fwrite.php
Edit:
You might also want to double check the type of data returned by the read() function, because if the data is not a jpg image, if it's for example a png, the extension of the file needs to be changed accordingly.
I'm creating an image editor in JS/PHP, but now I'm having trouble. First of all, I load the image from the database (load a blob with imagecreatefromstring). Then I apply a list of actions to this image. But how can I get the image size from this image handler I have then? Without writing it to a file or use a stream object. How??
In case you mean the image dimensions:
$width = imagesx($imgHandle);
$height = imagesy($imgHandle);
See imagesx() and imagesy().
If you mean filesize, that's not possible without converting the GD resource to some image format (GIF, PNG, JPEG) because the format determines the image size in bytes.
I doubt you can since php gd image object is a generic object, without considerations on the compression that will be used for storage (png/jpg/bmp ...)
Is there any way to get size of POST-request body in PHP?
As simple as:
$size = (int) $_SERVER['CONTENT_LENGTH'];
Note that $_SERVER['CONTENT_LENGTH'] is only set when the HTTP request method is POST (not GET). This is the raw value of the Content-Length header, as specified in RFC 7230.
In the case of file uploads, if you want to get the total size of uploaded files, you should iterate over the $_FILE array to sum each $file['size']. The exact total size might not match the raw Content-Length value due to the encoding overhead of the POST data. (Also note you should check for upload errors using the $file['error'] code of each $_FILES element, such as UPLOAD_ERR_PARTIAL for partial uploads or UPLOAD_ERR_NO_FILE for empty uploads. See file upload errors documentation in the PHP manual.)
If you're trying to figure out whether or not a file upload failed, you should be using the PHP file error handling as shown at the link below. This is the most reliable way to detect file upload errors:
http://us3.php.net/manual/en/features.file-upload.errors.php
If you need the size of a POST request without any file uploads, you should be able to do so with something like this:
$request = http_build_query($_POST);
$size = strlen($request);
My guess is, it's in the $_SERVER['CONTENT_LENGTH'].
And if you need that for error detection, peek into $_FILES['filename']['error'].
This might work :
$bytesInPostRequestBody = strlen(file_get_contents('php://input'));
// This does not count the bytes of the request's headers on its body.
I guess you are looking for $HTTP_RAW_POST_DATA