Autor Zpráva
lenka
Profil *
Ahoj mám fotogalerii kterou ukládám do DB a soubory nahrávam na servr do adresáře. Teď se lopotím s tím abych mohla vymazat nějaké fotky určitého druhu a s nimi i ty soubory nahrané na servru. Z databaze to vymažu jednoduše to mi je jasné ale jde mi hlavně o ty soubory v adresáři. Napadlo mě načíst názvy souboru do pole a to pak celé nějak smazat, ale moc netuším jak to formulovat.
<?php  
                $query = "SELECT * FROM foto where druh = 'sport'; 
                $vysledek = mysql_query($query, $link) or die("SQL dotaz neni mozno provézt");
                while ($zaznam=MySQL_Fetch_Array($vysledek))
                   {
                    $pole[] =$zaznam["foto"];
}
 ?>
No a teď bych to měla asi smazat pře
unlink
ale bohužel ten zápis se mi nedaří…

Děkuji za rady.

Moderátor panther: Vkládej prosím kódy mezi značky [pre] a [/pre] (stačí kliknout na ).
Alphard
Profil
Do pole to ani nemusíte načítat. V cyklu while dejte hned unlink().
lenka
Profil *
Myslíte nějak takto?

<?php  
                $query = "SELECT * FROM foto where druh = 'sport'; 
                $vysledek = mysql_query($query, $link) or die("SQL dotaz neni mozno provézt");
                while ($zaznam=MySQL_Fetch_Array($vysledek))
                   {

                       echo  (" <a href='smazat?soubor=".$zaznam["foto"]."'>Smazat</a>");
                    }
 ?>
Soubor smazat.php:
<?php
 $smazat = $GET_["soubor"];
 unlink("../fotogalerie/foto/$smazat");
 
$path= 'http://' . $_SERVER['SERVER_NAME'] . dirname($_SERVER['SCRIPT_NAME']) . '/fotogalerie.php'; 
Header("Location:".$path); 
exit; 
 
?>


Takto mi to ale nemaže
Taps
Profil
lenka:
zkus
<?php  
                $query = "SELECT * FROM foto where druh = 'sport'"; 
                $vysledek = mysql_query($query, $link) or die("SQL dotaz neni mozno provézt");
                while ($zaznam=MySQL_Fetch_Array($vysledek))
                   {
                    unlink("../fotogalerie/foto/".$zaznam["foto"]);
}
 ?>
Moderátor Alphard: Opravil jsem chybějící uvozovku.
lenka
Profil *
A šlo by to udělat abych to měla jako ten odkaz jak jsem zkoušela aby se mi to smazalo až po kliknutí?
Taps
Profil
lenka:
<?php  
                $query = "SELECT * FROM foto where druh = 'sport'"; 
                $vysledek = mysql_query($query, $link) or die("SQL dotaz neni mozno provézt");
                while ($zaznam=MySQL_Fetch_Array($vysledek))
                   {

                       echo  (" <a href='smazat.php?soubor=".$zaznam["foto"]."'>Smazat</a>");
                    }
 ?>

<?php
 $smazat = $GET_["soubor"];
 unlink("../fotogalerie/foto/".$smazat);
 
$path= 'http://' . $_SERVER['SERVER_NAME'] . dirname($_SERVER['SCRIPT_NAME']) . '/fotogalerie.php'; 
Header("Location:".$path); 
exit; 
 
?>
AM_
Profil
Taps:
to je dost odvážné řešení.
smazat.php?soubor=../../index.php
//koukám že už to takhle měla lenka... není to vůbec zabezpečené, takhle může kdokoli smazat jakýkoli soubor na tvém webu! (na nastavení oprávnění přístupu ke složkám bych se nespoléhal.)
Nejednodušší ochrana je asi toto:
$smazat = basename($_GET["soubor"]); //extrahuje z případné cesty jméno souboru, čímž eliminuje možnost smazat něco jiného, než soubor z adresáře fotogalerie/foto


lenka:
$GET_["soubor"];
má to být $_GET

Z databaze to vymažu jednoduše to mi je jasné
nikde tu nevidím, že bys to mazala z databáze. bylo by dobré ten kus kódu ukázat.

