Jednoduchý FTP klient v PHP 2.

18. února 2003

Ve druhém a závěrečném článku o tvorbě jednoduchého FTP klienta si popíšeme zbývající definované funkce a také poslední soubor aplikace.

Soubor funkce.php – pokračování

function PriradIkonu($nazev) {
   global $ikona_neznama;
   global $ikona_souboru;
   $pozice = StrRPos($nazev, „.“);
   if ($pozice) {
      $koncovka = StrToLower(SubStr($nazev, $pozice + 1));
      if ($ikona_souboru[$koncovka])
         $ikona = $ikona_souboru[$koncovka];
      else
         $ikona = $ikona_neznama;
   }
   else
      $ikona = $ikona_neznama;
   return $ikona;
}

Funkce PriradIkonu slouží k přiřazení příslušné ikonky při výpisu názvu souboru. Zpřístupníme si proměnné ikona_neznama (obsahuje jméno souboru obrázku ikonky pro nerozpoznaný typ koncovky) a ikona_souboru (obsahuje jméno souboru obrázku ikonky pro adresář). Pomocí funkce StrRPos zjistíme z názvu souboru pozici posledního výskytu znaku . a následně pomocí funkce SubStr získáme koncovku souboru. Pomocí funkce StrToLower převedeme všechny znaky na malá písmena (je rozdíl .gif a .GIF). Zjistíme, zda je v poli ikona_souboru prvek s klíčem rovným názvu koncovky, a podle toho přiřadíme do proměnné ikona buď jméno příslušného obrázku ikonky nebo použijeme jméno obrázku pro nerozpoznaný typ souboru. Totéž provedeme, pokud je název souboru bez přípony.

function Cesta2odkaz($cesta) {
   global $ftpserver;
   if ($cesta == „“) {
      $vysledek = „<a href=\“ftp.php?cesta=“.$cesta.“&“.SID.“\“>“.$_SESSION[‚ftpserver‘].“</a> / „;
   }
   else {
      $casti = Explode („/“, $cesta);
      $vysledek = „<a href=\“ftp.php?cesta=&“.SID.“\“>“.$_SESSION[‚ftpserver‘].“</a> / „;
      $vysledek .= „<a href=\“ftp.php?cesta=“.$casti[0].“&“.SID.“\“>“.$casti[0].“</a>“;
      $url = $casti[0];
      for ($i = 1; $i < Count($casti); $i++) {
         $url = $url.“/“.$casti[$i];
         $vysledek .= “ / <a href=\“ftp.php?cesta=“.$url.“&“.SID.“\“>“.$casti[$i].“</a>“;
      }
   }
   return $vysledek;
}

Funkce Cesta2odkaz vytvoří z předané cesty k aktuálnímu adresáři hypertextový odkaz, a to tak, že cestu rozdělí pomocí funkce Explode na části podle znaku /, čímž získáme pole obsahující jména adresářů tvořících cestu k aktuálnímu souboru. Potom v cyklu vytvoříme pro každý prvek tohoto pole platný odkaz na příslušný adresář. Funkce vrací řetězec obsahující přímo HTML kód odkazů.

function Krok_zpet($cesta) {
   if ($cesta == „“)
      $vysledek = „“;
   else {
      $pozice = StrRPos($cesta, „/“);
      if ($pozice)
         $vysledek = SubStr($cesta, 0, $pozice);
      else
         $vysledek = „“;
   }
   return $vysledek;
}
?>

Funkce Krok_zpet vytvoří z předané cesty cestu k nadřazenému adresáři, a to tak, že najde poslední výskyt znaku /, tento znak a všechno za ním odřízne a výsledek vrátí.

Soubor ftp.php

Hlavní a nejdelší soubor naší aplikace. Obsahuje skript starající se o vlastní přihlášení k FTP serveru a o provádění požadovaných operací (mazání, vytváření?) v závislosti na požadavku uživatele. Také se stará o zobrazení souborů, podadresářů a informacích o nich v aktuálním adresáři.

<?
session_start();
if (!IsSet($_SESSION[‚ftpserver‘])) {
   $adresa = „index.php?zprava=“.URLEncode(„Nepodařilo se připojit !“);
   Header(„Location: $adresa“);
   exit;
}

Zpřístupníme session proměnné a podle proměnné ftpserver rozhodneme, zda je stránka volána přihlášeným uživatelem či nikoli. Pokud nejde o řádně přihlášeného uživatele, provede se přesměrování na přihlašovací stránku a do URL se přidá zpráva o chybě.

require(„nastaveni.php“);
require(„funkce.php“);

