Silex cant display images as response - php

I can't display any response as image. I have tryed silex method and pure PHP, like this
$file = '1465797900_yoda.png';
if (!file_exists('images/'.$file)) {
return $app->abort(404, 'The image was not found.');
}
$stream = function () use ($file) {
readfile($file);
};
return $app->stream($stream, 200, array('Content-Type' => 'image/png'));
or pure PHP:
$file = 'images/1465797900_yoda.png';
$type = 'image/png';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
echo readfile($file);
If I use method 1 my response is blank image but method 2 return random track, like this:
J���j��?�'T|֢1���Kc�Zu�#��9�G��<��!4#�D�xU�� � á_PW�Fܽ�!rŨ%��Gs�u6�?0�_ �o.>IEND�B`�
Pure PHP dont have problems, only Silex.
Thanks for help.

i have written the following for giving Pics from a folder:
public function getpic( $id ) {
$path = '/assets/userpics/' . $id;
if ( is_file( $path ) ) {
return new BinaryFileResponse( $path );
}
//make some error stuff
}
in the Html where you call the image use or load it via js

Related

SVG from PHP script is not working in img src

I'm trying to open SVG file first in PHP and then return this data:
$file = dirname(__FILE__) . $_GET["file"] . ".svg";
if (!file_exists($file)) {
$file = dirname(__FILE__) . $_GET["file"] . ".png";
if (!file_exists($file)) {
throw new NotFoundHttpException();
} else
header('Content-Type: image/png');
} else
header('Content-Type: image/svg+xml');
$content = file_get_contents($file);
return $content;
And in HTML:
<img src="script.php?file=someimage">
Problem is that its not showing SVG images in the tag. It works, if I set script.php?file=someimage to the URL string of my browser, but not inside the tag. PNG works fine. If i set just
<img src="someimage.svg">
it also works perfect.
embed and object tags works, but I need img.
UPDATE:
The problem was in Yii2, I send headers wrong way. In some reason it works for PNG, but not for SVG.
It should be done like that:
Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
Yii::$app->response->headers->add('Content-Type', 'image/svg+xml');
Looks like you forgot the /. Try replacing these lines where appropriate:
$file = dirname(__FILE__) . '/' . $_GET["file"] . ".svg";
// ...
$file = dirname(__FILE__) '/' . $_GET["file"] . ".png";
dirname() gives back a string without a trailing slash, so it was trying to open /path/to/scriptdirsomefile.svg.
Security
Also, I noticed that your script can be made to do bad things, such as exposing arbitrary files on the server. You can prevent a lot of exploits by doing some basic sanitizing of $_GET['file'] before starting:
$_GET['file'] = preg_replace('#/#', '_', $_GET['file']);
Change return $content; to echo $content;
So if the image files are on the same directory, it will be:
<?php
$file = $_GET["file"] . ".svg";
if (!file_exists($file)) {
$file = $_GET["file"] . ".png";
if (!file_exists($file)) {
throw new NotFoundHttpException();
} else
header('Content-Type: image/png');
} else
header('Content-Type: image/svg+xml');
$content = file_get_contents($file);
echo $content;
?>
Working example #1 (showing svg):
http://www.createchhk.com/SOanswers/subc/index.php
Working example #2 (showing png):
http://www.createchhk.com/SOanswers/subc/index2.php

How to make a safe file function in PHP?

This method receives a foldername and filename. It should make sure that the filename actually really exists in the folder path before doing anything. If so then it can proceed to get the file, send headers and send the response content. Is there a better and more secure way to to do this?
public function is_file_in_path($filename, $filepath)
{
if (file_exists($filepath)) {
$filename = realpath($filepath);
}
if ($filename) {
$image_mime = get_mime_by_extension($filename);
header('Content-Type: ' . $image_mime);
header('Content-Length: ' . filesize($filename));
echo file_get_contents($filename);
} else {
show_error('No image found.', 404);
}
}
To make the function to have higher compatibility and cleaner:
consider removing the word "public"
remove the 1st parameter, which is a bit redundant
change get_mime_by_extension to mime_content_type
change "No image found" to "No File found" (because this function can also be used if you supply a PDF file as parameter).
<?php
function is_file_in_path($filepath)
{
if (file_exists($filepath)) {
$filename = realpath($filepath);
}
if ($filename) {
$file_mime = mime_content_type($filename);
header('Content-Type: ' . $file_mime);
header('Content-Length: ' . filesize($filename));
echo file_get_contents($filename);
} else {
// show_error('No image found.', 404);
echo "No File Found";
}}
// is_file_in_path("./photo.jpg");
is_file_in_path("./ess.pdf");
?>

PHP get image from server

I am trying to display an image from a PHP server.
Here it is my function:
function get_file($path) {
$fileToGet = $GLOBALS['homedir'].$path;
//echo $fileToGet.PHP_EOL;
if (file_exists($fileToGet)) {
//echo 'file exists';
header('Content-Type: image/png');
header('Content-Length: '.filesize($fileToGet));
echo file_get_contents($file);
}
}
I am using the browser or postman and the image is invalid.
What I am missing?
I edited a little bit your function:
function get_file( $path ){
$fileToGet = $GLOBALS['homedir'];
if( substr( $fileToGet, -1) != '/' ){
// add trailing slash if needed
$fileToGet .= '/';
}
$fileToGet .= $path;
if (file_exists($fileToGet)) {
header('Content-Type: image/png');
header('Content-Length: '.filesize($fileToGet));
echo file_get_contents($fileToGet);
}
}
Just a security hint: if $path comes from the user there may be a problem because he will be able to access to some other file.
Think about this code:
get_file( $_GET['path'] );
then the user can call this url
yoursite/yourpage.php?path=../../../mypreciousimage.png
You're not outputting the contents of the file you're reading:
file_get_contents($file);
You'll need to echo it:
echo file_get_contents($file);
Or:
readfile($file);
You'll probably also want to add exit; to the end of that function, to ensure that no other code runs and that no other output gets sent.
Try
print file_get_contents($file);
Instead of
file_get_contents($file);

