Saltar al contenido

Laravel: Error en la carga de archivos de formulario: se detectó un tipo incorrecto

La guía paso a paso o código que encontrarás en este post es la resolución más sencilla y efectiva que hallamos a tu duda o problema.

Solución:

El problema era que PHP usa el file comando del sistema operativo (en este caso Ubuntu) para adivinar la extensión en función del contenido del archivo. Se estaba equivocando. Actualizar Ubuntu probablemente ayudaría.

docx es un documento de formato XML abierto de Microsoft Word, basado en XML y todo el contenido se almacena como archivos separados y, en última instancia, se compacta en un solo archivo comprimido ZIP. Parece un contenedor de archivos.

Y no deberíamos tomar la extensión de archivo como la misma con mimetype. Por lo que sé, un archivo normal (un archivo mp4 con docx no debe tomar como normal) con docx La extensión de archivo puede tener uno de estos tipos MIME.

'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
'application/zip'
'application/CDFV2'

En tu código,

$file->getClientOriginalExtension() extraiga la extensión del nombre del archivo original que se cargó, lo que no debe considerarse como un valor seguro.

$file->getClientMimeType() extraiga el tipo mime de la solicitud del cliente, que no debe considerarse como un valor seguro.

Ambas funciones implementadas en ./vendor/symfony/http-foundation/File/UploadedFile.php

Luego eche un vistazo a la última función en su código,

$file->extension() usar algún método para adivinar (que tal vez no sea exacto) la extensión del archivo. En secuencia php finfo (manual) que se basa en el contenido del archivo, el sistema file. Como el código fuente a continuación, es una suposición, por lo que no es preciso todo el tiempo. Consulte el comando de archivo que aparentemente devuelve un tipo MIME incorrecto.

Aquí deberías conseguirlo. Si desea ir más allá, consulte a continuación el código fuente de la función extension.


Código fuente
extension llamar guessExtension para adivinar la extensión del archivo, y guessExtension usar el tipo MIME devuelto por guessMiMeType

// FileHelpers.php
public function extension()

    return $this->guessExtension();

// File.php
public function guessExtension()

    return MimeTypes::getDefault()->getExtensions($this->getMimeType())[0] ?? null;

...
public function getMimeType()

    return MimeTypes::getDefault()->guessMimeType($this->getPathname());


guessMiMeType use dos adivinadores para adivinar el tipo mime. php finfo y del sistema filey finfo tener alta prioridad que file.

//MimeTypes.php
public function __construct(array $map = [])

    foreach ($map as $mimeType => $extensions) 
        $this->extensions[$mimeType] = $extensions;

        foreach ($extensions as $extension) 
            $this->mimeTypes[$extension] = $mimeType;
        
    
    $this->registerGuesser(new FileBinaryMimeTypeGuesser());
    $this->registerGuesser(new FileinfoMimeTypeGuesser());

...
/**
* Registers a MIME type guesser.
*
* The last registered guesser has precedence over the other ones.
*/
public function registerGuesser(MimeTypeGuesserInterface $guesser)

    array_unshift($this->guessers, $guesser);

...
public function guessMimeType(string $path): ?string

    foreach ($this->guessers as $guesser) 
        if (!$guesser->isGuesserSupported()) 
            continue;
        

        if (null !== $mimeType = $guesser->guessMimeType($path)) 
            return $mimeType;
        
    

    if (!$this->isGuesserSupported()) 
        throw new LogicException('Unable to guess the MIME type as no guessers are available (have you enable the php_fileinfo extension?).');
    

    return null;

//FileinfoMimeTypeGuesser.php
public function guessMimeType(string $path): ?string
 !is_readable($path)) 
        throw new InvalidArgumentException(sprintf('The "%s" file does not exist or is not readable.', $path));
    

    if (!$this->isGuesserSupported()) 
        throw new LogicException(sprintf('The "%s" guesser is not supported.', __CLASS__));
    

    if (false === $finfo = new finfo(FILEINFO_MIME_TYPE, $this->magicFile)) 
        return null;
    

    return $finfo->file($path);

//FileBianryMimeTypeGuesser.php
public function __construct(string $cmd = 'file -b --mime %s 2>/dev/null')

    $this->cmd = $cmd;

    public function guessMimeType(string $path): ?string

    if (!is_file($path) 

Safari es conocido por sus tipos de mímica, que no son correctos. Estoy seguro de que en su caso, no está enviando docx mime como debería, sino que está diciendo que es octet-stream. Bueno, su única solución es (si su archivo no está dañado) configurar manualmente la extensión del archivo para corregir uno o enviar manualmente el archivo desde el navegador, asegurándose de que el mimo sea correcto.

valoraciones y reseñas

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *