PHP serving image from outside of webroot - php

Today I was working on my website's function.php in an area that had nothing to do with serving images. I have a php script which gets images from outside of the webroot and serves them based on $_GET for the moment. One minute it was working and then the next it was not. I have no idea what happened. I chalked it up to MAC Sierra's BS server management but moving everything to a LINUX server made no difference.
<?php
include('includes/functions.php');
$path = $privatePath;
$uid = getUserProfileImage();
$img = $_GET['img'];
$file = $path."/img/users/".$uid."/".$img;
$fallback = "img/site/login.png";
//DETERMINE TYPE
$var = explode ('.', $img);
$ext = array_pop($var);
$allowed['gif'] = 'image/gif';
$allowed['png'] = 'image/png';
$allowed['jpg'] = 'image/jpeg';
$allowed['jpeg'] = 'image/jpeg';
if(file_exists($file) && $ext != '' && isset($allowed[strToLower($ext)])) {
$type = $allowed[strToLower($ext)];
} else {
$file = $fallback;
$type = 'image/png';
}
header('Content-Type: '.$type);
//header ("Content-Disposition: inline; filename=\"{$img}\");
header("Content-length: ".(string)(filesize($file)));
//echo file_get_contents($file);
readfile($file);
exit();
?>
This code was working just fine a from one min to the next. I have checked the permissions of the folder and verify that it is owned by www-data. Firefox reveals that the image has an error. Usually I had that error message when I was echoing something before the output buffer. But now it is for who knows what reason.
The RAW Data output in Firefox is as such when reading the image:
CgoKCv/Y/+EeQUV4aWYAAElJKgAIAAAADAAAAQMAAQAAAAACAAABAQMAAQAAAAACAAACAQMAAwAAAJ4AAAAGAQMAAQAAAAIAAAASAQMAAQAAAAEAAAAVAQMAAQAAAAMAAAAaAQUAAQAAAKQAAAAbAQUAAQAAAKwAAAAoAQMAAQAAAAIAAAAxAQIAHgA ...
And that goes on for a bit. I have resaved the image and about everything else that I can think of. I have even deleted all work done from prior when the script worked and no change. Anyone got any ideas? Or is there more error that I can log to see the problem and get a hint?

Related

Problem with generating fopen file in imagick

In Imagick I am trying to do the following:
When accessing .php already begins the download of .jpg, I do not even need a preview just the multiple download because this .pdf in question will always have two pages, with that fopen I can download only the first page, for some reason it does not download the second page.
pdf_file = './programming/'.$date.'.pdf';
$mpdf->Output($pdf_file);
$img = new imagick();
$img->setResolution(200,200);
$img->readImage($pdf_file);
$img->setImageUnits(imagick::RESOLUTION_PIXELSPERINCH);
$img->setImageFormat('jpg');
$img->setImageCompressionQuality(85);
$pages = $img->getNumberImages();
if ( $pages ) {
foreach($img as $i => $img_file){
$img_file->writeImage('./programming/('.$i.') '.$date.'.jpg');
$img_path = './programming/('.$i.') '.$date.'.jpg';
header('Content-Type: application/download');
header('Content-Disposition: attachment; filename="('.$i.') '.$date.'.jpg"');
header("Content-Length: " . filesize($img_path));
$fp = fopen($img_path, "rb");
fpassthru($fp);
fclose($fp);
}
} else {
echo '<h2>Not Found.</h2>';
}
$img->clear();
$img->destroy();
If anyone can guide me, I may have missed something!
Thank you in advance for your attention!
Note: The images that represent page 1 and 2 of the .pdf are already saved in ./programming/ folder, the code works well in that case, then the foreach did what I expected, created two images and stored them but only download one with fopen

PHP file_exists and save locally

I'm having a script that checks remote server for a file, and if it is already available locally it should use that one. If it isn't available locally, then download the image to the server. However, I'm struggling with the script overwriting images that I already have locally. If it's already available locally, the script shouldn't do anything with the file - just display it.
In some cases, the script tries to download a image that I already have - and the filesize for the file it overwrites becomes 0kb even though the file worked perfectly earlier.
What am I doing wrong here?
<?php
$url = "http://www.myserver.com/image123.jpg";
$filename = basename($url);
if(!file_exists(images/$filename))
{
// File doesn't exsist, download it!
$image = file_get_contents("$url");
file_put_contents("images/$filename", $image);
$image = "images/$filename";
} else {
// We already got this file, display it!
$image = "images/$filename";
}
echo $image;
?>
<?php
$url = "http://www.myserver.com/image123.jpg";
$filename = basename($url);
$path = "images/$filename";
if( !file_exists($path) ) {
$image = file_get_contents($url);
file_put_contents($path, $image);
}
echo $path;
?>

