I wrote this code to download an image from instagram. the image downloaded but it have some errors. that's mean I can download the image but I cant open it
<?php
$linktopage = 'http://instagram.com/p/jTh1cBHG36/';
$sourcecode = file_get_contents( $linktopage );
$sourcecode = substr($sourcecode , strpos($sourcecode, 'og:image') + 19, strlen($sourcecode));
$sourcecode = substr($sourcecode , 0 , strpos($sourcecode, '"'));
$name= substr($sourcecode , strpos($sourcecode, 'com/') + 4, strlen($sourcecode));
$fileToSend = $sourcecode;
header('Content-type: image/jpeg');
header('Content-Disposition: attachment; filename='.$name.'"');
header("Content-Length: ". file_size($fileToSend));
readfile($fileToSend);
?>
Comment the Content-Length line and it will work fine:
//header("Content-Length: ". file_size($fileToSend));
The correct function name is filesize (and I'm not sure if it will work on your URL).
I also see that you are missing a quote after filename=. It should be:
header('Content-Disposition: attachment; filename="'.$name.'"');
So, the working version of your code will be:
$linktopage = 'http://instagram.com/p/jTh1cBHG36/';
$sourcecode = file_get_contents( $linktopage );
$sourcecode = substr($sourcecode , strpos($sourcecode, 'og:image') + 19, strlen($sourcecode));
$sourcecode = substr($sourcecode , 0 , strpos($sourcecode, '"'));
$name= substr($sourcecode , strpos($sourcecode, 'com/') + 4, strlen($sourcecode));
$fileToSend = $sourcecode;
header('Content-type: image/jpeg');
header('Content-Disposition: attachment; filename="'.$name.'"');
//header("Content-Length: ". filesize($fileToSend));
readfile($fileToSend);
The problem is happening because of a typo error.
Typo error was in the following line:
header('Content-Disposition: attachment; filename='.$name.'"');
Due to the wrong name format '_' was getting added to the file extension.
One more addition in the code is for content length which is 2 line only:
$head = array_change_key_case(get_headers($sourcecode, TRUE));
$filesize = $head['content-length'];
Final Working code with typo error fixed:
<?php
$linktopage = 'http://instagram.com/p/jTh1cBHG36/';
$sourcecode = file_get_contents( $linktopage );
$sourcecode = substr($sourcecode , strpos($sourcecode, 'og:image') + 19, strlen($sourcecode));
$sourcecode = substr($sourcecode , 0 , strpos($sourcecode, '"'));
$name= substr($sourcecode , strpos($sourcecode, 'com/') + 4, strlen($sourcecode));
$fileToSend = $sourcecode;
$head = array_change_key_case(get_headers($sourcecode, TRUE));
$filesize = $head['content-length'];
header("Content-type: image/jpeg");
header("Content-Disposition: attachment; filename=".$name);
header("Content-Length: ". $filesize);
readfile($fileToSend);
?>
Related
This question already has answers here:
How to save a PNG image server-side, from a base64 data URI
(17 answers)
Closed 3 years ago.
I am trying to convert my base64 image string to an image file. This is my Base64 string:
http://pastebin.com/ENkTrGNG
Using following code to convert it into an image file:
function base64_to_jpeg( $base64_string, $output_file ) {
$ifp = fopen( $output_file, "wb" );
fwrite( $ifp, base64_decode( $base64_string) );
fclose( $ifp );
return( $output_file );
}
$image = base64_to_jpeg( $my_base64_string, 'tmp.jpg' );
But I am getting an error of invalid image, whats wrong here?
The problem is that data:image/png;base64, is included in the encoded contents. This will result in invalid image data when the base64 function decodes it. Remove that data in the function before decoding the string, like so.
function base64_to_jpeg($base64_string, $output_file) {
// open the output file for writing
$ifp = fopen( $output_file, 'wb' );
// split the string on commas
// $data[ 0 ] == "data:image/png;base64"
// $data[ 1 ] == <actual base64 string>
$data = explode( ',', $base64_string );
// we could add validation here with ensuring count( $data ) > 1
fwrite( $ifp, base64_decode( $data[ 1 ] ) );
// clean up the file resource
fclose( $ifp );
return $output_file;
}
An easy way I'm using:
file_put_contents($output_file, file_get_contents($base64_string));
This works well because file_get_contents can read data from a URI, including a data:// URI.
You need to remove the part that says data:image/png;base64, at the beginning of the image data. The actual base64 data comes after that.
Just strip everything up to and including base64, (before calling base64_decode() on the data) and you'll be fine.
maybe like this
function save_base64_image($base64_image_string, $output_file_without_extension, $path_with_end_slash="" ) {
//usage: if( substr( $img_src, 0, 5 ) === "data:" ) { $filename=save_base64_image($base64_image_string, $output_file_without_extentnion, getcwd() . "/application/assets/pins/$user_id/"); }
//
//data is like: data:image/png;base64,asdfasdfasdf
$splited = explode(',', substr( $base64_image_string , 5 ) , 2);
$mime=$splited[0];
$data=$splited[1];
$mime_split_without_base64=explode(';', $mime,2);
$mime_split=explode('/', $mime_split_without_base64[0],2);
if(count($mime_split)==2)
{
$extension=$mime_split[1];
if($extension=='jpeg')$extension='jpg';
//if($extension=='javascript')$extension='js';
//if($extension=='text')$extension='txt';
$output_file_with_extension=$output_file_without_extension.'.'.$extension;
}
file_put_contents( $path_with_end_slash . $output_file_with_extension, base64_decode($data) );
return $output_file_with_extension;
}
That's an old thread, but in case you want to upload the image having same extension-
$image = $request->image;
$imageInfo = explode(";base64,", $image);
$imgExt = str_replace('data:image/', '', $imageInfo[0]);
$image = str_replace(' ', '+', $imageInfo[1]);
$imageName = "post-".time().".".$imgExt;
Storage::disk('public_feeds')->put($imageName, base64_decode($image));
You can create 'public_feeds' in laravel's filesystem.php-
'public_feeds' => [
'driver' => 'local',
'root' => public_path() . '/uploads/feeds',
],
if($_SERVER['REQUEST_METHOD']=='POST'){
$image_no="5";//or Anything You Need
$image = $_POST['image'];
$path = "uploads/".$image_no.".png";
$status = file_put_contents($path,base64_decode($image));
if($status){
echo "Successfully Uploaded";
}else{
echo "Upload failed";
}
}
This code worked for me.
<?php
$decoded = base64_decode($base64);
$file = 'invoice.pdf';
file_put_contents($file, $decoded);
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
$datetime = date("Y-m-d h:i:s");
$timestamp = strtotime($datetime);
$image = $_POST['image'];
$imgdata = base64_decode($image);
$f = finfo_open();
$mime_type = finfo_buffer($f, $imgdata, FILEINFO_MIME_TYPE);
$temp=explode('/',$mime_type);
$path = "uploads/$timestamp.$temp[1]";
file_put_contents($path,base64_decode($image));
echo "Successfully Uploaded->>> $timestamp.$temp[1]";
This will be enough for image processing. Special thanks to Mr. Dev Karan Sharma
I am using PHPExcel to generate a spreadsheet.
If I generate and download at the same time, everything is fine.
But when I save to a MediumBlob in my MySQL and then download it, MSExcel says it is not ok.
I am using the same headers in both situations.
Gera is the function that generates the file:
$agora=date("Y-m-d H:i:s");
$relatorio_rh_xls=$dbHandle->real_escape_string(RelatorioBaseRH::Gera($ciclo,$dbHandle));
$qry="insert into tb_relatorio_rh (id_avaliacao_ciclo,relatorio_base_RH_xls,inicio_vigencia,fim_vigencia) values ( $ciclo,'".$relatorio_rh_xls."','".$agora."',null)";
$result4=$dbHandle->query($qry);
And then to retrieve it:
$query = "SELECT $nomeRelatorio, OCTET_LENGTH($nomeRelatorio) as tamanho " .
"FROM tb_relatorio_rh WHERE id_avaliacao_ciclo = '$id_avaliacao_ciclo' and fim_vigencia is null order by inicio_vigencia desc";
$resultadoConsulta= $dbHandle->query($query);
$qtdeLinhas=$resultadoConsulta->num_rows;
if ($qtdeLinhas>0) {
$fetBuscaRelatorio = $resultadoConsulta->fetch_assoc();
$relatorio=$fetBuscaRelatorio[$nomeRelatorio];
$size=$fetBuscaRelatorio['tamanho'];
$type= substr($nomeRelatorio, -3, 3);
if ($type == "xls"){ $type="xlsx";}
$nomeAvaliado= str_replace(' ','_',$nomeAvaliado);
$nomeDownload=substr($nomeRelatorio, 0, strlen($nomeRelatorio)-4) .'_' . $nomeAvaliado .'.'. $type;
header("Content-Length: $size");
header("Content-Type: $type");
header("Content-Disposition: attachment; filename=$nomeDownload");
print $relatorio;
}
The problem was with another php file I was including with include_once(anotherfile.php).
That anotherfile.php had blank lines after ?> closing tag.
I have written the following script which is to create a CSV file based on content from a Database. The script itself works perfectly and creates the CSV file and populates it as expected. The problem is that when the file downloads automatically it is empty, but when downloading it from the hosting server over FTP it is filled with the information.
Is the file just downloading too soon before the file is successfully written? Is there anything that can be done to fix this issue?
<?php
// Establish the MySQL Database Connection
include_once("./include/database.php");
include("functions.php");
$filename = 'devices.csv';
$headers = array('ID', 'Device', 'Name', 'Type', 'Scope', 'OS', 'Datacenter');
$handle = fopen($filename, 'w');
fputcsv($handle, $headers, ',', '"');
$sql = mysql_query("SELECT * FROM devices ORDER BY name ASC", $dp_conn);
while($results = mysql_fetch_object($sql))
{
$type = getDeviceType($results->type, $dp_conn);
$scope = getDeviceScope($results->scope, $dp_conn);
$os = getOS($results->os, $dp_conn);
$datacenter = getDatacenter($results->datacenter, $dp_conn);
$row = array(
$results->id,
$results->device_id,
$results->name,
$type,
$scope['name'],
$os,
$datacenter
);
fputcsv($handle, $row, ',', '"');
}
// rewind the "file" with the csv lines
fseek($handle, 0);
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
// make php send the generated csv lines to the browser
fpassthru($handle);
fclose($handle);
?>
After further testing and finding a similar post on the topic, I have found a fix. Rather than using fopen() on a file, I wrote the data to memory and it is now working correctly.
<?php
// Establish the MySQL Database Connection
include_once("./include/database.php");
include("functions.php");
$filename = 'devices.csv';
$headers = array('ID', 'Device', 'Name', 'Type', 'Scope', 'OS', 'Datacenter');
//$handle = fopen($filename, 'w');
$handle = fopen('php://memory', 'w');
fputcsv($handle, $headers, ',', '"');
$sql = mysql_query("SELECT * FROM devices ORDER BY name ASC", $dp_conn);
while($results = mysql_fetch_object($sql))
{
$type = getDeviceType($results->type, $dp_conn);
$scope = getDeviceScope($results->scope, $dp_conn);
$os = getOS($results->os, $dp_conn);
$datacenter = getDatacenter($results->datacenter, $dp_conn);
$row = array(
$results->id,
$results->device_id,
$results->name,
$type,
$scope['name'],
$os,
$datacenter
);
fputcsv($handle, $row, ',', '"');
}
// rewind the "file" with the csv lines
fseek($handle, 0);
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
// make php send the generated csv lines to the browser
fpassthru($handle);
fclose($handle);
?>
try putting this
// Establish the MySQL Database Connection
include_once("./include/database.php");
include("functions.php");
ob_start(); //start output buffering
$filename = 'devices.csv';
$headers = array('ID', 'Device', 'Name', 'Type', 'Scope', 'OS', 'Datacenter');
$handle = fopen($filename, 'w');
fputcsv($handle, $headers, ',', '"');
$sql = mysql_query("SELECT * FROM devices ORDER BY name ASC", $dp_conn);
while($results = mysql_fetch_object($sql))
{
$type = getDeviceType($results->type, $dp_conn);
$scope = getDeviceScope($results->scope, $dp_conn);
$os = getOS($results->os, $dp_conn);
$datacenter = getDatacenter($results->datacenter, $dp_conn);
$row = array(
$results->id,
$results->device_id,
$results->name,
$type,
$scope['name'],
$os,
$datacenter
);
fputcsv($handle, $row, ',', '"');
}
ob_end_clean(); //ending output buffering.
// rewind the "file" with the csv lines
fseek($handle, 0);
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
// make php send the generated csv lines to the browser
fpassthru($handle);
fclose($handle);
sorry if this is not a new question but i'm really stuck in this problem. I'm using script below for downloading a large file like a movie, I can not let user to access direct link of the file, also I need to let user download the file in a resume and section support manner. Using this code I just have resume support, not section. I'm using Yii framework.
Please Help me on this by any solution and suggestion.
public static function downloadFile($fileLocation, $saveName = null, $maxSpeed = 100, $doStream = false){
$start = 0;
$end = -1;
$section = false;
$extension = CFileHelper::getExtension($fileLocation);
$fileName = is_null($saveName) ? basename($fileLocation) : $saveName . '.' . $extension;
/* #var $contentType string mime type for the file, if is null, it will be octet-stream */
$contentType = CFileHelper::getMimeType($fileLocation);
$contentType = is_null($contentType) ? 'application/octet-stream' : $contentType;
if(isset($_SERVER['HTTP_RANGE']))
{
$range2 = substr($_SERVER['HTTP_RANGE'], strlen('bytes='));
$range = explode('-', $range2);
if($range[0] > 0)
$start = intval($range[0]);
if($range[1] > 0)
$end = intval($range[1]);
$section = true;
}
ob_end_clean();
$old_status = ignore_user_abort(true);
set_time_limit(0);
$size = filesize($fileLocation);
if($start > ($size -1)) $start = 0;
$fp = fopen($fileLocation, 'rb');
if($start) fseek($fp, $start);
if($end < $start) $end = $size -1;
header('Content-Type: '.$contentType);
$contentDisposition = 'attachment';
if($doStream == true){
$array_listen = array('mp3','m3u','m4a','mid','ogg','ra','ram','wm',
'wav','wma','aac','3gp','avi','mov','mp4','mpeg','mpg','swf','wmv','divx','asf');
if(in_array($extension,$array_listen)){
$contentDisposition = 'inline';
}
}
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) {
$fileName= preg_replace('/\./', '%2e', $fileName, substr_count($fileName, '.') - 1);
header("Content-Disposition: $contentDisposition; filename=\"$fileName\"");
} else {
header("Content-Disposition: $contentDisposition; filename=\"$fileName\"");
}
header('Content-Disposition: ' . $contentDisposition . '; filename="' . $fileName . '"');
header('Last-Modified: ' . date('D, d M Y H:i:s \G\M\T', filemtime($fileLocation)));
if($section)
{
header("HTTP/1.0 206 Partial Content");
header("Status: 206 Partial Content");
header('Accept-Ranges: bytes');
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: " . ($end - $start + 1));
}else
header('Content-Length: '.$size);
$size = $end - $start + 1;
while(!(connection_aborted() || connection_status() == 1) && !feof($fp))
{
print(fread($fp,1024*$maxSpeed));
flush();
ob_flush();
sleep(1);
}
fclose($fp);
ignore_user_abort($old_status);
set_time_limit(ini_get('max_execution_time'));
}
If you are using apache and able to install mods to it, you can use mod_xsendfile module. It supports partial downloads, cashing and other cool things.
Simple demo: Send Files Faster & Better with PHP & X-Sendfile
Is there any Zend Helper that can make PDF document with tables.
i need to pass result of my Query and the helper will return a PDF document with data in a table.
Just like the below Csv Helper.
what i did here is that i put the given class in
Zend/Controller/Action/Helper
and than in my Action i do so
public function getcsvAction() {
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNeverRender();
try{
$clModel = new Application_Model_DbTable_Mytable();
$select = $clModel->clCSV());
$this->_helper->Csv($select, "genertadfile name");
}catch(Exception $e){
echo 'Oops! Something went wrong.';
}
exit;
}
and this the class
<?php
// Zend_Controller_Action_Helper_Csv
class Zend_Controller_Action_Helper_Csv extends Zend_Controller_Action_Helper_Abstract{
public function direct($aryData = array(), $strName = "csv", $bolCols = true){
$this->printExcel($aryData, $strName, $bolCols);
}
public function printExcel($aryData = array(), $strName = "csv", $bolCols = true){
if (!is_array($aryData) || empty($aryData)){ exit(1); }
// header
header('Content-Description: File Transfer');
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename=" . $strName . "-export.csv");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-control: private, must-revalidate');
header("Pragma: public");
if ($bolCols){
$aryCols = array_keys($aryData[0]);
array_unshift($aryData, $aryCols);
}
ob_start();
$fp = fopen("php://output", "w");
if (is_resource($fp)){
foreach ($aryData as $aryLine) {
fputcsv($fp, $aryLine, ',', '"');
}
$strContent = ob_get_clean();
$strContent = preg_replace('/^ID/', 'id', $strContent);
$strContent = utf8_decode($strContent);
$intLength = mb_strlen($strContent, 'utf-8');
header('Content-Length: ' . $intLength);
echo $strContent;
exit(0);
}
ob_end_clean();
exit(1);
}
}
?>
There is a official module for pdf on zend framework 2: zendpdf
You can install it by adding zendframework/zendpdf to your composer.json file.
Its not finnished yet, that why you can't find any information about it. You can find here the previous documentation... just look for zend.pdf.*.rst files.
There is a ZF2 module for the DOMPDF library too. Find more info here. The code you can finde here. Easy installation by adding "dino/dompdf-module": "dev-master" to your composer.json file.
ADDING:
DOMPDF can be used like this:
public function dompdfAction()
{
return new DOMPDFModule\View\Model\PdfModel\PdfModel(
array(), // Variable assignments per Zend\View\Model\ViewModel
array(
'fileName' => 'monthly-report', // Optional; triggers PDF download, automatically appends ".pdf"
'paperSize' => 'a4',
'paperOrientation' => 'landscape'
)
);
}
It will generate an pdf file for the dompdfAction's viewscript.
ZendPdf can be used like this:
public function pdfAction()
{
$pdf = new \ZendPdf\PdfDocument();
$pdf->pages[] = ($page = $pdf->newPage(\ZendPdf\Page::SIZE_A4));
$font = \ZendPdf\Font::fontWithName(\ZendPdf\Font::FONT_HELVETICA);
$page->setFont($font, 36);
$page->drawText('<h1>html não funciona...</h1>', 10, 536, 'utf-8');
$page->drawText('PDF FUNCIONA', 10, 500, 'utf-8');
$image = \ZendPdf\Image::imageWithPath('public/images/zf2-logo.png');
$page->drawImage($image, 100, 100, 400, 300);
$pdf->save("teste.pdf");
}