move_uploaded_file / is_uploaded_file în PHP

Mută un fișier încărcat printr-un formular în locul lui definitiv de pe server.

Sintaxă
move_uploaded_file(string $from, string $to): bool

Ce face move_uploaded_file / is_uploaded_file

Când un vizitator încarcă un fișier, PHP îl salvează într-un director temporar și pune detaliile în $_FILES. Fișierul temporar se șterge la finalul cererii, deci trebuie mutat cu move_uploaded_file.

Funcția verifică întâi că fișierul a fost chiar încărcat prin HTTP POST în această cerere. Astfel nimeni nu te poate păcăli să muți un fișier al serverului, de exemplu /etc/passwd. Aceeași verificare, fără mutare, o face is_uploaded_file. Formularul are nevoie de enctype="multipart/form-data".

Parametri

Parametru Descriere
$from Calea temporară, din $_FILES["camp"]["tmp_name"].
$to Calea finală. Directorul trebuie să existe și să permită scrierea.

Ce returnează

true dacă fișierul a fost mutat. false dacă nu este un fișier încărcat valid sau mutarea a eșuat.

Exemple

Exemplul 1: Script de încărcare a unui CV

Rulează pe server, după trimiterea unui formular cu câmpul <input type="file" name="cv">.

<?php
$fisier = $_FILES["cv"];

if ($fisier["error"] !== UPLOAD_ERR_OK) {
    exit("Eroare la încărcare: cod " . $fisier["error"]);
}
if (strtolower(pathinfo($fisier["name"], PATHINFO_EXTENSION)) !== "pdf") {
    exit("Sunt acceptate doar fișiere PDF.");
}

$nume = bin2hex(random_bytes(8)) . ".pdf";
if (move_uploaded_file($fisier["tmp_name"], __DIR__ . "/uploads/$nume")) {
    echo "Fișierul " . htmlspecialchars($fisier["name"]) . " a fost încărcat.";
}

Rezultat pe server, după trimiterea formularului

Fișierul cv-ana-popescu.pdf a fost încărcat.

Exemplul 2: Un fișier care nu a fost încărcat este respins

Aici $_FILES este completat de mână, ca un atacator. PHP știe că fișierul nu a venit prin formular.

<?php
file_put_contents("parole.txt", "secret");
$_FILES["poza"] = ["name" => "poza.jpg", "tmp_name" => "parole.txt", "error" => 0];

var_dump(is_uploaded_file($_FILES["poza"]["tmp_name"]));
var_dump(move_uploaded_file($_FILES["poza"]["tmp_name"], "poza.jpg"));

Rezultat

bool(false)
bool(false)

Greșeli frecvente

  • Folosești rename sau copy pe tmp_name. Pierzi verificarea de securitate. Folosește move_uploaded_file.
  • Păstrezi numele original trimis de vizitator. Poate conține caractere periculoase sau extensia .php. Generează tu un nume nou și verifică extensia.
  • Fișierele mari nu ajung deloc: sunt respinse de setările upload_max_filesize și post_max_size din php.ini. Verifică $_FILES[...]["error"].

Comenzi înrudite

  • pathinfo: Împarte o cale de fișier în director, nume complet, nume fără extensie și extensie.
  • basename: Returnează doar numele fișierului dintr-o cale, fără directoare.
  • is_writable / is_readable: Verifică dacă scriptul poate scrie (is_writable) sau citi (is_readable) un fișier sau director.
  • mkdir: Creează un director nou, opțional cu toate directoarele părinte care lipsesc.