Domanda

Non posso usare mkdir Per creare cartelle con caratteri UTF-8:

<?php
$dir_name = "Depósito";
mkdir($dir_name);
?>

Quando navigo questa cartella in Windows Explorer, il nome della cartella sembra così:

Depósito

Cosa dovrei fare?

Sto usando PHP5

È stato utile?

Soluzione

Solo urlencode La stringa desiderata come nome file. Tutto personaggi restituiti da urlencode sono validi nei file di file (NTFS/HFS/UNIX), quindi puoi solo urldecode I nomi dei file di nuovo su UTF-8 (o qualunque codifica in cui si trovassero).

Avvertenze (tutti si applicano anche alle soluzioni seguenti):

  • Dopo la codifica dell'URL, il nome file deve essere inferiore a 255 caratteri (probabilmente byte).
  • UTF-8 ha rappresentazioni multiple per molti personaggi (usando i personaggi combinanti). Se non normalizzi il tuo UTF-8, potresti avere difficoltà a cercare glob o riapertura di un singolo file.
  • Non puoi fare affidamento scandir o funzioni simili per la disorzione alfa. Devi urldecode I nomi di file utilizzano quindi un algoritmo di ordinamento a conoscenza di UTF-8 (e COLLAZIONI).

Soluzioni peggiori

Quelle che segue sono soluzioni meno interessanti, più complicate e con più avvertenze.

Su Windows, il wrapper del filesystem PHP si aspetta e restituisce stringhe ISO-8859-1 per i nomi di file/directory. Questo ti dà due scelte:

  1. Usa l'UTF-8 liberamente nei tuoi file di file, ma capisci che i personaggi non ASCII lo faranno sembrano errato fuori Php. Un char UTF-8 non ASCII verrà archiviato come multiplo separare Personaggi ISO-8859-1. Per esempio ó verrà visualizzato come ó In Windows Explorer.

  2. Limita i nomi del file/directory a personaggi rappresentabili in ISO-8859-1. In pratica, passerai le tue stringhe UTF-8 utf8_decode Prima di usarli nelle funzioni del filesystem e passare le voci scandir ti dà attraverso utf8_encode Per ottenere i file di file originale in UTF-8.

Avvertimenti a bizzeffe!

  • Se non ci sono byte Passato a una funzione del filesystem corrisponde a Carattere di filesystem di Windows non valido In ISO-8859-1, sei sfortunato.
  • finestre Maggio Utilizzare una codifica diversa da ISO-8859-1 in locali non inglesi. Immagino che di solito sarà uno di ISO-8859-#, ma questo significa che dovrai usare mb_convert_encoding invece di utf8_decode.

Questo incubo è il motivo per cui probabilmente dovresti solo traslitterare Per creare filenature.

Altri suggerimenti

Sotto UNIX e Linux (e possibilmente anche in OS X), la codifica del file system corrente è data dal LC_CTYPE parametro locale (vedi funzione setlocale()). Ad esempio, può valutare qualcosa di simile en_US.UTF-8 Ciò significa che la codifica è UTF-8. Quindi i nomi dei file e i loro percorsi possono essere creati fopen() o recuperato da dir() con questa codifica.

In Windows, PHP opera come un "programma non consapevole non unicode", quindi i nomi dei file vengono convertiti avanti e indietro dall'UTF-16 utilizzato dal file system (Windows 2000 e successivamente) nella "pagina del codice" selezionata. Il pannello di controllo "Opzioni regionali e linguistiche", formati di scheda "" imposta la pagina del codice recuperata dal LC_CTYPE Opzione, mentre "Amministrativo -> Lingua per programmi non UNICODE" imposta la pagina Codice di traduzione per i nomi dei file. Nei paesi occidentali il LC_CTYPE Il parametro valuta qualcosa di simile language_country.1252 dove 1252 è la pagina del codice, nota anche come "codifica Windows-1252" che è simile (ma non esattamente uguale) a ISO-8859-1. In Giappone la pagina del codice 932 è di solito impostata invece, e così via per altri paesi. In PHP è possibile creare file il cui nome può essere espresso con la pagina del codice corrente. Viceversa, nomi di file e percorsi recuperati dal file system vengono convertiti da UTF-16 in byte usando il Pagina del codice corrente "best-fit".

