Maison  >  Article  >  développement back-end  >  Comment résoudre le problème des caractères chinois tronqués compressés par PHP

Comment résoudre le problème des caractères chinois tronqués compressés par PHP

藏色散人
藏色散人original
2022-11-14 10:25:041892parcourir

Solution aux caractères chinois tronqués dans la compression PHP : 1. Installez PhpZip via "composer require nelexa/zip" ; 2. Ouvrez "ZipFile.php" 3. Recherchez la méthode "extractTo" et modifiez ou supprimez la fonction "is_writable" ; ; 4. Convertissez simplement le format d'encodage.

Comment résoudre le problème des caractères chinois tronqués compressés par PHP

L'environnement d'exploitation de ce tutoriel : système Windows 7, PHP version 8.1, ordinateur Dell G3.

Comment résoudre le problème des caractères chinois tronqués compressés en PHP ?

Résolvez le problème des caractères chinois tronqués lorsque php est décompressé à l'aide de ZipArchive (php pur, contournez ZipArchive)

Résolvez le problème des caractères chinois tronqués lorsque php est décompressé à l'aide de ZipArchive

Utilisation de ZipArchive fourni avec php pour décompresser compressé les paquets avec des noms de fichiers chinois provoqueront Le code est tronqué et le phénomène est le suivant :

Comment résoudre le problème des caractères chinois tronqués compressés par PHP

Les réponses données en ligne sont fondamentalement les mêmes. J'ai essayé la même méthode mais je n'ai pas pu la résoudre. L'image ci-dessous est la même. solution donnée en ligne :

Comment résoudre le problème des caractères chinois tronqués compressés par PHP

Après tâtonnement, je l'ai finalement trouvée. La solution est d'abandonner ZipArchive et de choisir d'autres méthodes. Après comparaison, j'ai choisi "PhpZip". . Voici la méthode d'installation :

installation de composer :

composer require nelexa/zip

Si vous choisissez la version : composer require nelexa/zip:^3.0 (numéro de version 3.0)

Utilisation :

//解压文件
$fileAddess = "压缩包地址";
$toDir = "解压目录";
$zipFile = new \PhpZip\ZipFile();
$zipFile->openFile($fileAddess) // open archive from file
->extractTo($toDir); // extract files to the specified directory
$zipFile->close();

Remarques : (**S'il est installé et utilisé normalement, veuillez ignorer les commentaires suivants**)

1. Moi Le package compressé est placé dans le disque partagé et connecté à l'adresse smb. Un message d'erreur peut apparaître : "La destination n'est pas un répertoire inscriptible". déjà parcouru : ouvrez le fichier ZipFile.php, recherchez la méthode "extractTo" et modifiez "is_writable". Changez la fonction, ou supprimez-la, puis convertissez le format d'encodage ! , les commentaires ci-dessous sont ce que j'ai modifié !

/**
     * Extract the archive contents
     *
     * Extract the complete archive or the given files to the specified destination.
     *
     * @param string $destination Location where to extract the files.
     * @param array|string|null $entries The entries to extract. It accepts either
     *                                   a single entry name or an array of names.
     * @return ZipFile
     * @throws ZipException
     */
    public function extractTo($destination, $entries = null)
    {
        if (!file_exists($destination)) {
            throw new ZipException("Destination " . $destination . " not found");
        }
        if (!is_dir($destination)) {
            throw new ZipException("Destination is not directory");
        }
        $is_really_writable = $this->is_really_writable($destination);
        if (!$is_really_writable) {
            throw new ZipException("Destination is not writable directory");
        }
        /**
         * @var ZipEntry[] $zipEntries
         */
        if (!empty($entries)) {
            if (is_string($entries)) {
                $entries = (array)$entries;
            }
            if (is_array($entries)) {
                $entries = array_unique($entries);
                $flipEntries = array_flip($entries);
                $zipEntries = array_filter(
                    $this->centralDirectory->getEntries(),
                    function ($zipEntry) use ($flipEntries) {
                        /**
                         * @var ZipEntry $zipEntry
                         */
                        return isset($flipEntries[$zipEntry->getName()]);
                    }
                );
            }
        } else {
            $zipEntries = $this->centralDirectory->getEntries();
        }
        foreach ($zipEntries as $entry) {
            /******************************王天佑添加的逻辑start************************************/
            header("Content-type:text/html;charset=bgk");
            $entry_getName = iconv('GB2312', 'UTF-8//ignore',$entry->getName());
            //header("Content-type:text/html;charset=utf-8");
            /******************************王天佑添加的逻辑start************************************/
            $file = $destination . DIRECTORY_SEPARATOR . $entry_getName;
            if ($entry->isDirectory()) {
                if (!is_dir($file)) {
                    if (!mkdir($file, 0755, true)) {
                        throw new ZipException("Can not create dir " . $file);
                    }
                    chmod($file, 0755);
                    touch($file, $entry->getTime());
                }
                continue;
            }
            $dir = dirname($file);
            if (!is_dir($dir)) {
                if (!mkdir($dir, 0755, true)) {
                    throw new ZipException("Can not create dir " . $dir);
                }
                chmod($dir, 0755);
                touch($dir, $entry->getTime());
            }
            if (file_put_contents($file, $entry->getEntryContent()) === false) {
                throw new ZipException('Can not extract file ' . $entry_getName);
            }
            touch($file, $entry->getTime());
        }
        return $this;
    }
    //王天佑加的新逻辑,判断目录是否可写
    public function is_really_writable($file){
        if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE) {
            return is_writable($file);
        }
        if (is_dir($file)) {
            $file = rtrim($file, '/') . '/' . md5(mt_rand(1,100) . mt_rand(1,100));
            if (($fp = @fopen($file, "w+")) === FALSE) {
                return FALSE;
            }
            fclose($fp);
            @chmod($file, 0777);
            @unlink($file);
        } elseif (!is_file($file) OR ($fp = @fopen($file, "r+")) === FALSE) {
            fclose($fp);
            return FALSE;
        }
        return TRUE;
    }

Apprentissage recommandé : "Tutoriel vidéo PHP"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn