Как вы десериализуете несколько строк данных с помощью цикла? - PullRequest
0 голосов
/ 21 января 2019

Проблема

У меня есть большой CSV-файл, который я экспортировал из базы данных MySQL.В одном из столбцов файла есть сериализованные строки.Я пытаюсь найти способ:

  1. Отменить сериализацию каждой строки (которая находится в отдельной ячейке) столбца
  2. Вывести ее таким образом, чтобы текст находился вформат, подобный следующему:
    array (
  'weight' => '108 lbs', 'ah' => '24"', 'sw' => '50"', 'sdw' => '23"', 'shw' => '18"', 'sd' => '27"', 'sh' => '12"',
)

Вот пример несериализованных строк (их около 1000):

    a:7:{s:6:"weight";s:6:"30 lbs";s:2:"ah";s:3:"26"";s:2:"sw";s:3:"20"";s:3:"sdw";s:0:"";s:3:"shw";s:3:"19"";s:2:"sd";s:3:"19"";s:2:"sh";s:3:"17"";}

    a:7:{s:6:"weight";s:7:"107 lbs";s:2:"ah";s:3:"26"";s:2:"sw";s:3:"72"";s:3:"sdw";s:3:"23"";s:3:"shw";s:3:"18"";s:2:"sd";s:3:"27"";s:2:"sh";s:3:"12"";}

    a:7:{s:6:"weight";s:6:"37 lbs";s:2:"ah";s:0:"";s:2:"sw";s:0:"";s:3:"sdw";s:0:"";s:3:"shw";s:0:"";s:2:"sd";s:0:"";s:2:"sh";s:0:"";}

    a:7:{s:6:"weight";s:6:"66 lbs";s:2:"ah";s:3:"26"";s:2:"sw";s:3:"50"";s:3:"sdw";s:3:"23"";s:3:"shw";s:3:"18"";s:2:"sd";s:3:"27"";s:2:"sh";s:3:"12"";}

    a:7:{s:6:"weight";s:6:"30 lbs";s:2:"ah";s:0:"";s:2:"sw";s:3:"26"";s:3:"sdw";s:0:"";s:3:"shw";s:3:"18"";s:2:"sd";s:3:"39"";s:2:"sh";s:3:"12"";}

Вопросы

  1. Можно ли выполнить циклическое преобразование в сериализованные данные, затем десериализовать их и отобразить в нужном формате (например, в формате HTML table)?

Примечание: хотя это сериализованоданные взяты из базы данных MySQL, если возможно, я бы предпочел не подключаться к базе данных, чтобы снова получить эти сериализованные данные.

Попытки решения

Пока что у меня есть:

  1. Просмотр документации php http://php.net/manual/en/function.unserialize.php
  2. Просмотр примеров кода по переполнению стека
  3. Используетсяинструменты, подобные этому http://unserialize.onlinephpfunctions.com/, чтобы увидеть, как использовать эту функцию
  4. Попытался реализовать свой собственный код (см. ниже)

После прочтения темы / проблемы,Я знаю, что мне, вероятно, нужно использовать:

  1. Цикл (для циклического просмотра сериализованных данных)
  2. var_export или var_dump для отображения содержимого в нужном формате

Пример кода

Вот код, который я использовал для получения вышеуказанного результата:

    <?php 

  $var1='a:7{s:6:"weight";s:7:"105lbs";s:2:"ah";s:3:"23"";s:2:"sw";s:3:"26"";s:3:"sdw";s:0:"";s:3:"shw";s:3:"17"";s:2:"sd";s:3:"80"";s:2:"sh";s:3:"12"";}';
    $var2='a:7:{s:6:"weight";s:7:"108 lbs";s:2:"ah";s:3:"24"";s:2:"sw";s:3:"50"";s:3:"sdw";s:3:"23"";s:3:"shw";s:3:"18"";s:2:"sd";s:3:"27"";s:2:"sh";s:3:"12"";}';

    $combined = unserialize($var2);
    $combined2 = unserialize($var1);

    print_r($combined);
    print_r($combined2);

    ?>

Хотя я не получаю желаемый результат, я могучтобы некоторые не сериализованные данные появлялись на экране:

    Array ( [weight] => 108 lbs [ah] => 24" [sw] => 50" [sdw] => 23" [shw] => 18" [sd] => 27" [sh] => 12" ) Array ( [weight] => 105 lbs [ah] => 23" [sw] => 26" [sdw] => [shw] => 17" [sd] => 80" [sh] => 12" )

Это прогресс, но он проблематичен, поскольку не является циклом (был введен вручную) и в нем отсутствует разметка HTML для более удобного форматирования в дальнейшем.

Любое понимание этого будет с благодарностью.Заранее спасибо!


ОБНОВЛЕНИЕ 1

Попытки решения

Я создал временный файл CSV только с одним столбцом и 10 строками.Смотрите CSV-файл здесь .

Я пытался использовать общий код @geoffry, но, похоже, он не извлекает какую-либо информацию из моего CSV-файла.Я получал бесконечный цикл (в консоли показывалось 1000 тегов <tr> (но без содержимого из файла csv).

После наведения в правильном направлении с помощью fgetscsv, я нашелкод ниже. С помощью этого кода я могу получить столбцы на странице в их сериализованной форме, так что я точно знаю, что файл открывается правильно, но этот цикл пропускает этап десериализации, что здесь более важно.

<?php

$filename = "myfilename.csv"; 

$id = fopen($filename, "r"); 
while ($data = fgetcsv($id, filesize($filename))) 
$table[] = $data; 
fclose($id);

echo "<table>\n";

foreach($table as $row)
{
echo "<tr>";
    foreach($row as $data)
    echo "<td>$data</td>";
echo "</tr>\n";
}

echo "</table>\n";

?>

Я безуспешно пытался объединить аспекты этого кода и кода @geoffrey ниже (например, добавив в цикл код unserialize).

Вопросы:

  1. Я прочитал в комментариях руководство PHP fgetscsv , что если вы пользователь Mac (которым я являюсь), вам нужно добавить auto_detect_line_endings в свойЯ попробовал это и не заметил никакой разницы. Может ли это быть частью проблемы?
  2. Расположение fclose($fp); в коде @geoffrey и в том, который я вставил выше, различаются. Пробовал использовать его в разных строках / областях моегоКод / цикл без удачи.Является ли это причиной того, что я не вижу ничего, когда использую unserialized в своем коде?
  3. Что-то, чего мне не хватает?

Еще раз спасибо за понимание.Очень признателен!

ОБНОВЛЕНИЕ 2

Мне удалось десериализовать сериализованные данные с помощью вспомогательной функции под названием maybe_unserialize.Хотя я не смог перебрать весь код, это был шаг в правильном направлении, и я смог получить несериализованный массив с использованием PHP.

Пример кода

<?php 

$original = array(
    'a:7:{s:6:"weight";s:7:"149 lbs";s:2:"ah";s:3:"24"";s:2:"sw";s:3:"75"";s:3:"sdw";s:3:"23"";s:3:"shw";s:3:"18"";s:2:"sd";s:3:"27"";s:2:"sh";s:3:"12"";}'
);

$string = implode(", ", $original);
$done = maybe_unserialize($string);
var_export($done);

 ?>

Надеюсь, этопомогите кому-нибудь еще с подобной проблемой!

1 Ответ

0 голосов
/ 22 января 2019

Поскольку вы имеете дело с CSV, я предполагаю, что вы захотите прочитать в файле и перебрать каждую строку, где данные, которые вы хотите десериализовать, находятся в столбце 5. Я также предполагаю, что желаемый формат вывода HTML, этоследует попытаться помочь вам в этом.

<table>
<?PHP
  $fp = fopen('file.csv', 'r');
  while(($row = fgetcsv($fp)) !== false)
  {
    echo "<tr>";
    $data = unserialize($row[5]);
    foreach($data as $name => $value)
    {
      echo "<td>" . htmlspecialchars($name ) . "</td>";
      echo "<td>" . htmlspecialchars($value) . "</td>";
    }
    echo "</tr>";
  }
  fclose($fp);
?>
</table>

Возможно, вы захотите проверить документацию по fgetcsv, так как вам может потребоваться указать дополнительные аргументы в зависимости от формата CSV.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...