PHP - Playing video from dynamic directory path - strange error

I am attempting to include an avi video in a webpage. The video is held outside the webroot folder for security and is dynamically loaded using PHP (see full code below).
A sample full path is '/Users/me/project/1/video/test1.avi';
The page is experiencing a strange error. I build the path to the file using the following statement:
$pic = $CFG->dataroot."/".$COURT->id."/".$preview;
//($CFG->dataroot = '/Users/me/project')
//($COURT->id = 1 - a number representing the folder name.)
//($preview = 'video/test1.avi' - or the location of image/video)
This works for images but fails to load the video showing just the video controls and 'loading...'
EDIT: I have echoed $COURT->id and the variable 1 is being passed correctly
If I change the code and directly specify the directory by removing $COURT->id it works for both video and the images.
$pic = $CFG->dataroot."/1/".$preview; //- works
Any ideas why this might be?
Thanks in advance Steve
(I am testing on a Mac using Apache and Safari.)
Full code:
<?php
$preview = $_GET['preview'];
//works with images but not video
//$pic = $CFG->dataroot."/".$COURT->id."/".$preview;
//works but the folder '1' needs to dynamic i.e. var $COURT->id
$pic = $CFG->dataroot."/1/".$preview;
if ( isset($_GET['preview']) ) {
if (file_exists($pic) && is_readable($pic)) {
// get the filename extension
$ext = substr($pic, -3);
// set the MIME type
switch ($ext) {
case 'jpg':
$mime = 'image/jpeg';
break;
case 'gif':
$mime = 'image/gif';
break;
case 'png':
$mime = 'image/png';
break;
case 'avi':
$mime = 'video/avi'; //$mime = 'video/x-msvideo';
break;
case 'doc':
$mime = 'application/msword';
break;
case 'tif':
$mime = 'image/tiff';
break;
default:
$mime = false;
}
// if a valid MIME type exists, display the image
// by sending appropriate headers and streaming the file
if ($mime) {
header('Content-type: '.$mime);
header('Content-length: '.filesize($pic));
$file = # fopen($pic, 'rb');
if ($file) {
fpassthru($file);
exit;
}
}
}
}
Obviously, when images are sent as $preview (on page before where link to preview is), courtid is sent dynamically to next page, and its OK.
But when video is sent as $preview - courtid its not se(n)t.
Why not, we cannot see in these codes, but codes before, ones that triggers this (play) function.
Try to echo courtid on a page where video should play to check out if it is set as 1 and thats it.
I simply cannot find any other logical solution.

Creating ZIP File in PHP coming up with Browser errors, not Script errors

