Autor Zpráva
Lukas_K
Profil
Pro web http://asy-metri.wz.cz/ tvořím administrační část (administraci novinek) a potřebuji vytvořit upload obrázků. Web běží na serveru webzdarma.cz a obrázky by se měli nahrávat do složky obrazky. Níže uvedený kód mi však nefunguje (obrázek se na server neuploaduje, je nutné jej tam přes ftp, např. prostřednictvím TC, zkopírovat). Pro jednoduchost mám zatím povolené jen jpg obrázky. Moc prosím o radu, jak rozchodit upload.
 <?php
  if (isset($_FILES['fupload']))
  {
    print "název: ".           $_FILES['fupload']['name']       ."<br />";
    print "velikost: ".        $_FILES['fupload']['size'] ." bajtů<br />";
    print "dočasné umístění: ".$_FILES['fupload']['tmp_name']   ."<br />";
    print "typ:  ".            $_FILES['fupload']['type']       ."<br />";
    print "chyba: ".           $_FILES['fupload']['error']      ."<br />";
    if ($_FILES['fupload']['type'] == "image/pjpeg")
    {
      $nazev_souboru = $_FILES['fupload']['tmp_name'];
      $cil = "obrazky/".$_FILES['fupload']['name'];
      move_uploaded_file($nazev_souboru, $cil)
        or die ("Přenesený soubor nelze zkopírovat");

      $size = getImageSize($cil);
      $html_img_str  = "<p><img width=\"$size[0]\" height=\"$size[1]\" ";
      $html_img_str .= "src=\"$cil\" alt=\"přenesený obrázek\" /></p>";
      print $html_img_str;
    }
  }
  ?>
  <form enctype="multipart/form-data"
      action="<?php print $_SERVER['PHP_SELF']?>" method="post">
      <p>
         <input type="hidden" name="MAX_FILE_SIZE" value="256000" />
         <input type="file" name="fupload" style="width: 500px;"/><br />
         <input type="submit" value="Odeslat soubor" />
      </p>
  </form> 
Alphard
Profil
První podmínka se provede, řádky 4 až 8 se vypíší?
Lukas_K
Profil
Alphard jj, přesně tak
Alphard
Profil
Z vás abyc člověk tahal každou inforamaci. Provede se druhá podmínka, tj. vypíše se chyba na řádku 14 nebo ten text na řádku 19? Je typ výše vypsaný skutečně 'image/pjpeg'? Vypiše se nějaká jiná chyba?
Lukas_K
Profil
Alphard:
Pardon, pokud uploaduji jiný obrázek než typu jpg, vypíše mi to chybu, jejiž výpis zařizuje osmý řádek. Provede se druhá podmínka a vypíše se řádek 14, mně se ale nevypíše žádná chyba a obrázek zůstává pouze v dočasném úložišti (tmp). Řádek 16 až 19 je zde proto, aby se zobrazil uploadovaný obrázek, což také nefunguje...
Alphard
Profil
Lukas_K:
Provede se druhá podmínka a vypíše se řádek 14, mně se ale nevypíše žádná chyba
Takže to vypadá na obvyklý problém s právy k adresáři a zakázaný výpis chyb.

Testujete na ostrém hostingu, ten jede na Linuxu. Víte, jak se nastavuji práva k souborům? Adresáři obrazky nastavte přes ftp požadovaná práva (777 povoluje vše, i když je zbytečně benevolentní, nenarazíte na problémy) a snad to půjde.
Lukas_K
Profil
Alphard:složka "obrazky" už má nastavené atributy 777 a pořád to nefunguje, resp. nic se nezměnilo, tak nevím. Ale díky moc za ochotu...
Alphard
Profil
Vhodná práva jsou nutná podmínka, to nebyla zbytečná práce. Teď už v tom na první pohled chybu nevidím a nikdo jiný se také neozývá, takže doporučuji povolit výpis chyb a přečíst si, kde je problém.
Šéva
Profil
Lukas_K:
Zdravím, ještě co mne napadlo, máte script na upload obrázků ve stejné úrovni jako složku, do které chcete obrázky nahrát? Jak jste se zmínil o tom, že je to v administraci, tak mne napadlo, zda není soubor se scriptem jinde než složka s obrázky. V případě že ano, tak si zkontrolujte cestu ke složce s obrázky na řádku 12. Zkuste třeba použít $_SERVER["DOCUMENT_ROOT"] a zbytek cesty.
Lukas_K
Profil
Šéva:
Taky zdravím, děkuji za příspěvek, tušil jsem, že to bude zřejmě cestou, tedy řádkem 12. Jj, skript je ve složce administrace, zatímco složka obrazky je v kořenovém adr. Podle stránky forum.c4.cz/path-pro-vsechny-adresare-t337.htm jsem zmíněnou funkci použil takto: $cil = $_SERVER["DOCUMENT_ROOT"]."/obrazky/".$_FILES['fupload']['name']; (vč. lomítka před názvem složky), zkoušel jsem ještě absolutní cestu : $cil= $_SERVER["DOCUMENT_ROOT"]."asy-metri.wz.cz/obrazky/".$_FILES['fupload']['name']; (vč. http:// před asy-metri), ale pořád skript nefunguje, zřejmě funkci používám špatně...
Rellik
Profil
Můžeš vyzkoušet http://firstpage.rellik.eu/?page=upl
Jinak podle toho, jak popisuješ ty cesty, bych řekl, že je chyba tady. Pokud máš složku, kam se má uploadovat, o řád výš než složku se scriptem, tak zkus dát absolutní cestu: $cil = "../obrazky/".$_FILES['fupload']['name'];
jestli teda máš strukturu asi takovou:
root----|----obrazky
        |__administrace --/--upload.php
Lukas_K
Profil
Rellik:
Díky moc! Použil jsem kód, který byl na Tebou doporučené stránce a když jsem zadal absolutní cestu ke složce, tak skript zafungoval tak, jak má. Ještě jednou díky, Lukáš
Lukas_K
Profil
Na upload obrázků jsem použil tento kód:
<?php
$slozka = "../obrazky/"; // složka do které se uploadovaný soubor uloží
$soubor = $_FILES["file"]["name"]; //zasílaný soubor
$podpora = array('image/jpeg','image/jpg','image/pjpeg','image/gif','image/png'); //  povolené soubory (jpg, gif, png)
if (isset($soubor)) // pokud je soubor odeslán
{
    if (in_array($_FILES["file"]["type"],$podpora)) // je zkontrolován jestli je podporován jeho upload
        { 
         if (is_uploaded_file($_FILES["file"]["tmp_name"])) // ověří se jeho upload to dočasné složky
             {
              $name = $_FILES["file"]["name"]; // zjištění jména souboru a na dalším řádku jeho přejmenování
              $rename = strtr($name, "áčďéěíňóřšťúůýž ÁČĎÉĚÍŇÓŘŠŤÚŮÝŽABCDEFGHIJKLMNOPRSTUVWXZ","acdeeinorstuuyz_acdeeinorstuuyzabcdefghijklmnoprstuvwxz");
              if (move_uploaded_file($_FILES["file"]["tmp_name"], $slozka.$rename)) // ověření uploadu do zadané složky
               {
                echo "<br />Soubor \"".$name."\" byl uploadován a přejmenován na \"".$rename."\".<br/><img src=\"$slozka.$rename\">"; // výpis úspěšnosti
               }    
             } else {
                      echo "Nastala chyba! Soubor nebyl nahrán!"; // Pokud upload neproběhne správně vypíše se chyba
                      }
         }
        else {
                echo "Tento soubor není podporován!"; // Pokud není soubor podporován vypíše se chyba 
                }
}
?>
Dvanáctý řádek kódu s funkcí strtr (která by měla převést písmena s háčky a čárky na písmena bez diakritického znaménka a nahradit mezeru podtržítkem) však nepracuje jak má, např. soubor s názvem "Sdružení řidičů.JPG" přejmenuje na "Sdruvyenxuzvcidiilvs.JPG". Zkoušel jsem jiné uspořádání znaků na dvanáctém řádku, ale výsledkem byly pouze odlišné zkomoleniny. Chtěl bych tedy poprosit o radu jak kód upravit, aby funkce strtr pracovala správně... Kódování stránky je utf8, pokud by to na to mělo mít nějaký vliv...
Enko
Profil *
Lukas_K:
Ahoj Lukáši,
v tvém programu nedomýšlíš spoustu věcí. Například necháváš nahranému souboru stejné jméno, jen z něj odstraníš diakritiku. Toto je špatně protože ti můžou vzniknout duplicity, respektive si v případě duplicit přehraješ ten původní. Zkus ho pojmenovat třeba pomocí funkce uniqid() a i přesto musíš kontrolovat na duplicity.
Dále doporučuju na zachytávání chyb používat http://php.vrana.cz/ukladani-souboru-od-uzivatele.php. Řeší to všechny možnosti chyb. A nespoléhej na toto: if (in_array($_FILES["file"]["type"],$podpora)) // je zkontrolován jestli je podporován jeho upload. Jde to lehce podvrhnout. Opravdové zjištění koncovky souboru se řeší přes PATHINFO_EXTENSION(viz odkaz výše).
Pak je taky dobré nastavit maximální velikost nahrávaného obrázku. Další hezký návod máš tady: [url=http://php.vrana.cz/zmensovani-obrazku.php/url]http://php.vrana.cz/zmensovani-obrazku.php/url]
Dále mě napadlo, že pokud chceš odstraňovat diakritiku, tak doporučuji používat funkci odsud: http://php.vrana.cz/vytvoreni-pratelskeho-url.php. To jen tak v rychlosti, co mě napadlo k tvému dotazu.

Měj se :)
Lukas_K
Profil
Enko:
Díky moc za rady, můj program je nyní domyšlenější, viz:
<?php
$koncovky = array('jpg', 'jpeg', 'png', 'gif');
if (!$_FILES || $_FILES["obrazek"]["error"] == UPLOAD_ERR_INI_SIZE) {
    echo ("Maximální velikost obrázku je " . ini_get('upload_max_filesize') . ".\n");
} elseif ($_FILES["obrazek"]["error"] == UPLOAD_ERR_NO_FILE) {
    echo ("Nevybrali jste soubor, který chcete nahrát.\n");
} elseif ($_FILES["obrazek"]["error"]) {
    echo ("Soubor se nepodařilo nahrát, kontaktujte prosím správce serveru.\n");
} elseif (!in_array(strtolower(pathinfo($_FILES["obrazek"]["name"], PATHINFO_EXTENSION)), $koncovky)) {
    echo ("Koncovka souboru musí být jedna z: " . implode(", ", $koncovky) . ".\n");
} elseif (!($imagesize = getimagesize($_FILES["obrazek"]["tmp_name"])) || $imagesize[2] > 3) {
    echo ("Typ obrázku musí být JPG, PNG nebo GIF.\n");
} else {    
    $name = $_FILES["obrazek"]["name"]; // zjištění jména souboru a na dalším řádku jeho přejmenování
    $rename = strtr($name, "áčďéěíňóřšťúůýž ÁČĎÉĚÍŇÓŘŠŤÚŮÝŽABCDEFGHIJKLMNOPRSTUVWXZ","acdeeinorstuuyz_acdeeinorstuuyzabcdefghijklmnoprstuvwxz");
    if (move_uploaded_file($_FILES["obrazek"]["tmp_name"], "../obrazky/$id-" . $rename))
      {
      echo "<br />Soubor \"".$name."\" byl uploadován a přejmenován na \"".$rename."\".<br/><img src=\"$slozka.$rename\">"; // výpis úspěšnosti
      }
    echo ("Obrázek byl úspěšně nahrán.");
}
?>
avšak problém s přejmenováním obrázků pořád nemám vyřešen, zůstává stejný jako v mém předchozím příspěvku. Ještě mě zlobí, že při novém přihlášení a následném vstupu na stránku s uploadem se vždy zobrazuje hláška "Maximální velikost obrázku je 4M." ze čtvrtého řádku kódu. Ale to je spíše detail...
panther
Profil
Lukas_K:
Ještě mě zlobí, že při novém přihlášení a následném vstupu na stránku s uploadem se vždy zobrazuje hláška "Maximální velikost obrázku je 4M."
protoze nikde nekontrolujes podminkou, zda byl odeslan formular. Pak je tedy splnena podminka !$_FILES a vypsana hlaska.
Rellik
Profil
panther:
protoze nikde nekontrolujes podminkou, zda byl odeslan formular.
Je to informace o tom jak veliký jde odeslat soubor podle povolní servru. Kdybys chtěl nahrát větší, tak se prostě nenahraje. Je to prostě limit uploadu nastavený přímo v konfiguraci servru. Jinak viz panter.
Lukas_K
Profil
panther, Rellik: Díky moc, mělo mě to napadnout, tohle jsem ale moc neřešil. Netušíte ještě co by mohlo způsobovat špatné přejmenovávání? Proč např. ž přepíše program na "vy" místo na z, í na "xu" místo i apod? Je potřeba ke 14. a 15. řádku ještě připsat nějaká podmínka...?
Enko
Profil *
Lukas_K:
K tomu přejmenování obrázků, pokud už z nějakého nevyhnutelného důvodu musíš zachovávat původní jméno souboru a v žádném případě se tomu nemůžeš vyhnout, používej tuto funkci od Jakuba Vrány, jen na první pokus nemusí fungovat přesně tak, jak potřebuješ. Stačí si přečíst co k tomu Jakub píše anebo nahlédnout do dokumentace k jednotlivým funkcím. Jinak je nejlepší(nebo spíše nejuniverzálnější řešení) soubor přejmenovávat pomocí uniqid s prefixem a druhým parametrem true. Odstraňování diakritiky pomocí funkce strtr apod je zbytečně velice náročné a dost často na něco zapomeneš, když stačí využívat nativní vlastnosti přímo z php.
Lukas_K
Profil
Enko:
Ok, díky moc za představení funkce. Měl jsem zkušenosti jen se strtr.

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:

0