Napadlo mě načíst názvy souboru do pole a to pak celé nějak smazat
z toho mi vyplývá, že chceš mazat víc souborů najednou. Zde zaslaná řešení je ale mažou po jednom (klikneš na jedno "smazat" -> smaže se jeden soubor). Jak to tedy vlastně chceš?
lenka
Profil *
Takto mám přesně takto ale bohužel mi nic nemaže, smazou se mi udaje akort z databaze ale soubory ne:
<?php  
                $query = "SELECT * FROM foto where druh = 'sport'"; 
                $vysledek = mysql_query($query, $link) or die("SQL dotaz neni mozno provézt");
                while ($zaznam=MySQL_Fetch_Array($vysledek))
                   {
                   echo  (" <a href='smazat-foto.php?sezona=".$zaznam["sezona"]."&druh=".$zaznam["druh"]."'>Smazat</a>");
                   }
 ?>

Soubor smazat-foto.php:
<?php
$sezona=$_GET["sezona"];
$druh=$_GET["druh"];
$query = "SELECT * FROM foto WHERE sezona = '$sezona' and druh = '$druh'";
$vysledek = mysql_query($query, $link) or die("SQL dotaz nešlo provézt");
          while ($zaznam=MySQL_Fetch_Array($vysledek))
                   {
                    unlink("../fotogalerie/foto/".$zaznam["foto"]);
                   }

$vysledek=mysql_query($q="delete from foto where sezona = '$sezona' and druh = 'extraliga'");

$path = 'http://' . $_SERVER['SERVER_NAME'] . dirname($_SERVER['SCRIPT_NAME']) . '/fotogalerie.php';      
Header("Location:".$path); 
?>
AM_
Profil
a řádek 8 se provede a nic nesmaže, nebo se to do toho cyklu ani nedostane? vypiš si adresu té fotky, kterou se snažíš mazat (to co je ve funkci unlink), podívej se, zda fotka opravdu existuje... chybové hlášky máš zapnuté?

lenka:
mysql_query($query, $link)“ parametr $link můžeš vynechávat, tak bych ho tam zbytečně nedával, určitě ne tak že jednou ano jednou ne.
lenka
Profil *
Když si vypíšu
echo $zaznam["foto"];
před unlink tak tam ten název souboru vidím, ale jenom jeden. Pak to ale nesmaže nic a chtěla bych smazat všechny soubory daného druhu, ale echo mi vypiše pouze jeden.
lenka
Profil *
Omlouvám se měla jsem chybu v cestě, už mi to i maže soubory, ještě bych tě poprosila s tou ochranou jak jsi psal basename kam bych to měla začlenit. A to že mi echo vypsalo pouze ten jeden soubor ale smazali se všechny co jsem chtěla to je normální?
panther
Profil
lenka:
A to že mi echo vypsalo pouze ten jeden soubor ale smazali se všechny co jsem chtěla to je normální?
záleží, kam to echo dáš. Předpokládám, že jsi ho dala mimo cyklus while, a pak je to v pořádku. Kdybys ho dala dovnitř cyklu, vypíší se všechny názvy.
AM_
Profil
lenka:
ještě bych tě poprosila s tou ochranou jak jsi psal basename kam bych to měla začlenit
když to máš takhle tak nikam, předtím ten tvůj kód mazal jinak. takhle bys jen měla mít ošetřené $sezona a $druh funkcí mysql_real_escape_string než je vložíš do dotazu na 4. řádku.
lenka
Profil *
Takto to oštření stačí?
<?php  
                $query = "SELECT * FROM foto where druh = 'sport'"; 
                $vysledek = mysql_query($query, $link) or die("SQL dotaz neni mozno provézt");
                while ($zaznam=MySQL_Fetch_Array($vysledek))
                   {
                       $zaznam["sezona"] = mysql_real_escape_string($zaznam["sezona"]);
                       $zaznam["druh"] = mysql_real_escape_string($zaznam["druh"]); 
                      echo  (" <a href='smazat-foto.php?sezona=".$zaznam["sezona"]."&druh=".$zaznam["druh"]."'>Smazat</a>");
                   }
 ?>
panther
Profil
lenka:
Takto to oštření stačí?
mysql_real_escape_string(), případně (int) pro číselné vstupy se používá při ukládání dat do DB, nikoliv pro jejich čtení.
Tady je to ošetření na nic, musíš ošetřovat vstupy od uživatele ještě před vykonáním SQL dotazu.

Správně tedy je v [#8] ve druhém kódu na 4. řádku toto:
$query = "SELECT * FROM foto WHERE sezona = '".mysql_real_escape_string($sezona)."' and druh = '".mysql_real_escape_string($druh)."'";
AM_
Profil
panther:
se používá při ukládání dat do DB, nikoliv pro jejich čtení.
neřekl bych při ukládání (chvíli jsem musel přemýšlet, jak to myslíš) - přesněji - pokud něco, co zadal uživatel (přišlo to z $_GET nebo $_POST), vkládáš do stringu mysql dotazu, mělo by to být ošetřené. Proč to dělat vysvětlím na klasickém příkladu:

SELECT * FROM users WHERE jmeno='${_GET['jmeno']}' AND heslo='${_GET['heslo']}'

rázem se heslo ' OR ''=' stane univerzálním heslem pro všechny uživatele :) po dosazení:
SELECT * FROM users WHERE jmeno='admin' AND heslo='' OR ''=''