Připojíme soubor s nastavením a soubor obsahující funkce.

if (!IsSet($_REQUEST[‚cesta‘]))
   $cesta = $poc_cesta;
else
   $cesta = URLDecode($_REQUEST[‚cesta‘]);

Zjistíme, zda byla předána proměnná cesta, pokud ne, nastavíme ji na hodnotu počáteční cesty definované v proměnné poc_cesta. Pole _REQUEST obsahuje proměnné předané jak pomocí metody GET, tak i POST.

$pripojeni = @ftp_connect($_SESSION[‚ftpserver‘], $_SESSION[‚port‘]);
if (!$pripojeni) {
   session_destroy();
   $adresa = „index.php?zprava=“.URLEncode(„Nepodařilo se připojit !“);
   Header(„Location: $adresa“);
   exit;
}

Pokusíme se pomocí funkce ftp_connect připojit k FTP serveru. Funkci předáváme adresu FTP serveru a číslo portu. Potlačíme výpis případné chyby. Pokud se připojení nezdaří, funkce vrací FALSE a provede se přesměrování na přihlašovací stránku s připojením chybové hlášky. Předtím je však potřeba zrušit vytvořenou session voláním funkce session_destroy. Pokud se připojení zdaří, funkce vrací ukazatel na toto připojení.

$prihlaseni = @ftp_login($pripojeni, $_SESSION[‚jmeno‘], $_SESSION[‚heslo‘]);
if (!$prihlaseni) {
   session_destroy();
   $adresa = „index.php?zprava=“.URLEncode(„Nepodařilo se přihlásit !“);
   Header(„Location: $adresa“);
   exit;
}

Pomocí funkce ftp_connect se pokusíme přihlásit k FTP serveru. Funkci předáváme ukazatel na spojení, přihlašovací jméno a heslo. Potlačíme výpis případné chyby. Pokud se připojení nezdaří, funkce vrací FALSE a provede se přesměrování na přihlašovací stránku.

switch ($_REQUEST[‚prikaz‘]) {
   case „vytvor_adresar“:
      if (!@ftp_mkdir($pripojeni, $cesta.“/“.$_POST[‚novy_adresar‘])) {
         $chyba = „Adresář se nepodařilo vytvořit !“;
      }
      break;

Proměnná prikaz slouží k předávání požadované akce uživatele mezi stránkami. Pokud je proměnná rovna řetězci vytvor_adresar, pak se skript pokusí vytvořit v aktuálním adresáři podadresář se jménem, které uživatel vyplnil ve formuláři a které je uložené v proměnné novy_adresar. K vytvoření adresáře je použita funkce ftp_mkdir, které předáme ukazatel na připojení a jméno nového adresáře včetně cesty. Pokud se adresář nepodaří vytvořit, vrací funkce FALSE a do proměnné chyba uložíme chybovou hlášku.

   case „smaz_adresar“:
      if (!@ftp_rmdir($pripojeni, URLDecode($_GET[‚adresar‘]))) {
         $chyba = „Adresář se nepodařilo smazat (je prázdný?) !“;
      }
      break;

Pokud je proměnná prikaz rovna řetězci smaz_adresar, pak se skript pokusí smazat adresář, který uživatel označil (cesta k němu je uložena v proměnné adresar). Ke smazání adresáře je použita funkce ftp_rmdir, které předáme ukazatel na připojení a cestu k mazanému adresáři. Pokud se adresář nepodaří smazat, vrací funkce FALSE a do proměnné chyba uložíme chybovou hlášku. Pokud adresář není prázdný nelze ho smazat!

   case „uloz_soubor“:
      $docasny_soubor = $_FILES[„nahravany_soubor“][„tmp_name“];
      $jmeno_souboru = $_FILES[„nahravany_soubor“][„name“];
      if (!@ftp_put($pripojeni, $cesta.“/“.$jmeno_souboru, $docasny_soubor, FTP_BINARY)) {
         $chyba = „Soubor se nepodařilo přenést !“;
      }
      break;

Pokud je proměnná prikaz rovna řetězci uloz_soubor, pak se skript pokusí uložit na server soubor, který uživatel vybral ve formuláři. Po odeslání formuláře se soubor přenese na server a je zde dočasně uložen. Jméno dočasného souboru je v proměnné $_FILES["nahravany_soubor"]["tmp_name"] a původní jméno souboru v proměnné $_FILES["nahravany_soubor"]["name"]. Tento dočasný soubor musíme pomocí funkce ftp_put uložit do požadovaného adresáře. Funkci předáme ukazatel na připojení, jméno ukládaného souboru včetně cesty, jméno zdrojového (dočasného) souboru a mód přenosu dat. Pokud se soubor nepodaří uložit, vrací funkce FALSE a do proměnné chyba uložíme chybovou hlášku.

   case „smaz_soubor“:
      if (!@ftp_delete($pripojeni, URLDecode($_GET[‚soubor‘]))) {
         $chyba = „Soubor se nepodařilo smazat !“;
      }
      break;

Je-li proměnná prikaz rovna řetězci smaz_soubor, pak se skript pokusí smazat soubor, který uživatel označil (cesta k němu je uložena v proměnné soubor). K smazání souboru je použita funkce ftp_delete, které předáme ukazatel na připojení a cestu k mazanému souboru. Nepodaří-li se soubor smazat, vrací funkce FALSE a do proměnné chyba uložíme chybovou hlášku.

   case „stahni_soubor“:
      $fp = fopen(„docasny.soubor“, „w+“);
      if (!@ftp_fget($pripojeni, $fp, URLDecode($_GET[‚soubor‘]), FTP_BINARY)) {
         $chyba = „Soubor se nepodařilo stáhnout !“;
      }
      else {
         $velikost = ftp_size($pripojeni, URLDecode($_GET[‚soubor‘]));
         header(„Cache-Control: no-cache, must-revalidate“);
         header(„Pragma: no-cache“);
         header(„Content-Type: application/zip“);
         header(„Content-Disposition: inline; filename=“.URLDecode($_GET[‚$nazev‘]).““);
         header(„Content-Length: $velikost“);
         header(„Expires: 0“);
         rewind($fp);
         fpassthru($fp);
         unlink(„docasny.soubor“);
         ftp_quit($pripojeni);
         exit;
      }
      break;
}

Pokud je proměnná prikaz rovna řetězci stahni_soubor, pak se skript pokusí o stažení požadovaného souboru, který uživatel označil (cesta k němu je uložena v proměnné soubor). Pomocí funkce fopen si vytvoříme dočasný soubor s názvem docasny.soubor. Funkcí ftp_fget se pokusíme uložit stahovaný soubor do dočasného souboru. Předáváme ji ukazatel na připojení, jméno souboru do kterého se bude ukládat (v našem případě dočasný soubor), jméno stahovaného souboru včetně cesty a mód přenosu. V případě neúspěchu vrací funkce FALSE a do proměnné chyba uložíme chybovou hlášku.

Je-li vše v pořádku, zjistíme ještě velikost stahovaného souboru pomocí funkce ftp_size. Následně odešleme příslušné hlavičky a pomocí funkce fpassthru odešleme obsah dočasného souboru (obsahuje obsah stahovaného souboru) webovému prohlížeči. Funkce rewind slouží k přesunutí ukazatele na začátek souboru. V hlavičce jsme definovali Content-Type: application/zip, čímž dosáhneme toho, že prohlížeč nabídne uložení stahovaného souboru. Tímto způsobem je možné stáhnout i soubory obsahující PHP skripty, které by se při pokusu o stažení klasickým způsobem nejprve provedly a na prohlížeč by se odeslal pouze jejich výsledek. Nakonec ještě smažeme dočasný soubor pomocí funkce unlink a uzavřeme FTP připojení pomocí funkce ftp_quit, které předáme ukazatel na připojení. Ukončíme skript.

$seznam=ftp_rawlist($pripojeni, $cesta);
require(„hlavicka.php“);
?>

Pomocí funkce ftp_rawlist načteme obsah aktuálního adresáře. Funkci předáme ukazatel na spojení a cestu k adresáři, jehož obsah chceme zjistit. Funkce vrací neformátovaný výstup a požadované údaje je nutno získat funkcemi definovanými v souboru funkce.php. Připojíme soubor s hlavičkou HTML stránky.

<body>
<table align=“center“ width=“700″ cellspacing=“1″ cellpadding=“1″ border=“0″>
  <tr class=“hlavicka“>
    <td align=“center“ nowrap><br><b><? echo $program; ?></b><br> </td>
  </tr>
</table>

Vykreslíme tabulku se jménem aplikace.

<table align=“center“ width=“700″ cellspacing=“1″ cellpadding=“1″ border=“0″>
  <tr class=“adr“>
    <td width=“320″>
      <br>
      <form action=“ftp.php“ method=“POST“>
      <table width=“100%“ cellspacing=“0″ cellpadding=“0″ border=“0″>
        <tr>
          <td width=“100%“ nowrap align=“center“>
            <b>Nový adresář:</b>
            <input type=“TEXT“ name=“novy_adresar“ size=20>
            <input type=“HIDDEN“ name=“prikaz“ value=“vytvor_adresar“>
            <input type=“HIDDEN“ name=“cesta“ value=“<? echo URLEncode($cesta); ?>“>
            <input type=“HIDDEN“ name=“<? echo session_name(); ?>“ value=“<? echo session_id(); ?>“>
            <input type=“SUBMIT“ value=“Založ“>
          </td>
        </tr>
      </table>
      </form>
    </td>
    <td width=“380″>
      <br>
      <form action=“ftp.php“ method=“POST“ enctype=“multipart/form-data“>
      <table width=“100%“ cellspacing=“0″ cellpadding=“0″ border=“0″>
        <tr class=“adr“>
          <td width=“100%“ nowrap align=“center“>
            <b>Nahrát soubor:</b>
            <input type=“FILE“ name=“nahravany_soubor“ size=20>
            <input type=“HIDDEN“ name=“prikaz“ value=“uloz_soubor“>
            <input type=“HIDDEN“ name=“cesta“ value=“<? echo URLEncode($cesta); ?>“>
            <input type=“HIDDEN“ name=“<? echo session_name(); ?>“ VALUE=“<? echo session_id(); ?>“>
            <input type=“SUBMIT“ value=“Poslat“>
          </td>
        </tr>
      </table>
      </form>
    </td>
  </tr>
</table>

Vykreslíme tabulku s formuláři pro založení nového adresáře a nahrání souboru. Pomocí skrytých polí HIDDEN předáváme proměnné cesta, ve které je uložena cesta k aktuálnímu adresáři, proměnnou prikaz, obsahující typ požadované akce. Poslední předávaná proměnná slouží k předání jména a id session, kde jsou uloženy přihlašovací údaje. Jméno session zjistíme funkcí session_name a podobně id funkcí session_id.

<?
if (IsSet($chyba)) {
?>
<table align=“center“ width=“700″ cellspacing=“1″ cellpadding=“1″ border=“0″>
  <tr class=“chyba“>
    <td align=“center“ width=“100%“><b><? echo $chyba; ?></b></td>
  </tr>
</table>
<?
}
?>

Je-li nastavena proměnná chyba, vykreslíme tabulku a vypíšeme její obsah.

<table align=“center“ width=“700″ cellSpacing=“1″ cellPadding=“1″ border=“0″>
  <tr class=“hlavicka“>
    <td nowrap><b>Aktuální adresář:</b></td>
  </tr>
</table>
<table align=“center“ width=“700″ cellSpacing=“1″ cellPadding=“1″ border=“0″>
  <tr class=“adr“>
    <td width=“580″ nowrap><b><? echo Cesta2odkaz($cesta); ?></b></td>
    <td width=“120″ align=“right“><b><a href=“index.php?prikaz=odhlasit&<? echo SID ?>“>Odhlasit se!</a></b></td>
  </tr>
</table>

Voláním funkce Cesta2odkaz vypíšeme cestu k aktuálnímu adresáři. Jednotlivé adresáře se vypíší jako hypertextové odkazy, aby bylo možno rychleji přecházet do nadřazených adresářů. Také vypíšeme odkaz na odhlášení uživatele od FTP serveru.

<table align=“center“ width=“700″ cellspacing=“1″ cellpadding=“1″ border=“0″>
  <tr class=“hlavicka“>
    <td width=“16″>&nbsp;</td>
    <td width=“304″><b>Název</b></td>
    <td width=“40″><b>Smazat</b></td>
    <td width=“100″><b>Velikost</b></td>
    <td width=“120″><b>Datum</b></td>
    <td width=“120″><b>Atributy</b></td>
  </tr>
<?
$zpet = Krok_zpet($cesta);
echo „<tr class=\“adr\“>“;
echo „<td>&nbsp;</td>“;
echo „<td nowrap><b><a href=\“ftp.php?cesta=“.URLEncode($zpet).“&“.SID.“\“>..</a></b></td>“;
echo „<td>&nbsp;</td>“;
echo „<td>&nbsp;</td>“;
echo „<td>&nbsp;</td>“;
echo „<td>&nbsp;</td>“;
echo „</tr>“;

Vykreslíme hlavičku tabulky a voláním funkce Krok_zpet do proměnné zpet uložíme cestu k nadřazenému adresáři. Vypíšeme první řádek tabulky obsahu aktuálního adresáře. Tento první řádek bude obsahovat odkaz na nadřazený adresář. V URL předáváme proměnnou cesta jejíž obsah je nutno zakódovat funkcí URLEncode.

