PHP a zachytenie nedoručených mailov

Všetky správy o nedoručení e-mailu by mali byť doručované na konto UNIXového užívateľa, ktorý e-mail odoslal, v tomto prípade by to mal byť užívateľ, ktorý je vlastníkom daného priečinku, z ktorého sa e-mail odosiela. K hláškam o nedoručení správ sa teda prakticky nedá dostať, pretože nie každý má prístup napr. k SSH a pod.
Našťastie existuje riešenie priamo v PHP, ktoré však vyžaduje vypnutý safe_mode.

<?
mail($to, $subject, $content, $mime, '-f tvoja@adresa.sk');
?>

Riešenie spočíva v pridaní piateho parametra funkcie mail(), ktorý je k dispozícií už od 4. verzie PHPčka. Parameter „-f tvoja@adresa.sk“ spôsobí nastavenie „envelope-sender-address“ na ľubovoľnú adresu, e-mail sa tvári ako skutočne odosielaný z danej adresy. Pokiaľ sa envelope-adress nenastavuje, je uvedený defaultný server (zväčša mail.hosting.sk) a tam sa aj doručujú správy o neúspešnom doručení.
Riešenie funguje iba za predpokladu, že je vypnutý safe_mode, pri zapnutom je odmietaný piaty parameter funkcie mail()

Inzercia: Webhosting a doména k webu zdarma

Akcia platí od 24. júna do 31. augusta 2009.

Akcia sa týka všetkých, starých aj nových klientov klientov, ktorí si v tomto období objednajú a zaplatia jednu z nasledujúcich služieb:

* kompletná výroba webstránky,
* redizajn starej webstránky,
* výroba webstránky na základe dodaného grafického návrhu,
* výroba online obchodu,
* výroba akejkoľvek internetovej aplikácie.

Bližšie informácie
http://www.altamira.sk

Kontakt
info@altamira.sk

Diskusné fórum o PHP a tvorbe webu

Fórum vzniklo ako logický nasledovník Wishlistu, ktorý tu pár mesiacov fungoval. Jeho primárnou úlohou malo byť sprostredkovanie tipov a námetov na články. Niekoľko zaujímavých nápadov skutočne prišlo, niekoľko článkov som na základe wishlistu spracoval a niekoľko je ešte v príprave. No, keďže väčšina z vás využívala wishlist najmä na písaníe otázok so žiadosťou o pomoc, rozhodol som sa spustiť toto diskusné fórum, ktoré by malo suplovať funkcie, ktoré wishlist primárne neponúkal.
Dúfam, že sa tu časom rozvinie aká taká komunita a všetky problémy slovenských programátorov nebudú smerované len na české alebo zahraničné diskusné fóra, ako to je zvykom teraz.

Prihlasovanie uživateľa prostredníctvom $_SESSION

Predpokladom pre prihlasovanie užívateľov do klientskej časti webu je tabuľka, kde budú uložené dáta, pričom nevyhnutnou súčasťou je samozrejme prihlasovacie meno a heslo. Je dobré zapamätať si, že stĺpec tabuľky, ktorý využívame ako prihlasovacie menu by mal mať nad sebou index UNIQUE, ktorý zabezpečí, že v tabuľke nebudeme mať dvoch užívateľov s rovnakým prihlasovacím menom. Viac informácií o tejto problematike som už rozoberal v samostatnom článku, takže sa o tom nebudem viac rozpisovať.

Predpokladajme teda, že máme v MySQL databáze tabuľku s takouto štruktúrou.

Name Login Password ID
Fero fero hashhesla 1

Pochopiteľne v stĺpci password ukladáme heslá užívateľov v nejakom aspoň minimálne šifrovanom formáte :-). (md5 / sha1).

Ideálne je celý prihlasovací engine zabaliť do nejakej triedy, ktorú si incializujeme hneď v úvode index.php. Mám zabehnutú takúto štruktúru.

<?
 
class login_management {
 
   public function loginUser() { }
   public function logoutUser() { }
   public function checkUser() { }
 
}
 
?>

Myslím, že úlohy jednotlivých metód sú jasné z ich názvov. Snáď len toľko, že metóda checkUser() je uvádzaná v každom súbore, resp. v súbore index.php, ak predpokladáme, že to je hlavný súbor, do ktorého sú includované podstránky, na základe napr. URL adresy. Táto metóda skontroluje či je užívateľ prihlásený alebo nie, prípadne ak sa užívateľ pokúša vstúpiť na chránenú podstránku, presmeruje ho na chybovú hlášku – v prípade, že nie je prihlásený.
Poďme teraz k samotnému obsahu metód.

