Diskuze: Upload obrázku do zatím neexistující složky
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Tvůrce
Zobrazeno 41 zpráv z 41.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Preco tu zlozku nevytvoris riadok pred tym ako movnes ten uploadnuty subor?
A co znamena nechce fungovat? Co ti to pise? Aka chyba? Hori ti pocitac? Rozpada sa klavesnica?
Tiež ma to zaujíma prečo si na to nevytvorí funkciu ktorá mu najprv vytvorí zložku a potom to tam nahrá ...
Prípadne ak to ešte nejako ošetruješ tak by som to nechal na JS prípadne napísal ešte jednu funkciu ktorá by sa o to postarala ešte pred nahraním a vytvorením zložky ...
$path = './obrazky/' . $_SESSION['inzeraty']['ID'] . '/';
mkdir($path, 0644);
move_uploaded_file($_FILES['file']['tmp_name'], $path . $_FILES['file']['name']);
Vzhledem k tomu, že se stále učím a mám ještě dlouhou cestu před
sebou, tak ukážu vlastní kod, který používám. Co se týká kodu pro
zpracování obrázků a následného nahratí, tak část je vygooglena a jen
upravena pro svoje účely a zároveň to obsahuje určité chyby/věci které
by tam třeba nemuseli být, nebo by se mohli udělat lépe. Na víc je to už
trochu starší kod, který aktuálně mám jinak. Zároveň to obsahuje
kompresi velikosti.
Rozhodně není problém ve funkčnosti, pakliže do toho nacpeš co je
požadované!
class InzeratyObrazky
{
public function zmenitVelikost($Cesta, $CestaNova)
{
$SirkaNova = 640;
if(!file_exists($Cesta)) die("Soubor $Cesta neexistuje.");
$info = getimagesize($Cesta);
$SirkaStara = $info[0];
$VyskaStara = $info[1];
if($SirkaStara < 640)
{
$SirkaNova = $SirkaStara;
}
if($SirkaStara == 0 || $VyskaStara == 0)
die("Jedna ze stran (nebo obě) jsou nulové.");
$PomerStran = $SirkaStara / $VyskaStara;
$VyskaNova = (int) round($SirkaNova / $PomerStran, 0);
switch($info[2])
{
case IMAGETYPE_GIF: $fOpen = "imagecreatefromgif"; $fSave = "imagegif"; break;
case IMAGETYPE_JPEG: $fOpen = "imagecreatefromjpeg"; $fSave = "imagejpeg"; break;
case IMAGETYPE_PNG: $fOpen = "imagecreatefrompng"; $fSave = "imagepng"; break;
default: die("Nelze určit typ obrázku.");
}
$img_puvodni = $fOpen($Cesta);
if(!$img_puvodni) die("Nelze načíst původní obrázek.");
$img_novy = imagecreatetruecolor($SirkaNova, $VyskaNova);
if(!$img_novy) die("Nelze vytvořit nový obrázek.");
$resize = imagecopyresized(
$img_novy, $img_puvodni, 0, 0, 0, 0,
$SirkaNova, $VyskaNova, $SirkaStara, $VyskaStara);
if(!$resize) die("Stala se chyba při změně rozměrů.");
$save = $fSave($img_novy, $CestaNova);
if($save) Kontroler::msg("Velikost obrázku byla úspěšně změněna.");
else Kontroler::msg("Nepodařilo se uložit nový obrázek.");
}
public function nahrajObrazek($soubor, $soubor_name, $soubor_size, $ces, $uzivatel)
{
// Převod na MB!
$soubor_size = $soubor_size/1024/1024;
// Je soubor menší než je maximální možná velikost?
if($soubor_size > 5)//maximalni velikost souboru je 5MB
echo "Soubor je větší než maxilmální možný soubor";
//pokud je menší :: už se soubor náhrál na server??
else if(is_uploaded_file($soubor))
{
// samotný skript
// zjistí příponu souboru a převede ji na malá písmenka
$pripona = strtolower(pathinfo($soubor_name, PATHINFO_EXTENSION));
if(!($pripona == 'jpg' OR $pripona == 'jpeg' OR $pripona == 'png' OR $pripona == 'gif'))
{
Kontroler::msg("Nahrané fotky nemají podporovaný formát. Pouze jpg, jpeg, png, gif");
echo "<script>window.location.replace('./?p=novyinzerat2');</script>";
exit;
}
if($uzivatel == 'neregistrovany')
{
$ces = $_SESSION['inzerce']['id'];
$cesta = "inzeraty_obrazky/neregistrovany/".$ces."/"; //zde je cesta ke složce, do které budeme ukládat soubory
}
if($uzivatel == 'registrovany')
{
$ces = $_SESSION['inzerce']['id'];
$cesta = "inzeraty_obrazky/neregistrovany/".$ces."/"; //zde je cesta ke složce, do které budeme ukládat soubory
}
// Pokud už existuje složka se stejným názvem, tedy příponou uploadovaného soubrou, nic nevytvářej, jinak vytvoř adresář, kam uložime později uploadovaný soubor
if(!file_exists($cesta)) mkdir($cesta, 0777 );
//přesune soubor na požadované místo, pokud ne, vyhodí chybu
if (copy($soubor, $cesta."/".$soubor_name))
{
$resize = $cesta."/".$soubor_name;
$this->zmenitVelikost($resize, $resize);
//není potřeba informace
Kontroler::msg("Vše bylo v pořádku nahráno. <br> - Již zadejte email a heslo k dokončení. <br> - Nutné vyplnit pro potvrzení a další úpravu.");
}
else{echo "Při nahrávání souboru došlo k chybě!";}
}
}
}
A takto to tam láduji:
//Limit kolik fotek se nahraje
if($_FILES['obrazky'])
{
for($i=0; $i < 5; $i++)
{
$fotky->nahrajObrazek($_FILES['obrazky']['tmp_name'][$i], $_FILES['obrazky']['name'][$i], $_FILES['obrazky']['size'][$i], $_SESSION['inzerce']['id'], 'neregistrovany');
}
}
A když budeš chtít, tak ti vysvětlím některé procesy kdyby jsi něčemu nerozuměl. Z hlavy bych tohle nenapsal, ale kod chápu a vím dobře co dělá !
@Michal Kuba : Jedna sa o ciselnu reprezentaciu pristupovych prav. Pogoogli chmod.
https://cs.m.wikipedia.org/wiki/Chmod
Chmod, docela důležitá věc v tom smyslu jestli nechceš aby ti někdo třeba přepsal indexy, apod..
Ozývám se zase po delší době, stále jsem nepřišel tomu na kloub.
Už si v pohodě vytáhnu ID, který potřebuju a vytvořím si i složku,
jenže se do ní nejspíš nic nenahraje a když chci tu složku s ID otevřít,
tak mě to tam nepustí a hodí chybu.
Dělám to tímto kódem:
$uploadDir = './obrazky/'. $id; // adresar, kam se maji nahrat obrazky (bez lomitka na konci)
mkdir($uploadDir, 0644);
$allowedExt = array('jpg','JPG','JPEG','PNG', 'jpeg', 'png', 'gif', 'xls', 'xlsx', 'doc', 'docx', 'txt'); // pole s povolenymi priponami
// zpracovani uploadu
if(isset($_FILES['obrazek']) && is_array($_FILES['obrazek']['name'])) {
$counter = 0;
$allowedExt = array_flip($allowedExt);
foreach($_FILES['obrazek']['name'] as $klic => $nazev) {
$fileName = basename($nazev);
$tmpName = $_FILES['obrazek']['tmp_name'][$klic];
// kontrola souboru
/*if(
!is_uploaded_file($tmpName)
|| !isset($allowedExt[strtolower(pathinfo($fileName, PATHINFO_EXTENSION))])
) {
// neplatny soubor nebo pripona
continue;
}*/
// presun souboru
if(move_uploaded_file($tmpName, "{$uploadDir}".DIRECTORY_SEPARATOR."{$fileName}")) {
++$counter;
}
}
$this->pridejZpravu('Soubor by úspěšně nahrán na server.');
}
Mě to vlastně na konci nevyhodí ani tu hlášku o nahrání, když dám else tak to právě napíše, že se to nepodařilo nahrát.. Co dělám špatně k sakru?
Tohle je ta chyba co mi skáče v Total Commanderu:
CWD 247
550 Can't change directory to 247: Permission denied
247 je aktuálně největší ID inzerátu, tedy i složky, která se vytvoří a má se tam nahrát soubor..
Nemas prava vytvaret nove adresare v danym adresari...
Jakože složku s ID ještě vytvořit můžu, ale obrázek tam dát už ne?
Jde to nějak obejít nebo to budu muset nahrávat úplně někam jinam?
pro kontrolu, dej vytvorenemu adresari chmod 777.
Hmm, práva čtení a zápisu by měli pro vlastníka stačit.
Avšak pokud neprojde i 777, tak mám dojem, že ftp účet není brán jako
vlastník.
Takže možná bude chyba na straně hostingu.
Jo, tak CHMOD na 777 pomohl, že už tu složku otevřu, ale ten soubor se mi tam nenahrál :/
V tom kódu mám nějakou uploadovací chybu nebo proč tam není ten obrázek? :/
Hmm, nebugue tam ta konstanta DIRECTORY_SEPARATOR? Zkus ji nahradit '/', i když teoreticky by mělo projít \, ale záleží na OS kde běží server.
pořád to nejde.. Ale přísahal bych, když jsem to měl někdy úplně původně tak se ty obrázky dokázaly nahrát, když jsem to ještě nedělal do složek podle ID.. zkusím to dát nějak do podoby jako dřív..
Nemá ta cesta pro move vypadat takhle?
$uploadDir = './obrazky/'. $id . '/';
PS: Hodi ti vůbec php nějakou chybu? Máš zapnuté zobrazovaní chyb? Pokud nehodí, tak se to asi nahrává někam jinam(pohledej v jiných složkách), nebo to ani k příkazu "move" nedojde
Taky jsem měl podobný problém, ale po asi 3 dnech jsem zjistil že se vše nahrálo, úplně jinam
Já tam to lomítko mám, nebo ho potom dám před ten FILES.. podívám se ,jestli to není někde jinde, ale nevím tedy..
Mám tam nastaveno, že pokud vše projde v pořádku tak to má vypsat, že se obrázek nahrál, ale to nenapíše..
A máš zapnuté(v php.ini, popř. někde v nastaveních hostingu), zobrazovaní chyb?
<div class="form-group">
<label for="file">Obrázek: </label>
<input required type="file" class="form-control" name="file" value="<?= htmlspecialchars( $_SESSION['inzerat']['file']); ?>"/>
</div>
část formuláře právě pro obrázek -> ted jsem všechno z 'obrazek' přejmenoval na 'file', jen pro pořádek
Nemáš tam podporu pro multi upload. Přidej attribut multiple, odeber value to je kravina a změň name na file[].
Takže upload se nevykonal, jelikož se nejednalo o pole.
upravil jsem to takto:
<div class="form-group">
<label for="file">Obrázek: </label>
<input multiple required type="file" class="form-control" name="file[]" />
</div>
ale stále se obrázek nenahraje ://
A tu hlášku
Soubor by úspěšně nahrán na server.
ti to vypíše?
Ještě mě napadá zda nemáš u formuláře enctype="multipart/form-data".
Edit: Protože dle všeho $_FILES ti neexistuje.
Jestli ten atribut u formuláře mám? Teď ano, předtím ne. Ale ani v jednom případě to podle mě nešlo.. Enctype tam má teda být?
Pro odesílání souborů přes formulář to je nutné..
tak přesně to tam mám.. už mi z toho jde zase hlava kolem.. dnes už asi nic nevymyslím, zítra ráno až vstanu to zkusím zase nějak vyzkoušet. Ale za jakýkoliv nápady budu rád, už jsem toho ozkoušel fakt hodně..
je zajímavý, že když vymažu část s uploadem a místo toho udělám toto:
else if(empty($_FILES['file'])){
$this->pridejZpravu('Nebyl vybrán obrázek');
}
Tak to nevyhodí tu hlášku, takže FILES existuje?
Zkusil jsem ještě napsat na podporu mého hostingu, možná mi dají nějaké dobré vysvětlení nebo povolí nahrávání souborů.
PROBLEM SOLVED!!
Zkusil jsem si pomocí print_r vypsat co mám v $_FILES['obrazek'] úano, opět
jsem to pojmenoval obrazek a ne file) a stačilo tento kód
$path = './obrazky/' . $id . '/';
mkdir($path, 0777);
move_uploaded_file($_FILES['obrazek']['tmp_name'], $path . $_FILES['obrazek']['name']);
upravit na
$path = './obrazky/' . $id . '/';
mkdir($path, 0777);
move_uploaded_file($_FILES['obrazek']['tmp_name'][0], $path . $_FILES['obrazek']['name'][0]);
Zapotil jsem se ale konečně se to nahrává kam má!
A ted si sobecky dám dám fajfku!
A ještě mě tak napadá, ale to začínám teprv zkoušet a hledat. Když takhle do složky uživatel nahraje sice zatím jednu fotku a chci ji potom vytáhnout, je nějaký html výběr něco jako
<img src="../obrazky/234/*.*">
který vytáhne všechny obrázky? Protože nevím, jak to má člověk pojmenovaný a jakou má příponu. Nebo mám chtít nahrávat třeba jen jpg a to potom skriptem přejmenovat například na 1,2,3.. a vytahovat to takto?
Přes glob:
foreach(glob('./obrazky/234/*.jpg') as $file){
echo '<img src="./obrazky/234/' . $file . '">';
}
Zobrazeno 41 zpráv z 41.