View Image via controller function with absolue Path Yii1

I want to View Original Image when i click on thubnail image in gridview.
$file = 'http://localhost/myapp/upload/item_original/'.$model->image;
$type = 'image/jpg';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
readfile($file);
i tried above code and it didn't work.
then i tried easyimage extension.
public function actionViewImg($id){
$model = $this->loadModel($id);
Yii::import('application.extensions.easyimage.EasyImage');
$image = new Image('http://localhost/obhre/upload/item_original/1235.jpg'); //get the image
$image->save('upload/viewimg/1235.jpg');//save it to another folder
echo Yii::app()->easyImage->thumbOf('upload/viewimg/1235.jpg'); //view the image
}
above code is working if i put relative path.but not with the absolute path.
error is "Dont have a image"
This code should work:
public function actionViewImg($id)
{
$model = $this->loadModel($id);
$file = 'http://localhost/myapp/upload/item_original/'.$model->image;
header('Content-Type: image/jpg');
header('Content-Length: '.filesize($file));
echo file_get_contents($file);
exit;
}

Issues when downloading file from Slim Framework

I want to download file through Slim Framework (The reason why I'm using Slim Framework is because I want to write a simple REST API). I found this post:
Download file from Slim Framework 2.4 and this post: http://help.slimframework.com/discussions/questions/359-file-download. I followed the method. Here is my code:
$app->get('/download/:id', 'authenticate', function($id) use ($app)
{
$log = '../download/'.$id.'/myfile.zip';
$res = $app->response()->headers();
$res['Content-Description'] = 'File Transfer';
$res['Content-Type'] = 'application/octet-stream';
$res['Content-Disposition'] ='attachment; filename=' . basename($log);
$res['Content-Transfer-Encoding'] = 'binary';
$res['Expires'] = '0';
$res['Cache-Control'] = 'must-revalidate';
$res['Pragma'] = 'public';
$res['Content-Length'] = filesize($log);
readfile($log);
// NOTE:
// $response = array();
// $response["error"] = false;
// echoRespnse(200, $response);
});
I'm using the Google Chrome's Advanced Rest Client application to test. The problem is the browser hung after the file downloaded.If I comments out the NOTE part in my source code, the browser won't hang again. But I got a "Unexpected token P" error.
Can anybody help? Thanks.
Try the solution here: PHP readfile() adding extra bytes to downloaded file.
You lack the calls to ob_clean, flush and exit.
The problem might be becasue of extra characters output with the rest of the file contents.
For Slim 3, I had a bit of struggle.
I struggled with this in Slim 3.0.
I was trying something like the following and the pdf binary was getting displayed on the screen.
$header['Content-Description'] = 'File Transfer';
$header['Content-Disposition'] = 'attachment; filename="' .basename("$file") . '"';
// ...
$response = $response->withHeader($header);
In order to make it work, you need to set the key/value pairs using $response->withHeader(). And it works like a charm. For example:
$response = $response->withHeader('Content-Type', 'application/pdf');
$response = $response->withHeader('Content-Description', 'File Transfer');
$response = $response->withHeader('Content-Disposition', 'attachment; filename="' .basename("$file") . '"');
$response = $response->withHeader('Content-Transfer-Encoding', 'binary');
$response = $response->withHeader('Expires', '0');
$response = $response->withHeader('Cache-Control', 'must-revalidate');
$response = $response->withHeader('Pragma', 'public');
$response = $response->withHeader('Content-Length', filesize($file));
maybe it's a little late but you can use this package for slim http file response :
https://github.com/mhndev/slim-file-response
Is the solution above working for you? Here's my code, which just outputs obscure characters directly into the browser window:
$app->get('/file/:fileid', function($fileid) use ($app)
{
$zip = new ZipArchive();
$zipname = "zipfile3.zip"; // Zip name
$zip->open($zipname, ZipArchive::CREATE);
$files = array ( "sprecher_inserts_en_VB.doc" );
foreach ($files as $file) {
$path = "uploads/".$file;
if(file_exists($path)){
$zip->addFromString(basename($path), file_get_contents($path));
}
else{
echo"file does not exist";
}
}
$zip->close();
// after that, the zip file is on the server and valid when downloaded manually (e.g. by entering its URL directly)
$res = $app->response()->headers();
$res['Content-Description'] = 'File Transfer';
$res['Content-Type'] = 'application/octet-stream';
$res['Content-Disposition'] ='attachment; filename=' . basename($zipname);
$res['Content-Transfer-Encoding'] = 'binary';
$res['Expires'] = '0';
$res['Cache-Control'] = 'must-revalidate';
$res['Pragma'] = 'public';
$res['Content-Length'] = filesize($zipname);
ob_clean();
flush();
readfile($zipname);
exit();
});
The output in the browser window is the following, no dialog for downloading the file is loaded whatsoever:

Categories