Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

168
Vistas
php web site displays file instead of downloading

I am running a php 8 website on linux web app service in Azure. When the user presses a button I want to create a file on the fly (read data from db) and download it. Instead it is displaying contents on the page. Here is the code

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename=geodata.csv");
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize("geodata.csv"));

$file = fopen('php://output', 'w') 
            or die ("Unable to create file in write mode");
if (ob_get_contents()) ob_end_clean();
    fputcsv($output, array('name','loc','zip'), chr(6));
    $mrows = mysqli_query($myconnection, "SELECT name,loc,zip FROM geo_tbl WHERE sp = 'FL'");
    while ($mrow = mysqli_fetch_assoc($mrows)) {
        fputcsv($file, $mrow, chr(6));
    }
    fclose($file);
    readfile("geodata.csv");
    exit();

Thanks

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

I see several issues with the code:

  1. As Alan as already pointed out, you have duplicate Content-Type headers. If you are saving the file as an attachment, you can really use either one.

  2. You issue your die message after you have already set the Content-Type header for a csv file so the message would not be displayed correctly. You should therefore do the fopen statement before setting the content header.

  3. You are sending part of your output to variable $output instead of $file with the statement fputcsv($output, array('name','loc','zip'), chr(6)); and that variable does not seem to be defined.

  4. You are setting a Content-Length header with header('Content-Length: ' . filesize("geodata.csv")); but at this point you have no idea what the content length is.

  5. You should put double-quotes around your filename in the Content-Disposition header.

Although not errors, per se, you are retrieving the rows with fetch_assoc so $mrow will contain keys and values. You really only need to be using fetch_row. I also question your use of chr(6), which is an ACK character, as a column delimiter. Did you possibly mean chr(9), a TAB?

I believe the following is all you need:

<?php

//define (DELIMITER, chr(9)); // Shouldn't it be this?
define (DELIMITER, chr(6));

if (ob_get_contents()) {
    ob_end_clean();
}
$file = fopen('php://output', 'w') or die ("Unable to create file in write mode");

header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="geodata.csv"');
header('Pragma: no-cache');
header('Expires: 0');

fputcsv($file, array('name','loc','zip'), DELIMITER);
$mrows = mysqli_query($myconnection, "SELECT name,loc,zip FROM geo_tbl WHERE sp = 'FL'");
while ($mrow = mysqli_fetch_row($mrows)) {
    fputcsv($file, $mrow, DELIMITER);
}
fclose($file);
over 4 years ago · Santiago Trujillo Denunciar

0

When the user presses a button

Simply add the download attribute to your button, it should work straight away.

<a href="link/to/your/file.csv" download="filename.csv">Download link</a>

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download

over 4 years ago · Santiago Trujillo Denunciar

0

As others have said, there are several issues with your code.

But if you just remove the second content-type header and keep it as application/octet-stream, this should force a download.

However, your content-length will not be reported correctly. Perhaps read the contents into a variable, then take the length of that string as the content-length header.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda