1

ここでユーザー user1830391 が提供した回答に基づいて: CSV ファイルの一部の文字が PHP fgetcsv() 中に読み取られない

fgetcsv() の代わりに fgets() を使用するように次のコードを更新しました。それは私の最初のキャラクターの問題を修正しました。それはもはや問題ではありません...しかし...

.csv ファイルが ; を使用して区切られている場合はどうなりますか? の代わりに、一部のフィールドは二重引用符 "" を使用してラップされます。たとえば、行の 1 つが 2 行に分割されます。quote は、1 行の最後の要素で開き、次の行の最初の要素の終わりで閉じます。そのセルには「入力」(/n) があります。このコードを使用してこれをどのように扱うべきですか。fgetcsv は二重引用符内の要素をキャッチしますが、 fgets() はそうではないと思います。

function runCSVtoArray() {
    // --> FOR IMPORT
    //Function that converts a CSV file to a PHP array.
    //echo '<span class="success">Chargement du fichier CSV pour importation MYSQL....</span><br />';
    $readCharsPerLine = (JRequest::getVar('charsPerLine') > 0) ? JRequest::getVar('charsPerLine') : 1500; /* Import as of 2012-04-16 seem to have max 800chars per line. 1500 is alot of extra. */
    ini_set("auto_detect_line_endings", true);
    iconv_set_encoding("internal_encoding", "UTF-8");
    $openfile = $this->imp['importPath'].$this->imp['csvFileName'];
    if ( file_exists($openfile) ) {
        //echo '<span class="success">Fichier CSV trouvé....</span><br />';
        //echo '<span class="success">Ouverture du fichier : '.$openfile.'</span><br />';
        if (($handle = fopen($openfile, "r")) !== FALSE) {
            //echo '<span class="success">Fichier CSV ouvert... Chargement en cours....</span><br />';
            $row_i=0;
            $this->_importData = array();
            /*while (($data = fgetcsv($handle, $readCharsPerLine, ";")) !== FALSE) {*/
            while (($the_line = fgets($handle)) !== FALSE) {
                $data = explode(';', $the_line);
                $debugoutput = implode('; ', $data).'<br />'; echo ( (JRequest::getVar('encodeutf8')) && ( mb_detect_encoding($debugoutput, "UTF-8") == "UTF-8") ) ? utf8_encode($debugoutput) : $debugoutput.'<br />'; //Debug2
                /*
                $num        = count($data);
                if ($row_i==0) {
                    // TITLE ROW
                    $keyRow = array();
                    for ($c=0; $c < $num; $c++) {
                        //Making title array with CSV first line
                        //Key for colum
                        if ( (JRequest::getVar('encodeutf8')) && ( mb_detect_encoding($data[$c], "UTF-8") == "UTF-8") ) { $data[$c] = utf8_encode($data[$c]); }
                        if ($data[$c]!="") {
                            $keyRow[$c]=trim($data[$c]);
                            $keyRow[$c]=str_replace('GDWACCENT', '', $keyRow[$c]);  //STRIP GDWACCENT, GDW uTF8 fgetcsv fix
                        }
                        else { $keyRow[$c]=''; }
                    }
                } else {
                    //VALUE ROW...
                    for ($c=0; $c < $num; $c++) {
                        $key = $keyRow[$c];
                        if ( (JRequest::getVar('encodeutf8')) && ( mb_detect_encoding($data[$c], "UTF-8") == "UTF-8") ) {
                            $data[$c] = utf8_encode($data[$c]);
                            $data[$c]=str_replace('GDWACCENT', '', $data[$c]);  //STRIP GDWACCENT, GDW uTF8 fgetcsv fix
                        }
                        if ($data[$c]!="") {
                            $this->_importData[$row_i][$key]=trim($data[$c]);
                            $this->_importData[$row_i][$key]=str_replace('GDWACCENT', '', $this->_importData[$row_i][$key]);    //STRIP GDWACCENT, GDW uTF8 fgetcsv fix
                        }
                    }
                }
                */
                $row_i++;
            } //End while()
            //echo '<span class="success">Chargement terminer.... Sauvegarde en cours...</span><br />';
            return true;
        } else {
            //Incapable d'ouvrir le fichier d'importation.
            return false;
        }
    } else {
        //FILE NOT FOUND...
        return false;
    }
} // runCSVtoArray()
4

3 に答える 3

4

fgetcsv は ascii chars でのみ動作するという、あなたが頼っている答えは単に間違っています。真は次のとおりです。

ノート:

この関数では、ロケール設定が考慮されます。LANG が例えば en_US.UTF-8 の場合、1 バイト以上のエンコーディングのファイルは、この関数によって誤って読み取られます。

LANGそのため、fgets を使用する代わりに、変数を構成する必要があります。

lang 変数を設定する方法の例を次に示します。

putenv("LANG=fr_FR.UTF-8");
于 2013-02-12T16:19:07.010 に答える
3

これを解決するには、fgetcsv()の代わりにfopenとfgetsを使用してファイルを開き、各行にutf8_encodeを使用してコピーを書き込みます。それから私はコピーを使用し、それをfgetcsv()に通します

これが私の更新されたコードです。