Questa mappatura è approssimata, quindi alcuni personaggi potrebbero essere mangrati in modo imprevedibile. Per esempio, Caffé Brillì.txt verrebbe restituito da dir() Come stringa PHP Caff\xE9 Brill\xEC.txt Come previsto se la pagina del codice corrente è 1252, mentre restituirebbe l'approssimazione Caffe Brilli.txt Su un sistema giapponese perché mancano vocali accentati dalla pagina del codice 932 e quindi sostituite con le vocali non accentate "più adatte". I personaggi che non possono essere tradotti sono affatto recuperati come ? (punto interrogativo). In generale, sotto Windows non esiste un modo sicuro per rilevare tali artefatti.

Maggiori dettagli sono disponibili nella mia risposta al Bug php n. 47096.

PHP 7.1 supporta i fileNamme UTF-8 su Windows che ignora il codepage OEM.

Il problema è che Windows utilizza UTF-16 per stringhe del filesystem, mentre Linux e altri utilizzano diversi set di caratteri, ma spesso UTF-8. Hai fornito una stringa UTF-8, ma questo è interpretato come un altro set di caratteri a 8 bit che codifica in Windows, forse Latin-1, e quindi il carattere non ASCII, che è codificato con 2 byte in UTF-8, viene gestito come Se erano 2 caratteri in Windows.

Una soluzione normale è mantenere il codice sorgente al 100% in ASCII e avere stringhe da qualche altra parte.

Usando il com_dotnet Estensione PHP, puoi accedere a Windows ' Scripting.FileSystemObject, quindi fai tutto ciò che desideri con i nomi di file/cartelle UTF-8.

L'ho confezionato come un involucro di flusso PHP, quindi è molto facile da usare:

https://github.com/nicolas-grekas/patchwork-utf8/blob/lab-windows-fs/class/patchwork/utf8/winfsstreamwrapper.php

Prima verifica che il com_dotnet L'estensione è abilitata nel tuo php.iniQuindi abilita l'involucro con:

stream_wrapper_register('win', 'Patchwork\Utf8\WinFsStreamWrapper');

Infine, usa le funzioni per cui sei abituato (mkdir, fopen, rinominare, ecc.), Ma prefigurare il tuo percorso con win://

Per esempio:

<?php
$dir_name = "Depósito";
mkdir('win://' . $dir_name );
?>

Potresti usare questa estensione per risolvere il tuo problema: https://github.com/kenjiuno/php-wfio

$file = fopen("wfio://多国語.txt", "rb"); // in UTF-8
....
fclose($file);

Prova un supporto di testo codeigniter da questo linkLeggi sulla funzione convert_accented_characters (), può essere costumita

Il mio set di strumenti per utilizzare il filesystem con UTF-8 su Windows O Linux via PHP e compatibile con .htaccess Controllare il file esiste:

function define_cur_os(){

    //$cur_os=strtolower(php_uname());

    $cur_os=strtolower(PHP_OS);

    if(substr($cur_os, 0, 3) === 'win'){

        $cur_os='windows';

    }

    define('CUR_OS',$cur_os);

}

function filesystem_encode($file_name=''){

    $file_name=urldecode($file_name);

    if(CUR_OS=='windows'){

        $file_name=iconv("UTF-8", "ISO-8859-1//TRANSLIT", $file_name);

    }     

    return $file_name;

}

function custom_mkdir($dir_path='', $chmod=0755){

    $dir_path=filesystem_encode($dir_path);

    if(!is_dir($dir_path)){

        if(!mkdir($dir_path, $chmod, true)){

            //handle mkdir error

        }
    }
    return $dir_path;
}

function custom_fopen($dir_path='', $file_name='', $mode='w'){

    if($dir_path!='' && $file_name!=''){

        $dir_path=custom_mkdir($dir_path);

        $file_name=filesystem_encode($file_name);

        return fopen($dir_path.$file_name, $mode);

    }

    return false;

}

function custom_file_exists($file_path=''){

    $file_path=filesystem_encode($file_path);

    return file_exists($file_path);

}

function custom_file_get_contents($file_path=''){

    $file_path=filesystem_encode($file_path);

    return file_get_contents($file_path);

}

Risorse addizionali

Non ho bisogno di scrivere molto, funziona bene:

<?php
$dir_name = mb_convert_encoding("Depósito", "ISO-8859-1", "UTF-8");
mkdir($dir_name);
?>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top