Why is my Content-Length header wrong?

24,034

Solution 1

You are telling the user agent to expect strlen($data) and then actually sending $header."\n".$data! Try something like this at the end of your code...

  $output=$header."\n".$data;

  // create table header showing to download a xls (excel) file
  header("Content-type: application/octet-stream");
  header("Content-Disposition: attachment; filename=$export_filename");
  header("Cache-Control: public");
  header("Content-length: " . strlen($output); // tells file size
  header("Pragma: no-cache");
  header("Expires: 0");

  // output data
  echo $output;

Solution 2

The content-length header does NOT include the length of the headers plus the body of the response.

Content-Length: The length of the response body in octets (8-bit bytes)

Just FYI since the variables used in the "answer" are header + data. Do not be misled.

Solution 3

strlen returns the correct answer:

echo strlen("1\n2\t3");

// prints 5

You will need to examine your input more carefully.

Solution 4

You echo both $header and $data, but you only set Content-Length to the size of $data.

If $header contains additional HTTP-headers, you should output $header using header(). Otherwise, you should set Content-Length to strlen($header."\n".$data).

Solution 5

Before getting length of string, delete '\t' and '\n' symbols from $data with str_replace or with other function like that if strlen() really has bug (I haven't checked that).

Share:
24,034
kobra
Author by

kobra

Updated on May 25, 2020

Comments

  • kobra
    kobra almost 4 years

    I am trying to find out the exact length of a string using strlen() in php 5.2. The string ($data) contains '\t' and '\n'.

    echo strlen($data);
    

    Code:

        // fetch table header
          $header = '';
          while ($fieldData = $result->fetch_field()) {
            $header .= $fieldData->name . "\t";
          }
    
          // fetch data each row, store on tabular row data
          while ($row = $result->fetch_assoc()) {
            $line = '';
            foreach($row as $value){
              if(!isset($value) || $value == ""){
                $value = "\t";
              }else{
                // important to escape any quotes to preserve them in the data.
                $value = str_replace('"', '""', $value);
                // needed to encapsulate data in quotes because some data might be multi line.
                // the good news is that numbers remain numbers in Excel even though quoted.
                $value = '"' . $value . '"' . "\t";
              }
    
              $line .= $value;
            }
            $data .= trim($line)."\n";
          }
    
          // this line is needed because returns embedded in the data have "\r"
          // and this looks like a "box character" in Excel
          $data = str_replace("\r", "", $data);
    
          // Nice to let someone know that the search came up empty.
          // Otherwise only the column name headers will be output to Excel.
          if ($data == "") {
            $data = "\nno matching records found\n";
          }
    
          // create table header showing to download a xls (excel) file
          header("Content-type: application/octet-stream");
          header("Content-Disposition: attachment; filename=$export_filename");
          header("Cache-Control: public");
          header("Content-length: " . strlen($data); // tells file size
          header("Pragma: no-cache");
          header("Expires: 0");
    
      // output data
      echo $header."\n".$data;
    

    This does not return the exact length (its less than the actual length). Please advice.