2010-03-22 2 views
30

Когда я использую fputcsv, чтобы выписать строку дескриптору открытого файла, PHP добавит окружающий символ в любой столбец, который, по его мнению, нуждается в нем, но оставит другие столбцы без корпуса.Принудительное использование fputcsv для использования Enclosure For * all * Fields

Например, вы могли бы в конечном итоге с линией, как этот

11,"Bob ",Jenkins,"200 main st. USA ",etc 

доходя присоединяя поддельный пространства к концу каждого поля, есть ли способ заставить fputcsv всегда заключать столбцы с приложением (по умолчанию используется «) характер?

+0

Просто интересно, так как я думаю, что вы вопрос был: повторно в 'Magento/Varien_Io_File :: streamWriteCsv()' (который в конечном счете просто использует 'fputcsv'), сделал вы когда-нибудь находите хорошее решение для этого? Возможно, используется 'Varien_File_Csv'? – pspahn

+0

@pspahn Никогда не делал (и это было четыре года назад, но я не думаю, что это было связано конкретно с Magento) –

ответ

25

нет, fputcsv() только закрывает поле при следующих условиях

/* enclose a field that contains a delimiter, an enclosure character, or a newline */ 
if (FPUTCSV_FLD_CHK(delimiter) || 
    FPUTCSV_FLD_CHK(enclosure) || 
    FPUTCSV_FLD_CHK(escape_char) || 
    FPUTCSV_FLD_CHK('\n') || 
    FPUTCSV_FLD_CHK('\r') || 
    FPUTCSV_FLD_CHK('\t') || 
    FPUTCSV_FLD_CHK(' ') 
) 

Там нет "всегда прилагаю" вариант.

+2

грустно, потому что fgetcsv терпит неудачу с Österreich без двойных кавычек! – nalply

+9

VolkerK, конечно, совершенно верно. fputcsv не может помочь вам с этой проблемой (у меня такая же проблема). Позвольте мне помочь вам начать прыжок в следующем поиске, который вы будете делать: [http://stackoverflow.com/questions/3933668/convert-array-into-csv](http://stackoverflow.com/questions/3933668/convert-array-in-csv) – ftrotter

14

Недовольны этим решением, но это то, что я сделал и работал. Идея состоит в том, чтобы установить пустой символ как символ оболочки на fputcsv и добавить некоторые кавычки на каждый элемент вашего массива.

function encodeFunc($value) { 
    return "\"$value\""; 
} 

fputcsv($handler, array_map(encodeFunc, $array), ',', chr(0)); 
+2

В том числе chr (0) в файле вызывает проблемы в некоторых сценариях импорта, если файл UTF-8 –

+0

csv содержит^@, если вы используете chr (0) – Mike

+1

Вы можете избавиться от нулей (chr (0)) в результирующем файле, отфильтровывая их после завершения вывода вашего csv: 'file_put_contents ($ file, str_replace (chr (0), '', file_get_contents ($ file))); '. Кроме того, ваш 'encodeFunc' должен будет также избегать двойных кавычек, если ваши значения имеют их. См. Мою версию [здесь] (https://gist.github.com/anonymous/223ea7353626bc6a6a9e#file-csvenclosed-php). Помимо этого, похоже, это работает, просто имейте в виду, что это взломать. – Mahn

2

После много scrafffing вокруг и некоторые довольно утомительно проверка характера, у меня есть версия упоминаемых выше кодов по Diego и Mahn, что будет правильно раздеть encasings и заменить двойные кавычки на всех полях в fputcsv. а затем вывести файл в браузер для загрузки.

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

В частности, при выводе непосредственно в браузер с использованием потока ввода php: //, на который ссылается Диего. Chr(127) является символом пробела, поэтому файл CSV имеет несколько пробелов, чем в противном случае, но я считаю, что это оборачивает проблему chr(0) NULL символов в UTF-8.

/*** 
* @param $value array 
* @return string array values enclosed in quotes every time. 
*/ 
function encodeFunc($value) { 
    ///remove any ESCAPED double quotes within string. 
    $value = str_replace('\\"','"',$value); 
    //then force escape these same double quotes And Any UNESCAPED Ones. 
    $value = str_replace('"','\"',$value); 
    //force wrap value in quotes and return 
    return '"'.$value.'"'; 
} 


$result = $array_Set_Of_DataBase_Results; 
$fp = fopen('php://output', 'w'); 
if ($fp && $result) { 
    header('Content-Type: text/csv'); 
    header('Content-Disposition: attachment; filename="export-'.date("d-m-Y").'.csv"'); 
    foreach($result as $row) { 
     fputcsv($fp, array_map("encodeFunc", $row), ',', chr(127)); 
    } 
    unset($result,$row); 
    die; 
} 

Надеюсь, это полезно для некоторых.

6

Опираясь на ответ Martin «s, если вы хотите, чтобы избежать введения каких-либо символов, которые не вытекают из исходного массива (Chr(127), Chr(0) и т.д.), вы можете заменить строку fputcsv() со следующим вместо:

fputs($fp, implode(",", array_map("encodeFunc", $row))."\r\n"); 

Предоставлено, fputs() работает медленнее, чем fputcsv(), но это более чистый выход. Полный код таким образом:

/*** 
* @param $value array 
* @return string array values enclosed in quotes every time. 
*/ 
function encodeFunc($value) { 
    ///remove any ESCAPED double quotes within string. 
    $value = str_replace('\\"','"',$value); 
    //then force escape these same double quotes And Any UNESCAPED Ones. 
    $value = str_replace('"','\"',$value); 
    //force wrap value in quotes and return 
    return '"'.$value.'"'; 
} 

$fp = fopen("filename.csv", 'w'); 
foreach($table as $row){ 
    fputs($fp, implode(",", array_map("encodeFunc", $row))."\r\n"); 
} 
fclose($fp); 
+0

Я действительно нашел после публикации этого ответа, что с 'fputcsv', что функция действительно довольно хромает и использует стандартные функции * write-to-file *, так как вы также выполнили сортировку моего кода и обошли все проблемы с согласованностью CSV в платформ и программ. – Martin

+0

Благодарим вас за хороший пример. Мне нужно было всегда включать все значения в кавычки. И мне нужно было заставить концы строк CR + LF вместо LF. Этот пример решает обе проблемы. –