Почему мой заголовок Content-Length неверен?

Я пытаюсь узнать точную длину строки, используя strlen() в php 5.2. Строка ($data) содержит '\t' и '\n'.

echo strlen($data);

Код:

    // 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;

Это не возвращает точную длину (она меньше фактической длины). Пожалуйста посоветуй.


person kobra    schedule 24.08.2010    source источник
comment
Что такое строка, какова ожидаемая длина и какова фактическая длина, которая отображается?   -  person BoltClock    schedule 25.08.2010
comment
Вы не должны предполагать, что в strlen() есть ошибка. Какова длина, которую вы возвращаете? Чего ты ожидал?   -  person nos    schedule 25.08.2010
comment
Я пытаюсь сохранить данные из таблицы mysql в виде файла Excel. У меня всегда отсутствуют некоторые символы последней записи. Если я делаю header(Content-length: . (strlen($data) + 148)); вместо заголовка (длина содержимого: .strlen ($ data)); Я получаю правильный результат.   -  person kobra    schedule 25.08.2010
comment
@nos Я добавляю \t и \n, поэтому я уверен, что это есть в строке.   -  person kobra    schedule 25.08.2010
comment
была ли эта строка создана с одинарными кавычками, например. '\tfoo\nbar'?   -  person Gordon    schedule 25.08.2010
comment
@kobra: что вы видите на выходе echo strlen($data) и чего вы ожидали?   -  person BoltClock    schedule 25.08.2010
comment
Я не думаю, что strlen сломан. Пожалуйста, покажите весь (соответствующий) код.   -  person mvds    schedule 25.08.2010
comment
Я никоим образом не утверждаю, что strlen не работает. Мне просто нужно решение моей проблемы.   -  person kobra    schedule 25.08.2010
comment
Это не excel, это CSV. но по теме. покажите весь код пожалуйста, сейчас в вашем вопросе нет даже strlen()!   -  person mvds    schedule 25.08.2010
comment
Вы должны установить $data=''; для начала, иначе вы получите хорошее предупреждение в этом CSV (могут ли ваши предупреждения составлять до 148 байт? Вы смотрели на csv?)   -  person mvds    schedule 25.08.2010
comment
например, при сохранении на диск до того, как MS приложила к нему руки? и просматривать с помощью less, notepad, hexdump или другого основного средства просмотра?   -  person mvds    schedule 25.08.2010
comment
И, пожалуйста, наведите порядок, добавьте \t в одном месте, например $line .= $value."\t";   -  person mvds    schedule 25.08.2010
comment
Любая конкретная причина, по которой вы мой вопрос получили -1.   -  person kobra    schedule 25.08.2010


Ответы (5)


Вы говорите пользовательскому агенту ожидать strlen($data), а затем фактически отправляете $header."\n".$data! Попробуйте что-то подобное в конце вашего кода...

  $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;
person Paul Dixon    schedule 25.08.2010

strlen возвращает правильный ответ:

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

// prints 5

Вам нужно будет более внимательно изучить свой ввод.

person webbiedave    schedule 24.08.2010
comment
Я думаю, что когда я сохраняю данные в формате Excel, они переводят \n и \t (непечатаемые символы). Поэтому, если размер вкладки равен 4, приведенное выше должно привести к длине 8. Я думаю, что это проблема. - person kobra; 25.08.2010
comment
@kobra: каждая вкладка всегда состоит из 1 символа. Я не думаю, что Excel когда-либо путается с вашими символами табуляции. - person BoltClock; 25.08.2010
comment
это сработало для меня: header('Content-Length: '.strlen($data)); - person Joeme; 04.07.2017

Заголовок content-length НЕ включает длину заголовков плюс тело ответа.

Content-Length: длина тела ответа в октетах (8-битных байтах).

Просто к вашему сведению, поскольку переменные, используемые в «ответе», представляют собой заголовок + данные. Не вводите в заблуждение.

person mooyah    schedule 13.02.2012
comment
Переменная $header в его примере не является заголовком HTTP. Если, конечно, вы не предупредили нас всех, чтобы мы не думали, что он пытается вывести HTTP-заголовок с данными, в этом случае... здесь не на что смотреть. - person Micke; 06.01.2016

Прежде чем получить длину строки, удалите символы '\t' и '\n' из $data с помощью str_replace или другой подобной функции, если strlen() действительно содержит ошибку (я не проверял).

person good_evening    schedule 24.08.2010
comment
Мне нужны \t и \n в строке. - person kobra; 25.08.2010
comment
str_replace не изменяет исходную строку. - person Casey Chu; 25.08.2010

Вы повторяете как $header, так и $data, но устанавливаете только Content-Length размером $data.

Если $header содержит дополнительные HTTP-заголовки, вы должны вывести $header, используя header(). В противном случае вы должны установить Content-Length на strlen($header."\n".$data).

person Micke    schedule 26.07.2012