$i=0;
while ($seznam[$i]) {
   if (JeToAdresar($seznam[$i])) {
      $nazev = ZjistiNazev($seznam[$i]);
      if ($cesta == „“)
         $cesta_dale = $nazev;
      else
         $cesta_dale = $cesta.“/“.$nazev;
      echo „<tr class=\“adr\“>“;
      echo „<td nowrap><img src=\““.$adresar_ikon.“/“.$ikona_adresare.“\“ height=\“16\“ width=\“16\“></td>“;
      echo „<td nowrap><b><a href=\“ftp.php?cesta=“.URLEncode($cesta_dale).“&“.SID.“\“>“.$nazev.“</a></b></td>“;
      echo „<td align=\“right\“ nowrap><a href=\“ftp.php?prikaz=smaz_adresar&adresar=“.URLEncode($cesta_dale).“&cesta=“.URLEncode($cesta).“&“.SID.“\“>X</a></td>“;
      echo „<td nowrap>&nbsp;</td>“;
      echo „<td align=\“right\“ nowrap><code>“.ZjistiDatum($seznam[$i]).“</code></td>“;
      echo „<td align=\“right\“ nowrap><code>“.ZjistiAtributy($seznam[$i]).“</code></td>“;
      echo „</tr>“;
   }
   $i++;
}

Vypíšeme seznam podadresářů, které obsahuje aktuální adresář. Voláním funkce JeToAdresar zjišťujeme, zda se jedná skutečně o adresář nebo jde o soubor. Název adresáře zjistíme voláním funkce ZjistiNazev. Do proměnné cesta_dale uložíme cestu k adresáři. Vykreslíme obrázek ikonky adresáře, vypíšeme název a odkaz na smazání adresáře. Voláním funkce ZjistiDatum a ZjistiAtributy zjistíme zbylé informace o adresáři a vypíšeme je.

$i=0;
while ($seznam[$i]) {
   if (!JeToAdresar($seznam[$i])) {
      $nazev = ZjistiNazev($seznam[$i]);
      if ($cesta == „“)
         $cesta_dale = $nazev;
      else
         $cesta_dale = $cesta.“/“.$nazev;
      echo „<tr class=\“sbr\“>“;
      echo „<td nowrap><img src=\““.$adresar_ikon.“/“.PriradIkonu($nazev).“\“ height=\“16\“ width=\“16\“></TD>“;
      echo „<td nowrap><a href=\“ftp.php?prikaz=stahni_soubor&nazev=“.URLEncode($nazev).“&soubor=“.URLEncode($cesta_dale).“&cesta=“.URLEncode($cesta).“&“.SID.“\“>“.$nazev.“</a></td>“;
      echo „<td align=\“right\“ nowrap><a href=\“ftp.php?prikaz=smaz_soubor&soubor=“.URLEncode($cesta_dale).“&cesta=“.URLEncode($cesta).“&“.SID.“\“>X</a></td>“;
      echo „<td align=\“right\“ nowrap><code>“.ZjistiVelikost($seznam[$i]).“ B</code></td>“;
      echo „<td align=\“right\“ nowrap><code>“.ZjistiDatum($seznam[$i]).“</code></td>“;
      echo „<td align=\“right\“ nowrap><code>“.ZjistiAtributy($seznam[$i]).“</code></td>“;
      echo „</tr>“;
   }
   $i++;
}

Vypíšeme seznam souborů, které obsahuje aktuální adresář. Voláním funkce JeToAdresar zjišťujeme, zda se náhodou nejedná o adresář. Název souboru zjistíme voláním funkce ZjistiNazev. Do proměnné cesta_dale uložíme cestu k souboru. Vykreslíme obrázek ikonky souboru, přičemž jméno obrázku zjistíme voláním funkce PriradIkonu. Vypíšeme název a odkaz na smazání souboru. Voláním funkce ZjistiVelikost, ZjistiDatum a ZjistiAtributy zjistíme zbylé informace o souboru a vypíšeme je. Název souboru slouží jako odkaz pro jeho stažení.

ftp_quit($pripojeni);
?>
</table>
</body>
</html>

Ukončíme FTP spojení funkcí ftp_quit a ukončíme HTML stránku.

Cílem tohoto článku nebylo vytvořit plnohodnotného FTP klienta, ale pouze poukázat na možnost využití vestavěných funkcí PHP pro práci s FTP serverem. Tato aplikace by se dala určitě doplnit o spoustu dalších vlastností, nicméně pro základní administraci na serveru je plně dostačující.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *