2011-07-05 26 views
7

Tôi gặp phải một vấn đề nhỏ khi phân tích cú pháp CSV-Strings chứa các dấu âm tiếng Đức (-> ä, ö, ü, Ä, Ö, Ü) trong PHP.PHP str_getcsv loại bỏ umlauts

Giả sử chuỗi sau csv đầu vào:

w;x;y;z 
48;OSL;Oslo Stock Exchange;B 
49;OTB;Österreichische Termin- und Optionenbörse;C 
50;VIE;Wiener Börse;D 

Và mã PHP thích hợp sử dụng để phân tích chuỗi và tạo ra một mảng chứa các dữ liệu từ csv-String:

public static function parseCSV($csvString) { 
    $rows = str_getcsv($csvString, "\n"); 
    // Remove headers .. 
    $header = array_shift($rows); 
    $cols = str_getcsv($header, ';'); 
    if(!$cols || count($cols)!=4) { 
     return null; 
    } 
    // Parse rows .. 
    $data = array(); 
    foreach($rows as $row) { 
     $cols = str_getcsv($row, ';'); 
     $data[] = array('w'=>$cols[0], 'x'=>$cols[1], 'y'=>$cols[2], 'z'=>$cols[3]); 
    } 
    if(count($data)>0) { 
     return $data; 
    } 
    return null; 
} 

Các kết quả của việc gọi hàm trên với kết quả csv-string đã cho:

Array 
(
    [0] => Array 
     (
      [w] => 48 
      [x] => OSL 
      [y] => Oslo Stock Exchange 
      [z] => B 
     ) 

    [1] => Array 
     (
      [w] => 49 
      [x] => OTB 
      [y] => sterreichische Termin- und Optionenbörse 
      [z] => C 
     ) 

    [2] => Array 
     (
      [w] => 50 
      [x] => VIE 
      [y] => Wiener Börse 
      [z] => D 
     ) 
) 

Lưu ý rằng mục nhập thứ hai bị thiếu Ö. Điều này chỉ xảy ra, nếu âm sắc được đặt trực tiếp sau ký tự dấu tách cột. Điều này cũng xảy ra, nếu nhiều hơn một âm sắc là các địa điểm theo thứ tự, tức là "ÖÖÖsterreich" -> "sterreich". Chuỗi csv được gửi bằng cách sử dụng Biểu mẫu HTML, do đó nội dung được mã hóa URL. Tôi sử dụng máy chủ Linux, với mã hóa utf-8 và chuỗi csv có vẻ chính xác trước khi phân tích cú pháp.

Bất kỳ ý tưởng nào?

+1

không thể tái tạo. làm việc cho tôi. http://codepad.viper-7.com/v6WIaT – Gordon

+0

Đây là sự cố mã hóa. Tôi đã cố gắng để đặt chuỗi trực tiếp trong tập tin php, sử dụng mã hóa UTF-8. Sau đó, nó hoạt động. Bây giờ tôi sử dụng $ csvString = utf8_encode ($ csvString); trước mã phân tích cú pháp và nó hoạt động như một nét duyên dáng. – Javaguru

+1

Tôi đoán, tôi phải đảm bảo rằng tất cả dữ liệu biểu mẫu được mã hóa bằng UTF-8, sử dụng thẻ meta và một Tiêu đề phản hồi HTTP thích hợp. – Javaguru

Trả lời

6

fgetcsv Giả sử (http://php.net/manual/en/function.fgetcsv.php) hoạt động tương tự như str_getcsv() sau đó để báo giá xem man page:

thiết lập Locale được đưa vào tài khoản bởi chức năng này. Nếu LANG là ví dụ: en_US.UTF-8, các tệp theo mã byte bị đọc sai bởi hàm này.

thì bạn nên cố gắng thiết lập một miền địa phương với setlocale http://php.net/manual/en/function.setlocale.php

nếu điều này không làm việc, cố gắng tạo điều kiện cho đa byte quá tải http://www.php.net/manual/en/mbstring.overload.php

hoặc thậm chí tốt hơn, sử dụng một thư viện khuôn khổ tiêu chuẩn như một Thư viện Zend/Symfony để lấy dữ liệu ra

0

Tôi gặp vấn đề tương tự với ký tự ï trong một số dữ liệu có nguồn gốc từ Microsoft Excel, được lưu dưới dạng CSV (có, với Mã hóa UTF8 được chọn trong phần "tùy chọn web" của hộp thoại "Lưu dưới dạng ..."). Và vẫn còn, điều này dường như không phải là cùng một mã hóa UTF8 mà str_getcsv mong đợi.

bây giờ tôi chạy tất cả mọi thứ thông qua iconv đầu tiên và nó hoạt động tốt - có vẻ như cái gì đó lên với ý tưởng của Excel của một tập tin CSV:

iconv -f windows-1252 -t utf8 source.csv > output.csv