Metóda loginUser()

Metóda slúži na prihlásenie užívateľa – overenie zadaného mena a hesla s menom a heslom uloženým v tabuľke + nastavenie $_SESSION.

<?
 
public function loginUser($login,$password) {
 
    // ošetrenie vstupov, vygenerovanie md5 hashu
    $password = md5($this->safeInput($password));
    $login = $this->safeInput($login);
 
    // SQL dotaz
    $sql_user = "
        SELECT
           SQL_CALC_FOUND_ROWS *
        FROM
           table
        WHERE
           login LIKE '" . $login . "'
        AND
           password LIKE '" . $password . "'
        LIMIT 1";
 
        $query = mysql_query($sql_user);
 
   // zistenie počtu nájdených riadkov
   $count = mysql_result(mysql_query("SELECT FOUND_ROWS()"), 0);
 
   // ak je väčší než nula, prihlásenie je úspešné
   if($count>0) {
 
      $row = mysql_fetch_assoc($query);
 
      // inicializujeme v superglobálnom poli pole 'logged', v ktorom su uložené ďalšie údaje o prihlásenom užívateľovi.
      // pole záloveň slúži ako identifikátor prihlásenia / neprihlásenia.
      $_SESSION['logged'] = array();
 
      // pregenerovanie ID session, brani, tzv. session fixation
      session_regenerate_id();
 
      // nastavime vsetky potrebne udaje o uzivatelovi z tabulky do $_SESSION.
      $_SESSION['logged']['Name'] = $row['Name'];
 
      // unixový timestamp (počet sekúnd od r. 1970)
      // zaznamenávame si čas prihlásenia, ktorý neskôr kontrolujeme a aktualizujeme pri každej aktivite
      $_SESSION['logged']['timestamp'] = time();
 
      header("Location: http://presmerujeme_kamkolvek");
      exit;
 
   // počet riadkov bol rovný nule, takže prihlásenie nebolo úspešné
   } else {
 
      header("Location: http://presmerujeme_kamkolvek");
      exit();
 
   }
 
}
 
?>

Po vykonaní tejto metódy máme užívateľa prihláseného (za predpokladu, že zadal meno a heslo aké mal…). Jeho prihlásenie overujeme podmienkou existencie poľa $_SESSION[‚log­ged‘]:

<?
 
if(is_array($_SESSION['logged'])) { ... }
 
?>

Metóda checkUser()

V tejto metóde kontrolujeme, či je užívateľ prihlásený alebo nie a zároveň aktualizujeme timestamp. Číslo 1800 v podmienkach znamená, koľko sekúnd môže byť užívateľ neaktívny. Pokiaľ bude neaktívny dlhšie, bude automaticky odhlásený. Metóda je volaná na každej podstránke.

<?
 
   public function checkUser() {
 
      // užívateľ je prihlásený, ale zároveň, čas poslednej aktivity mínus aktuálny čas
      // je menší než povolený limit nečinnosti (1800 s = 30 min.)
      if (isset($_SESSION['logged']['timestamp']) && ($_SESSION['logged']['timestamp'] < time()-1800)) {
 
         // užívateľa odhlásime
         $this->logoutUser();
         return false;
 
      // užívateľ je prihlásený, funkcia vracia true
      } elseif(isset($_SESSION['logged']['timestamp'])) {
 
         $_SESSION['logged']['timestamp'] = time();
 
         return true;
 
      }
 
   }
 
?>

Poslednou nutnou metódou je metóda zabezpečujúca odhlasovanie. Je veľmi jednoduchá, založená na funkcii unset() alebo session_destro­y(). Pokiaľ použijemesession_destro­y(), zahodíme VŠETKY nastavené $_SESSION, takže je to na zamyslenie – či ich po odhlásení potrebujeme alebo nie.

<?
public function logoutUser() {
 
    session_destroy();
 
    // alebo
    // unset($_SESSION['logged']);
 
    header("Location: niekam_presmerujeme");
    exit;
 
}
?>

Na záver snáď len toľko, že tu načrtnuté metódy sú len kostrou prihlasovacej triedy, na ktorú sa dajú nabaľovať mnohé prvky.