I created a code to backup an entire website & automatically download it on a single click. Here is what my code looks like:
if (file_exists("file.zip")) {
unlink("file.zip");
}
$folder_array = array();
$file_array = array();
function listFolderFiles($dir){
global $folder_array;
global $file_array;
$ffs = scandir($dir);
foreach($ffs as $ff){
if ($ff != '.' && $ff != '..') {
if (is_dir($dir.'/'.$ff)) {
$new_item = "$dir/$ff";
$new_item = str_replace('..//','',$new_item);
if ($new_item !== "stats") {
array_push($folder_array, $new_item);
listFolderFiles($dir.'/'.$ff);
}
}
else {
$new_item = "$dir/$ff";
$new_item = str_replace('..//','',$new_item);
if (($new_item !== "stats/logs") && ($new_item !== "stats/")) {
array_push($file_array, $new_item);
}
}
}
}
}
listFolderFiles('../');
$zip = new ZipArchive;
if ($zip->open('file.zip', true ? ZIPARCHIVE::OVERWRITE:ZIPARCHIVE::CREATE) === TRUE) {
foreach($folder_array as $folder) {
$zip->addEmptyDir($folder);
}
foreach($file_array as $key => $file) {
$file_path = "../$file";
$zip->addFile($file_path, $file);
}
}
$zip->close();
$file = "file.zip";
chmod("$file", 0700);
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=". $file);
readfile($file);
Now this code was working good for awhile, but it seems today it doesn't want to work. The thing is, it's not a PHP script error. I've checked my error logs and nothing is showing up. It appears to be a browser error, but each browser displays a different message:
Chrome says "This webpage is not available"
Firefox says "The connection was reset"
Internet Explorer says "This page can't be displayed"
Even though these errors come up, the ZIP file is still being created and I can download it from the server.
Here is a list of things I've tried after extensive research:
1) I removed the code to have the ZIP file download automatically (all code written after I close the ZIP file). Still get the browser errors.
2) I read that it's possible too many files are getting opened and its going over my limit. I added to the code to close and reopen the ZIP file after every 200 files. Still didn't work.
3) I limited the amount of files to ZIP. Everything was working fine below 500. Between 500 to 1,000 files, the code would work a partial amount of the time. Sometimes it would go through fine, the others it would give me the browser error. After 1,000 or so it just wouldn't work properly at all.
The hosting is through GoDaddy.
PHP Version is 5.2.17
max_execution_time is set at 240 (the code never goes this long, usually only takes about 30 sec to run)
memory_limit is set at 500M (more than twice the size of all the files combined)
I'm at a loss, I really don't know what is going on because this code was working just fine for 1,500 files a few weeks ago. And again, the ZIP file is still being created, there are no PHP errors and it's only the Browsers that are coming back with these errors.
I don't know what's wrong with your code, but I'm using the code below and it has been working forever with me.
function create_zip($path, $save_as)
{
if (!extension_loaded('zip'))
throw new ErrorException('Extension ZIP has not been compiled or loaded in php.');
else if(!file_exists($path))
throw new ErrorException('The file/path you want to zip doesn\'t exist!');
$zip = new ZipArchive();
if (!$zip->open($save_as, ZIPARCHIVE::CREATE))
throw new ErrorException('Could not create zip file!');
$ignore = array('.','..');
if($path == dirname($save_as))
$ignore[] = basename($save_as);
$path = str_replace('\\', '/', realpath($path));
if (is_dir($path)) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
$file = str_replace('\\', '/', $file);
if( in_array(substr($file, strrpos($file, '/')+1),$ignore )) continue;
$file = realpath($file);
if (is_dir($file)) {
$zip->addEmptyDir(str_replace($path . '/', '', $file . '/'));
}
else if (is_file($file)) {
$zip->addFromString(str_replace($path . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($path)) {
$zip->addFromString(basename($path), file_get_contents($path));
}
return $zip->close();
}
$zip = create_zip('/path/to/your/zip/directory', '/path/to/your/save.zip');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename('/path/to/your/save.zip').'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize('/path/to/your/save.zip'));
echo readfile('/path/to/your/save.zip');
instantate an iterator (before creating the zip archive, just in case the zip file is created inside the source folder) and traverse the directory to get the file list.
See More Code At:click me

PHP output image issues

if (file_exists($path)) {
$fileContent = id3_getImage($path);
$fileMime = id3_getMimeOfImage($path); // is set to image/jpeg
if ($fileMime != "") {
header('Content-Type: '.$fileMime);
print($fileContent);
die;
}
}
So the above code does not work in the browser, however when I make a image with image
$img = imagecreatefromstring($fileContent);
imagejpeg($img, 'test.jpg');die;
the image is created and I can view it on my computer. So I have no clue what I am doing wrong :(
*Could it be a setting in the apache conf? I honestly have no clue on this one
header('Content-Type: image/jpeg');
// Output the image
imagejpeg($img);
You need send header before. But if you want to create the image and show, you need create, and read this for the browser.
readfile($filename);
You can read the man here:
http://php.net/manual/en/function.readfile.php
I use smartReadFile.php from Google Groups to display any type of file.
https://jplayer.googlegroups.com/attach/f308294ddea52f6c/smartReadFile.php?view=1&part=4
It's really smart. =)
<?php
require "smartReadFile.php";
$dir = 'images/';
$filename = 'someimage' . '.jpg';
$location = $dir.$filename;
smartReadFile($location, $filename);
?>
This one is working for me when reading from DB
$image = imagecreatefromstring([path/DBfiels]);
header('content-type: image/jpeg');
imagejpeg($image);
imagedestroy($image);

Categories