escape funkce správně zakódují výskyt znaků, které by mohly ovlivnit význam SQL dotazu (především apostrofů uzavírajících proměnnou)
panther
Profil
AM:
pokud něco […] vkládáš do stringu mysql dotazu
vkládám do stringu MySQL dotazu == ukládám data do DB (z uživatelského vstupu jsem mohl dodat). Vkládání samozřejmě může být i update. Nemyslím si, že by to bylo řečeno tak, že by se nad tím muselo nějak zdlouhavě přemýšlet :-)

Každopádně je nesmysl použít mysql_real_escape_string() tak, jak je užito v [#14].
AM_
Profil
panther:
vkládám do stringu MySQL dotazu == ukládám data do DB
ukládám data do DB == INSERT, UPDATE
tahám data z DB == SELECT

v dotazu v [#15] panther dle mého názoru do DB nic neukládáš.

Každopádně je nesmysl použít mysql_real_escape_string() tak, jak je užito v [#14].
na tom se shodnem
panther
Profil
AM:
v dotazu v [#15] panther dle mého názoru do DB nic neukládáš.
áá, už vím. :-) Já žil tak nějak v představě, že v tom dotazu je INSERT, on je tam zatím SELECT. Tím se to vysvětluje, proč jsme se nemohli dohodnout. Ten příspěvek v [#15] upravím, aby tam nestrašila ta má nepozornost.
lenka
Profil *
Tak přeci ještě jedna prosba, zkouším se prohrabat tímto zápisem. Teď mi jde o smazaní jenom jednoho souboru, ale mám asi chybu někde v té podmínce if. Takto mi to napíše že : Pokus o smazani selhal. Když tu podmínku vymažu tak se soubor smaže, takže cestu mám teď v pořádku :-)

$file=$zaznam["fotka"];
echo ($file);
if(strpos($file, "../") === false && strpos($file, __FILE__) === false && is_file($file)) {
  
  unlink("../fotografie/soupiska/".$zaznam["fotka"]);
}
else {
  exit ("Pokus o smazani selhal");
}
AM_
Profil
ta podmínka je vymyšlená špatně, uprav to takhle:
$file=basename($zaznam["fotka"]);
if(is_file($file)) {
  unlink("../fotografie/soupiska/".$zaznam["fotka"]);
}
lenka
Profil *
Bohužel i takto mi to napíše že pokus selhal, přitom když vypíši
$file
a
$zaznam["fotka"]
tak se schodují a v adresáři ten soubor také mám. Bez té podmínky if se mi to smaže.
Majkl578
Profil
Já bych tu podmínku z [#21] napsal ještě jinak:
$file = __DIR__ . '/../fotografie/soupiska/' . $zaznam["fotka"];
if (file_exists($file) && @unlink($file)) { //úmyslně @, zamezí E_WARNING při chybě
  echo 'Soubor smazán.';
} else {
  echo 'Soubor nelze smazat.';
}
Předpokládám, že $zaznam["fotka"] je z databáze, a proto nebude obsahovat nic jako ../index.php. Pokud ano, je to nutné ošetřit.
lenka
Profil *
Takhle to skončí s chybou:

Notice: Use of undefined constant __DIR__ - assumed '__DIR__' in C:\wamp\www\administrace\odstranit.php on line 15
Soubor nelze smazat.

řádek 15 je ta podmínka if
panther
Profil
lenka:
Use of undefined constant
a PHP < 5.3.0, co?


Jak praví manuál, „The directory of the file. If used inside an include, the directory of the included file is returned. This is equivalent to dirname(__FILE__). This directory name does not have a trailing slash unless it is the root directory. (Added in PHP 5.3.0.)
lenka
Profil *
A jak to tedy mám udělat když mám tu nižší verzi?
__construct
Profil
lenka:
Tak ako napísal Majkl578 ale zmeníš:
//$file = __DIR__ . '/../fotografie/soupiska/' . $zaznam["fotka"];
$file = dirname(__FILE__) . '/../fotografie/soupiska/' . $zaznam["fotka"];
if (file_exists($file) && @unlink($file)) { //úmyslně @, zamezí E_WARNING při chybě
  echo 'Soubor smazán.';
} else {
  echo 'Soubor nelze smazat.';
}

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