Anglická verze
logolink

< Zpět na seznam lekcí

Generování dopisů pomocí PHP

PHPObsah lekce:

  • Textové výstupy většího rozsahu
  • Zadání problému
  • Datum
  • Oslovení
  • Funkce pro generování hesla

Textové výstupy většího rozsahu

V praxi se často vyskytuje potřeba vytvořit textové výstupy většího rozsahu. Mezi takové řadíme například obchodní dopisy klientům pojišťoven, bankovních ústavů, sdělení důležitých informací větší skupině lidí (studenti škol, zaměstnanci firem) apod. Příklady:

  • Obchodní dopisy - tzv. hromadná korespondence - například instituce potřebuje poslat každému svému klientovi dopis obsahující údaje specifické pro daného klienta (zpravidla výstupy z databázového systému) a nějaké relevantní informace. Může se jednat například o nabídky specifické pro daného zákazníka (rozhoduje zde mnoho faktorů - jak dlouho je již zákazníkem, jaké produkty využivá apod.). Konkrétně se může jednat o nabídky balíčků digitální televize, nabídky spojené s pojištěním, zaslání autentifikačních informací (PIN k platební kartě, heslo k účtu apod.).
  • Důležité informace - například nový student VŠ musí dostat na papíře informaci o přihlašovacích údajích do informačních systémů univerzit.

Problémy tohoto typu lze řešit pomocí mechanismu hromadné korespondence v kancelářském balíku Office. Cesta přes PHP se může hodit v prípadě, že chceme generovat tiskoviny ze vstupních dat různého typu, databází, linuxových textových výstupů a jako výstup získat například textový soubor, PDF, HTML nebo kvalitní dokument ve formátu pro systém LaTeX .

My si ukážeme řešení problému administrátora informačního systému, který potřebuje zaslat zaměstnancům dopisy s informací o změně přihlašovacích hesel k IS včetně těchto hesel (hesla systém musí vygenerovat podle zadaných kritérií o složitosti hesel v daném IS).

Zadání problému

Text dopisu

Úkolem je napsat skript, který do vygeneruje html stránku s krátkými dopisy pro všechny uživatele ze vstupu tohoto znění (jednotlivé řádky dopisu jsou pro potřebu lekce očíslovány a tučně jsou zvýrazněna místa, která se budou v dynamicky měnit):

  1. Datum: 16. 05. 2010
  2. Adresát: Jaromír Karola
  3. Vážený pane!
  4. Posílám Vám dopis s novým heslem pro přístup do informačního systému.
  5. Vaše nové heslo pro přihlášení: p0n6vbqk9c (P0N6VBQK9C)
  6. František Žebř, správce počítačové sítě

Jako vstupní data pro náš skript poslouží dvě pole se jmény uživatelů a jejich pohlavím (pro jednoduchost již máme pole přednaplněna, ale jejich naplnění by jistě bylo možné z patřičných externích vstupních dat).

Vstupní pole s daty
$uzivatele = array("Jaromír Karola", "Andulka Šťastná", "Ota Menoušek", "Oto Najbrt", "Ágnes Císařová"); $uzivatelepohlavi = array("M", "Z", "M", "M", "Z");

Požadavky na vlastnosti hesla

Heslo bude náhodně vygenerováno z vhodných malých písmen a číslic. Jeho délka bude 10-15 znaků a bude zajištěno, že bude každé heslo jedinečné. Navíc bychom měli z hesla vyloučit znaky, které by mohly půsbit uživatelům obtíže. Zamyslete se, zda znáte nějaké písmeno nebo číslici, která by mohla činit uživateli problém se správným přečtením hesla (předpokládejme, že hesla budou zapsána fontem typu Courier - tedy strojopisem). Budeme hesla tvořit z malých i velkých písmen?

Struktura kódu skriptu

Dopisy pro jednotlivé uživatele zpracujeme cyklem for (ideální pro zpracování pole o známém počtu prvků).

Cyklus for

for($k=0;$k<count($uzivatele);$k++){
  print("<p>Datum: ".."</p>");
  print("<p>Adresát: ".$uzivatele[$k]."</p>");
  Oslovení
  Generování hesla do proměnné $heslo
  print("<h2>Vaše nové heslo pro přihlášení: ".$heslo." (".heslo velkými písmeny.")</h2>");
  print("<p>František Žebř, správce počítačové sítě</p>");
}

Heslo budeme generovat pomocí funkce generujheslo. Jejím vstupem budou všechny potřebné proměnné pro generování hesla a výstupem bude samotné heslo (návratová hodnota funkce), které se v hlavním for cyklu vloží do proměnné $heslo. Jedním z parametrů funkce bude rozhodně parametr délka, který bude sloužit pro zadání požadované délky generovaného hesla. Do našeho skriptu vložíme hlavičku funkce nad cyklus for:

Funkce generujheslo

function generujheslo($delka){

  $heslo = "";
  $znakyhesla = "023456789bcdfghjkmnpqrstvwxyz";
}

Ve funkci jsou již připraveny dva řádky kódu. Jedná se o proměnnou heslo, do které se bude generovat heslo a kterou bude naše funkce vracet. Druhý řádek je proměnná znaky hesla, která obsahuje řetězec znaků, ze kterých se bude heslo generovat (Proč v tomto řetězci chybí některá písmena a číslice?).

