Autor Zpráva
ForestCZE
Profil
Ahoj, potřeboval bych prosím pomoct. Mám následující kód:

<input type="file" name="expozice" />

pripony = array("jpg", "jpeg");
            
            if($_FILES["expozice"]["error"] != UPLOAD_ERR_NO_FILE){
                if($_FILES["expozice"]["error"] != UPLOAD_ERR_INI_SIZE){
                    $je_foto = getimagesize($_FILES["expozice"]["tmp_name"]);
                    if($je_foto[2] == 2){
                        if(in_array(strtolower(pathinfo($_FILES["expozice"]["name"], PATHINFO_EXTENSION)), $pripony)){
                            $sirka = 145;
                            $rozmery = getimagesize($_FILES["expozice"]["tmp_name"]);
                            $pomer = $rozmery[0]/$rozmery[1];
                            $vyska = $sirka/$pomer;
                            $barvy = imagecreatetruecolor($sirka, $vyska);
                            $jpg = imagecreatefromjpeg($_FILES["expozice"]["tmp_name"]);
                            imagecopyresampled($barvy, $jpg, 0, 0, 0, 0, $sirka, $vyska, $rozmery[0], $rozmery[1]);
                            imagejpeg($barvy, "../expozice/".$_POST["expozice"]."/miniatury/".$_FILES["expozice"]["name"]);
                            imagedestroy($barvy);
                            move_uploaded_file($_FILES["expozice"]["tmp_name"], "../expozice/".$_POST["expozice"]."/".$_FILES["expozice"]["name"]);
                            chmod("../expozice/".$_POST["expozice"]."/miniatury/".$_FILES["expozice"]["name"], 0777);
                            chmod("../expozice/".$_POST["expozice"]."/".$_FILES["expozice"]["name"], 0777);
                        }else{
                            echo "Foto musí být ve formátu JPG nebo JPEG!";
                        }
                    }else{
                        echo "Tento soubor není foto!";
                    }
                }else{
                    echo "Maximální velikost je: ".ini_get("upload_max_filesize");
                }
            }else{
                echo "Soubor nevybrán!";
            }

A potřebuju z toho udělat, aby tam těch fotek šlo víc. Já samozřejmě vím, že to bude:

<input type="file" name="expozice[]" multiple="multiple"/>

A pak:

$pocet = count((array)$_FILES["expozice"]["tmp_name"]);

for($f = 0; $f < $poocet; $f++){
...
}

Ale jde mi o to, jestli by mi mohl někdo pomoct v tom, jak to správně vložit do toho cyklu. Jakou část do toho cyklu vložit, aby se mi třeba např. 10x nevypsala hláška, že je špatná přípona nebo jiná hláška. Děkuji moc předem.
Taps
Profil
ForestCZE:
tak hlášky si můžeš uložit do pole a pak vybrat jen unikátní hodnoty
ForestCZE
Profil
Taps:
Pole mi dělá problém, takže nevím, jak to myslíš. Šlo by to ještě udělat tak, že otočím podmínky s tím, že hlášku vypíšu do funkce die() nebo exit() a pak už v pohodě provedu skript v cyklu, jenže v okamžiku chyby se logicky zastaví vše a nenačte se zbytek stránky (např. footer). Proto jsem to tam nacpal takto.
mimochodec
Profil
ForestCZE:
Místo
echo "Foto musí být ve formátu JPG nebo JPEG!";

udělej $nenijpeg = true;

a na konci toho cyklu
if ($nenijpeg)
ForestCZE
Profil
mimochodec:
No jenže já tam ten cyklus právě zatím nemám, jelikož netuším, jak ho tam vložit i s těma hláškama. Nerad bych způsobil pád serveru.
Taps
Profil
ForestCZE:
místo echo můžeš použít
<?
$chyba[] = 'chybová hláška';
?>
čímž dojde k naplnění pole a pak jen
<?
  if(is_array($chyba)){
      $unique = array_unique($chyby);
      foreach($unique as $hlaska){
      echo $hlaska.'<br>';
      }
  }
?>
Nebo to můžeš udělat na úrovni řetězců tak jak psal mimochodec
Alphard_
Profil *
ForestCZE:
Nerad bych způsobil pád serveru.
Server jen tak nespadne, spadne PHP s fatal error. Nicméně, jestli správně chápu, že testujete na produkci, je to praštěné :-) Nainstalujte si server lokálně.

s tím, že hlášku vypíšu do funkce die() nebo exit() a (...), jenže v okamžiku chyby se logicky zastaví vše a nenačte se zbytek stránky (např. footer)
Proto se tady dlouhodobě vyjadřuji proti používání die a exit. Tímto směrem vůbec neuvažujte. Pro řízení běhu cyklu se podívejte na break a continue, tohle jsou naopak zcela běžné konstrukce.

Doporučuji snažit se vyhnout extrémnímu zanoření. Třeba vytvořením funkci isValidImageUpload() a saveImage(), které pak budete elegantně volat v jednom cyklu.
mimochodec
Profil
Taps:
Mám teď pocit, že ForestCZE se ptá na něco víc, než to ošetření chyb.

ForestCZE:
Nejdřív si ujasni, jak si představuješ tu reakci, když něco bude špatně. Nahraje se pět souborů, z toho jeden exe a dva větší než povolená velikost souboru. Co se má přesně stát? Chceš vypsat, že došlo k nějakým chybám, nebo je chceš rozepsat, nebo rozepsat vč. jejich počtu (tzn. 1 a 2)? A co ty soubory, co jsou ok? Zpracovat nebo ne?
ForestCZE
Profil
Alphard:
Souhlasím s tím vyhnutím fcí die i exit a ani to zanoření se mi nelíbí. Proto se tu na to ptám, jak to udělat co nejlépe.

mimochodec:
Stačí mi, aby to vypsalo chybovou hlášku nesplněné podmínky, na kterou to narazí při procházení jako první. Zbytek je mi "jedno", když nesplní další dvě, protože když jednu "opraví" a odešle, najde to další a jakmile bude všechno splněné, tak to vlastně odbourá všechno nežádoucí a uploadnou se takové soubory, jaké tam můžou být.

EDIT: A nezpracovávat ani ok soubory, ale zpracovat je až tehdy, kdy budou všechny v pořádku.
mimochodec
Profil
ForestCZE:
Zbytek je mi "jedno", když nesplní další dvě, protože když jednu "opraví" a odešle, najde to další a jakmile bude všechno splněné, tak to vlastně odbourá všechno nežádoucí a uploadnou se takové soubory, jaké tam můžou být.

Tady mysím chybí nějaký podmět nebo něco. Kdo co opraví? Jestli chceš "zpracovat je až tehdy, kdy budou všechny v pořádku", znamená to, že když yyberu pět souborů a cokoliv tam bude špatně, dozvím se první chybu, na kterou ten skript narazí a následně se všechno zapomene a vybírám soubory znovu.
ForestCZE
Profil
mimochodec:
Kdo co opraví?
Uploadující osoba, až napraví chybu, kterou vidí (např. vybere menší soubory a splní podmínku)

dozvím se první chybu, na kterou ten skript narazí a následně se všechno zapomene a vybírám soubory znovu
Ano, tak to může klidně být (a tak jsem to i zamýšlel)

Jinak dal jsem si relaxující horkou vanu xD a napadlo mě něco. Nešlo by to udělat jednoduše:

if(promenna1 == hodnota1){
echo "Chyba 1";
}

elseif(promenna2 == hodnota2){
echo "Chyba 2";
}

elseif(promenna3 == hodnota3){
echo "Chyba 3";
}

elseif(promenna4 == hodnota4){
echo "Chyba 4";
}else{
//vše je ok
//pošlu hromadný upload v cyklu
}
Alphard
Profil
ForestCZE:
Zbytek je mi "jedno", když nesplní další dvě, protože když jednu "opraví" a odešle, najde to další a jakmile bude všechno splněné, tak to vlastně odbourá všechno nežádoucí a uploadnou se takové soubory, jaké tam můžou být.
Vás budou uživatelé milovat. Input file nelze předvyplnit, takže budou muset neustále vybírat třeba 5 souborů... Navíc jestli ty fotky budou větší, může upload trvat i několik minut.

I když je to na programování řádově těžší, tak mnohem lepší je zpracovat vše co mohu, dočasně uložit a vyžádat si opravu jen toho, co bylo špatně. Ještě lepší je zapojit do uploadu javascript, odesílat na pozadí (na pozadí se i validuje) a případná chyba se zobrazí ještě před odesláním formuláře. Takhle fungují třeba web mail klienti.

Docela jednoduchý workaround je použít javascript, viz např. How to validate upload file size and file extension using JavaScript, který dokáže zkontrolovat velikost a extenzi. Tím lze odchytit věšinu problémů ještě před zahájením uploadu. V moderních prohlížečích lze pomocí canvasu v javascriptu obrázek i zmenšit (Resizing and Cropping Images with Canvas), je to lepší, než uživateli nadávat, že má moc velké obrázky. Koho má bavit dělat zmenšeniny z originálů, někam je ukládat a pak uploadovat...

A další věc k použitelnosti, proč vyžadujete jpg?
ForestCZE
Profil
Alphard:
Vás budou uživatelé milovat
Já zase miluju taková moudra, když ani nevíte, na co to potřebuji a že to nebude veřejně přístupný upload...

A další věc k použitelnosti, proč vyžadujete jpg?
Protože za prvé jak jsem psal v první citaci a za druhé jsem ještě neviděl fotky z foťáku v png nebo gif...
Alphard
Profil
Já chtěl pomoc. Ostatně, jak to provést jsem naznačoval již ve svém prvním příspěvku [#7] Alphard.

Ten cyklus by mohl vypadat takhle.
function processImageUpload() {
  // počet uploadovaných snímků
  $imgsCount = count($_FILES['expozice']['tmp_name']);

  // validace předchází zpracování
  for ($key = 0; $key < $imgsCount, $key++) {
    if (($state = isValidImageUpload($key)) !== true) {
      echo $state; // vypsání chyby, nebo ji můžete vrátit pomocí return
      return false; // přeruš zpracování
    }
  }

  // upload je validní, uložíme snímky
  for ($key = 0; $key < $imgsCount, $key++) {
    saveImage($key);
  }

  return true;
}

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: