2012-11-08 14 views
9

Sử dụng chức năng PHP 5.3 fgetcsv, tôi gặp một số sự cố do mã hóa các vấn đề. Lưu ý rằng tệp đó có các ký tự latin "đặc biệt" như tiếng Tây Ban Nha, é, í ï, v.v ...php fgetcsv - vấn đề mã hóa charset

Tôi nhận tệp CSV xuất một số dữ liệu có cấu trúc mà tôi có trong tệp MS 2008 dành cho Mac Excel.

Nếu tôi mở ứng dụng bằng ứng dụng Mac OS X TextEdit, mọi thứ có vẻ hoàn hảo.

Nhưng khi tôi xuống chương trình PHP của mình và cố gắng đọc CSV bằng cách sử dụng hàm fgetcsv PHP đó, tôi không nhận được nó để đọc đúng bộ ký tự.

/** 
* @Route("/cvsLoad", name="_csv_load") 
* @Template() 
*/ 
public function cvsLoadAction(){ 
    //setlocale(LC_ALL, 'es_ES.UTF-8'); 
    $reader = new Reader($this->get('kernel')->getRootDir().'/../web/uploads/documents/question_images/2/41/masiva.csv'); 

    $i = 1; 
    $r = array("hhh" => $reader -> getAll()); 

    return new Response(json_encode($r, 200)); 
} 

Như bạn có thể thấy, tôi cũng đã thử sử dụng setlocale đến es_ES.UTF-8. Nhưng không có gì làm cho nó hoạt động.

Phần đọc đến đây:

public function getRow() 
{ 
    if (($row = fgetcsv($this->_handle, 10000, $this->_delimiter)) !== false) { 
     $this->_line++; 
     return $this->_headers ? array_combine($this->_headers, $row) : $row; 
    } else { 
     return false; 
    } 
} 

Xem những gì tôi nhận được trong biến $ row sau mỗi lần đọc hàng:

enter image description here

Những ? nhân vật được coi là nguyên âm với đồ họa nhấn mạnh vào chúng.

Bất kỳ đầu mối nào ở đó? Nó sẽ hoạt động nếu tôi sử dụng MS Excel cho Windows? Làm thế nào tôi có thể biết trong thời gian chạy mã hóa chính xác của tập tin và thiết lập nó trước khi đọc nó?

(Đối với những người nói tiếng Tây Ban Nha này, đừng sợ hãi với những thứ y tế khủng khiếp như vậy trong những văn bản đó;)).

+1

Cùng một vấn đề. Tệp CSV được mã hóa UTF8 nhập tiền phạt trên một máy chủ nhưng không nhập một máy chủ khác. Đã kết thúc viết trình đọc CSV của riêng tôi. –

+0

FWIW, bạn không thể thực sự * biết * mã hóa của một tệp mà không được thông báo. Bạn có thể đoán khi bạn đọc nó, và chuyển đổi cho phù hợp, nhưng không có gì là đáng tin cậy như được nói với mã hóa. – cmbuckley

+0

Cảm ơn cbuckley. Bạn có ý nghĩa gì với loại "chuyển đổi tương ứng" để thử đoán và hỏi người dùng xem liệu anh ấy có chấp thuận việc nhập không? Và nếu không, tiếp tục cố gắng mã hóa khác cho nguồn gốc? – ElPiter

Trả lời

28

Hãy thử điều này:

function convert($str) { 
    return iconv("Windows-1252", "UTF-8", $str); 
} 

public function getRow() 
{ 
    if (($row = fgetcsv($this->_handle, 10000, $this->_delimiter)) !== false) { 
     $row = array_map("convert", $row); 
     $this->_line++; 
     return $this->_headers ? array_combine($this->_headers, $row) : $row; 
    } else { 
     return false; 
    } 
} 
+2

+1. Lưu ý trên [docs] (http://php.net/manual/en/function.fgetcsv.php): nếu tệp được mã hóa một byte (chẳng hạn như CP1252), nhưng ngôn ngữ là multibyte, thì fgetcsv không làm việc như mong đợi. – cmbuckley

+0

Đây là một trong những !! :) Cảm ơn rất nhiều. Chỉ cần một số ý kiến: đầu tiên, cần phải khai báo là tĩnh chức năng chuyển đổi và ánh xạ nó trong mảng_map là 'self: convert'; thứ hai, trong trường hợp của tôi nó là biểu tượng ("macintosh", "UTF-8", $ str), như MS Excel cho Mac OS xuất sang CSV bằng Mac OS Roman. Cuối cùng, mặc dù đây là một câu trả lời tuyệt vời và thực sự giúp tôi, vẫn không phải là tất cả những gì tôi cần, vì tôi sẽ không biết liệu người dùng của tôi có tải lên tệp từ máy Mac hoặc PC hay bất cứ thứ gì ... làm cách nào để phát hiện mã hóa của tệp được tải lên là gì? Cảm ơn một lần nữa !! – ElPiter

+0

Bạn cần sử dụng chẩn đoán ..đầu tiên nhìn thấy nếu nó là hợp lệ UTF-8 hoặc UTF-16, nếu không, xác định PC/MAC (Từ tiêu đề tác nhân người dùng) và sử dụng Windows-1252 cho PC và Macintosh cho mac. Tất nhiên nếu người dùng không sử dụng tập lệnh latin, bạn sẽ sử dụng Windows-1251 (Cyrillic cho Windows), v.v. Ai đó phải viết một thư viện cho điều này: D – Esailija

0

Điều này có thể phù hợp với cách excel mã hóa tệp khi lưu.

Hãy thử tải lên các tập tin .xls để google docs và tải xuống như một .csv

+0

Tôi cũng đã thử, nhưng nó thậm chí còn tồi tệ hơn tôi nghĩ. Tuy nhiên, tôi sẽ thử lại. Cảm ơn đã phản ứng nhanh chóng. :) – ElPiter