Základní kostru našeho skriptu si stáhněte v následujícím souboru: dopisy-zadani.txt.

Kroky řešení

Datum

Na prvním řádku dopisu bude zapsáno aktuální datum ve tvaru den. měsíc. rok (například 3. 6. 2011).

Vyhledejte dokumentaci funkce Date v PHP a zapište do skriptu tuto funkci se správnými parametry.

Při čtení dokumentace mnohdy pomůžou příklady a příspěvky uživatelů pod specifikací dané funkce nebo příkazu. V tomto případě mi mohl k pochopení pomoci příklad 4:

Příklad 4 z dokumentace k funkci Date z php.net
Example #4 date() Formatting

<?php
// Assuming today is March 10th, 2001, 5:16:18 pm, and that we are in the
// Mountain Standard Time (MST) Time Zone

$today date("F j, Y, g:i a");                 // March 10, 2001, 5:16 pm
$today date("m.d.y");                         // 03.10.01
$today date("j, n, Y");                       // 10, 3, 2001
$today date("Ymd");                           // 20010310
$today date('h-i-s, j-m-y, it is w Day');     // 05-16-18, 10-03-01, 1631 1618 6 Satpm01
$today date('\i\t \i\s \t\h\e jS \d\a\y.');   // it is the 10th day.
$today date("D M j G:i:s T Y");               // Sat Mar 10 17:16:18 MST 2001
$today date('H:m:s \m \i\s\ \m\o\n\t\h');     // 17:03:18 m is month
$today date("H:i:s");                         // 17:16:18
?>

Oslovení

U oslovení je celá věc poměrně dost jednoduchá. Oslovení bude závislé na pohlaví daného člověka: Vážená paní/Vážený pane.

Stačí tedy použít jednoduchou podmínku KDYŽ - POTOM (If ... then), která vypíše text podle hodnoty v poli $uzivatelepohlavi. Každý člověk je prvek pole s indexem $k.

Výpis oslovení

for($k=0;$k<count($uzivatele);$k++){

print("<p>Datum: ".Date("d. m. Y")."</p>");
print("<p>Adresát: ".$uzivatele[$k]."</p>");

if ($uzivatelepohlavi[$k]=="M"){
print("<h1>Vážený pane!</h1>");
}else{
print("<h1>Vážená paní!</h1>");
}
...

Funkce pro generování hesla

A to nejlepší na konec :)

Varianta řešení 1

Dopište sami skript pro generování hesla s použitím funkcí substr, mt_rand, strlen, strstr a strtoupper.

Varianta řešení 2

Použijte a podrobně vysvětlete následující kód:

Generování hesla

function generujheslo($delka){

  $heslo = "";
  $znakyhesla = "023456789bcdfghjkmnpqrstvwxyz";
  $i = 0;
  while ($i < $delka) {
    $znak = substr($znakyhesla, mt_rand(0, strlen($znakyhesla)-1), 1);
    if (!strstr($heslo, $znak)) {
      $heslo = $heslo.$znak;
      $i++;
    }
  }
  return($heslo);

}

$uzivatele = array("Jaromír Karola", "Andulka Šťastná", "Ota Menoušek", "Oto Najbrt", "Ágnes Císařová");
$uzivatelepohlavi = array("M", "Z", "M", "M", "Z");

for($k=0;$k<count($uzivatele);$k++){

print("<p>Datum: ".Date("d. m. Y")."</p>");
print("<p>Adresát: ".$uzivatele[$k]."</p>");

if ($uzivatelepohlavi[$k]=="M"){
print("<h1>Vážený pane!</h1>");
}else{
print("<h1>Vážená paní!</h1>");
}

print("<p></p>");

$heslo = generujheslo(8);

print("<h2>Vaše nové heslo pro přihlášení: ".$heslo." (".strtoupper($heslo).")</h2>");

print("<p>František Žebř, správce počítačové sítě</p>");

}

Všimněte si, že v tomto kódu není zaručena jedinečnost hesla, ale je zaručeno, že se zádný znak nebude v hesle opakovat více než jednou.

Domácí úkol

  1. Upravte výsledný skript tak, aby jeho výstup sloužil jako vstup pro systém LaTeX tak, že každý dopis bude na zvláštní straně, bude typograficky v pořádku (navrhněte v php funkci predlozky, která bude realizovat vkládání pevných mezer za jednopísmenné předložky a spojky).
  2. Upravte výsledný skript tak, aby bylo každé z vygenerovaných hesel pro danou skupinu uživatelů skutečně jedinečné (využijte ve funkci proměnnou $k - vložte ji do funkce pomocí přikazu globals a příkaz vysvětlete).
  3. Co kdybychom chtěli výsledné dopisy v podobě html stránky použít v textovém procesoru typu Word? Bylo by možné nějak efektivně dopisy do procesoru vložit, vizuálně upravit a zařídit, aby byl každý na zvláštní straně?

Otázky

  1. V jakých situacích se uplatní počítače při vytváření většího počtu tiskovin jako například dopisů?
  2. Charakterizujte funkce v PHP. Zejména příkazy globals, return a předávání parametrů odkazem a hodnotou.
  3. Charakterizujte funkce substr, mt_rand, strlen, strstr a strtoupper.
webdesign, xhtml, css, php - Mgr. Michal Mikláš