2010-02-10 3 views
11

나는 CSV 파일을 받아들이고 모든 행을 배열로 읽어들이는 간단한 스크립트를 가지고있다. 그런 다음 첫 번째 행의 각 열을 순환합니다 (내 경우에는 설문 조사의 질문을 보유하고 있습니다). 설문 조사는 프랑스어로 이루어지며 질문의 첫 번째 문자가 특수 문자 (é, ê, ç 등) 일 때마다 fgetcsv는 간단히 생략합니다.fgetcsv()는 행의 시작 부분에있을 때 특수 문자를 무시합니다!

값의 중간에있는 특수 문자는 첫 문자 일 때만 영향을받지 않습니다.

나는 이것을 디버깅하려했지만 당황 스럽다. 나는 파일의 내용을 가진 위해서 var_dump를하고 문자가 확실히있다 :

var_dump(utf8_encode(file_get_contents($_FILES['csv_file']['tmp_name']))); 

그리고 여기 내 코드입니다 :

if(file_exists($_FILES['csv_file']['tmp_name']) && $csv = fopen($_FILES['csv_file']['tmp_name'], "r")) 
    { 
     $csv_arr = array(); 

     //Populate an array with all the cells of the CSV file 
     while(!feof($csv)) 
     { 
      $csv_arr[] = fgetcsv($csv); 
     } 

     //Close the file, no longer needed 
     fclose($csv); 

     // This should cycle through the cells of the first row (questions) 
     foreach($csv_arr[0] as $question) 
     { 
      echo utf8_encode($question) . "<br />"; 
     } 

    } 
+3

평범한 ASCII를 사용하는 경우 fgetcsv()는 바이너리 만 안전합니다. 즉, 전혀 그렇지 않습니다. http://stackoverflow.com/questions/3637770/why-fgetcsv-drops-some-characters-with-diacritics- 기본적으로 fgets()를 사용하여 데이터를 읽은 다음 맞춤 함수를 사용하여 CSV를 구문 분석합니다. 분명히이 또한 작동합니다 : http://stackoverflow.com/questions/1472886/some-characters-in-csv-file-are-not-read-during-php-fgetcsv – Piskvor

답변

1

가 이미 manual page on fgetcsv을 체크 아웃 적이 있습니까? 그 구체적인 문제에 관해 이야기하는 것은 아무것도 없지만, 여기에 아무 것도 나타나지 않는 한 많은 도움이 필요할 것입니다.

예를 들어이있다 :

주 : 로케일 설정은이 기능에 의해 고려됩니다. LANG이 예인 경우 en_US.UTF-8,이 함수는 1 바이트 인코딩의 파일을 잘못 읽습니다.

또한 항상 줄의 시작으로 볼 때 숨겨진 줄 바꿈 문제 일 수 있습니까? 이있다 :

참고 : 매킨토시 컴퓨터 중 하나 또는 생성 된 파일을 읽을 때 PHP가 제대로 문제를 해결하는 데 도움이 될 수 auto_detect_line_endings는 런타임 구성 옵션을 사용, 라인 엔딩을 인식되지 않습니다.

다른 줄 끝이있는 파일을 저장해볼 수도 있습니다.

+0

사용 방법에 대한 설명서 페이지를 읽었습니다. 주석 영역을 통한 기능 및 빠른 검색은 특수 문자 또는 utf-8 인코딩을 위해 어떤 것도 팝업하지 않았습니다. 내가 UTF-8 인코딩에 문제가있을 수 있다는 것을 알아 차렸지만 값을 인코딩하지 않으면 값이 여전히 표시되지 않습니다. 이 문제를 해결할 다른 방법이 있을지 모르겠습니다. "|" 라인 구분자의 끝으로 동일한 문제가 발생합니다. 이것은 매우 혼란 스럽습니다. – Gazillion

8

fgetcsv()으로 전화하기 전에 로케일을 올바르게 설정하고 있습니까?

setlocale(LC_ALL, 'fr_FR.UTF-8'); 

그렇지 않은 경우 fgetcsv()은 멀티 바이트 안전하지 않습니다.

사용 가능한 로케일 목록에 나타나는 항목으로 설정했는지 확인하십시오. (확실히 데비안에) 리눅스에서 당신은 UTF8 지원에 대한

C 
en_US.utf8 
POSIX 

가 끝 UTF8로 인코딩을 선택 ... 당신은 뭔가를 얻어야한다

locale -a 

을 수행하여이 문제를 볼 수 있습니다. 입력이 다른 것으로 인코딩 된 경우 적절한 로케일을 사용해야하지만 OS가 먼저 지원하는지 확인하십시오.

로캘을 시스템에서 사용할 수없는 로캘로 설정하면 도움이되지 않습니다.

+0

미안하지만 내가 무지한 것처럼 보일 때면 무엇이 mb-safe입니까? 스크립트의 동작에 아무런 영향을 미치지 않는 선을 추가했습니다. 설명서에 PHP 4.3.5 (PHP 5가 설치되어 있기 때문에) 기능이 바이너리 안전이라고 나와 있습니다. – Gazillion

+2

멀티 바이트 안전 = 단일 문자가 둘 이상의 바이트 (예 : UTF-8)로 구성 될 수있는 인코딩을 처리 할 수 ​​있습니다. . –

+0

아 감사합니다! 나는 거기에 떠날거야 :) – Gazillion

2

이 동작에는 bug report이 있지만 분명히 isn't a bug이 있습니다.

+0

이것은 버그가 아니며 기능입니다. 이 농담이어야합니다. – molli

1

LANGC으로 설정하여 동일한 결과를 얻었으며 이러한 값이 큰 따옴표로 묶여 있는지 확인하여 해결했습니다. 예를 들어, 라인

a,"a",é,"é",óú,"óú",ó&ú,"ó&ú" 

를 들어 fgetcsv()를 통과 할 때 다음과 같은 배열을 생성 : 물론

array (
    0 => 'a', 
    1 => 'a', 
    2 => '', 
    3 => 'é', 
    4 => '', 
    5 => 'óú', 
    6 => '&ú', 
    7 => 'ó&ú', 
) 

, 당신은 그들을 두 배로하여 가치의 인용 부호를 이스케이프해야합니다,하지만 많은입니다 누락 된 문자를 복구하는 것보다 번거롭지 않습니다.

이상하게도 입력 파일에 대한 UTF-8 및 cp1252 인코딩이 모두 발생합니다.

관련 문제