function runCSVtoArray() {
    // --> FOR IMPORT
    //Function that converts a CSV file to a PHP array.
    //echo '<span class="success">Chargement du fichier CSV pour importation MYSQL....</span><br />';
    $readCharsPerLine = (JRequest::getVar('charsPerLine') > 0) ? JRequest::getVar('charsPerLine') : 1500; /* Import as of 2012-04-16 seem to have max 800chars per line. 1500 is alot of extra. */
    putenv("LANG=fr_CA.UTF-8");
    setlocale(LC_ALL, 'fr_CA.UTF-8');
    //ini_set("auto_detect_line_endings", true);
    //iconv_set_encoding("internal_encoding", "UTF-8");
    $openfile = $this->imp['importPath'].$this->imp['csvFileName'];
    $utf8File = str_replace('.csv', '_utf8.csv', $openfile);

    if ( file_exists($openfile) ) {
        //echo '<span class="success">Fichier CSV trouvé....</span><br />';

        //rewrite the file in UTF8
        if (JRequest::getVar('encodeutf8')) {
            if (($handle = fopen($openfile, "r")) !== FALSE) {
                $newFileHandle = fopen($utf8File, 'w');     //NEW UTF8 FORMAT
                //fwrite($newFileHandle, "\xEF\xBB\xBF");
                while (($the_line = fgets($handle)) !== FALSE) {
                    fwrite($newFileHandle, utf8_encode($the_line));
                }   //End of while()
            }
            $openfile = $utf8File;
        }

        //echo '<span class="success">Ouverture du fichier : '.$openfile.'</span><br />';
        if (($handle = fopen($openfile, "r")) !== FALSE) {
            //echo '<span class="success">Fichier CSV ouvert... Chargement en cours....</span><br />';
            $row_i=0;
            $this->_importData = array();
            while (($data = fgetcsv($handle, $readCharsPerLine, ";")) !== FALSE) {
            /*while (($the_line = fgets($handle)) !== FALSE) {*/
                //$data = explode(';', $the_line);
                //$debugoutput = implode('; ', $data); echo ( (JRequest::getVar('encodeutf8')) && ( mb_detect_encoding($debugoutput, "UTF-8") == "UTF-8") ) ? utf8_encode($debugoutput).'<br />' : $debugoutput.'<br />';   //Debug2
                //$debugoutput = implode('; ', $data); echo $debugoutput.'<br />';  //Debug2
                $num            = count($data);
                if ($row_i==0) {
                    // TITLE ROW
                    $keyRow = array();
                    $maxItems = count($data);   //Count the number of ";"
                    for ($c=0; $c < $num; $c++) {
                        //Making title array with CSV first line
                        //Key for colum
                        if ( (JRequest::getVar('encodeutf8')) && ( mb_detect_encoding($data[$c], "UTF-8") == "UTF-8") ) {
                            //$data[$c] = utf8_encode($data[$c]);
                            $data[$c] = $data[$c];
                        }
                        if ($data[$c]!="") {
                            $keyRow[$c]=trim($data[$c]);
                            $keyRow[$c]=str_replace('GDWACCENT', '', $keyRow[$c]);  //STRIP GDWACCENT, GDW uTF8 fgetcsv fix
                        }
                        else { $keyRow[$c]=''; }
                    }
                } else {
                    //VALUE ROW...
                    for ($c=0; $c < $num; $c++) {
                        $key = $keyRow[$c];
                        if ( (JRequest::getVar('encodeutf8')) && ( mb_detect_encoding($data[$c], "UTF-8") == "UTF-8") ) {
                            //$data[$c] = utf8_encode($data[$c]);
                            $data[$c] = $data[$c];
                            $data[$c]=str_replace('GDWACCENT', '', $data[$c]);  //STRIP GDWACCENT, GDW uTF8 fgetcsv fix
                        }
                        if ($data[$c]!="") {
                            $this->_importData[$row_i][$key]=trim($data[$c]);
                            $this->_importData[$row_i][$key]=str_replace('GDWACCENT', '', $this->_importData[$row_i][$key]);    //STRIP GDWACCENT, GDW uTF8 fgetcsv fix
                        }
                    }   //End of for()
                }
                $row_i++;
            } //End while()
            //echo 'HERE<br />';
            //gdwprint($this->_importData);
            //exit();
            //echo '<span class="success">Chargement terminer.... Sauvegarde en cours...</span><br />';
            return true;
        } else {
            //Incapable d'ouvrir le fichier d'importation.
            return false;
        }
    } else {
        //FILE NOT FOUND...
        return false;
    }
} // runCSVtoArray()
于 2013-02-12T20:21:44.203 に答える
1

私の経験から、入力データfgetcsv()は UTF-8 でなければなりません。

あなたの場合、Éric で É を無視した場合、入力は UTF-8 ではなく、おそらく 1 バイト エンコーディングです (echo bin2hex($str);確認するには Windows-1252?)。php バグ トラッカー ( https://bugs.php.net/bug.php?id=55507 ) にバグレポートがあります。解決策は、fgetcsv にフィードする前にテキストを utf8 に変換することです

また、UTF-8には BOM が含まれていないことが重要です。

于 2013-02-12T17:23:22.843 に答える