Zdravím.
Chtěl bych se zeptat, zda je lepší zpracovávat formulář v souboru, ve kterém formulář je, nebo v jiném ?
Myslím tím, když budu mít formulář v souboru dejme tomu formular.php, zda je lepší zpracovávat data rovnou v tomto souboru nebo vytvořit třeba zpracovani_formulare.php a zpracovávat tam ?
Snad jsem to zapsal alespoň trochu srozumitelně....
Děkuji za každou radu,
Magnus.
Většinou to dělám v tom samém souboru na začátku skriptu, protože je to pohodlnější a naseká se méně chyb. Vždy po zpracování formuláře posílám header('Location:') pro refresh, aby se poslaná data neuložila do historie prohlížeče.
Pokud soubor ukládám ve formátu UTF-8, pak header() nejde odeslat. Mohl bys mi, nebo někdo jiný, poradit, co s tím ?
Četl jsem, že je to něco s BOMem, ale netuším, jak to "zprovoznit".
Je to možné, že se ti do souboru vložil BOM znak. Jedná se identifikační znaky, které nejsou na pohled vidět, ale mohou nasekat paseku. Zvláště ve spojení s header(), protože tyto znaky jsou už součásti výstupu a to se před header() nesmí. Tyto znaky se nachází hned na začátku souboru a je potřeba takový editor, který tyto znaky zobrazí a ty je pak můžeš odstranit. Respektive takový editor, který tyto znaky nevkládá.
Jinak záleží na situaci. Obecně však preferuji vše v jednom, protože to mám na jednom místě. U rozsáhlých souborů, které mají několik stovek řádků a míchají se tam všechno možné, bych pak raději rozdělil a zpracování formuláře řešil mimo.
Koukám, že tu v editoru mám možnost formátu "UTF-8 (bez BOM)", tak to vyzkouším, snad to půjde.
Děkuji vám za pomoc. :)
Tak jsem změnil formát, aby se soubor uložil bez BOM a stejně mi hází chybu, že header byl odeslán. :(
Hlásí to v souboru, kde mám pouze PHP, kde se zpracovávají přijatá data POSTem.
Nebyla by ještě nějaká možnost, prosím ?
<HTML>Opravdu žádný zpracovávaný soubor nemá BOM? Doporučuju stáhnout výstup toho POST requestu a podívat se na něj nějakým hexeditorem. Pokud tam je skupina tří bajtů EF BB BF, nechal jsi tam někde BOM.</HTML>
Asi jsem vážně blb... Já si neuvědomil, že zpracovávající soubor vkládám do souboru, kde již výstup je.
Mohl bych se tedy k tomu zeptat, když mám hlavní soubor index.php, kam pomocí GET vkládám soubory s textem (a formuláři), jak to nejlépe udělat ?
Napadlo mě jedině v index.php dát před jakýkoliv výstup podmínky, jestli se neodeslal nějaký formulář. To bych ovšem těch podmínek měl desítky pod sebou.
<HTML>Nejspíš by bylo nejlepší dát zpracování formulářů do jiných skriptů. (Tedy formuláře se nebudou posílat na index.php.) Po zpracování formuláře pak můžeš uživatele přesměrovat zpátky na stránku s formulářem. Tak se to dnes běžně<sup>1</sup> dělá.
<sup>1)</sup> Aspoň doufám, že je to běžné.</HTML>
Běžně to dělám následovně:
<?php // před touto značkou nesmí být nic, ani prázdný řádek
if(isset($_POST['odeslat'])) {
// zpracování dat z formuláře, _zapsání_ do databází apod
// bez jakéhokoli výstupu. Nic se nevypisuje.
// Tímto způsobem se dají snadno zpracovat i ajaxová volání.
header('Location: '.$_SERVER['SCRIPT_URI']);
// ....přesměrování na sebe sama
exit(); // a dál už pokračovat nemusím.
}
// a tady už je normální skript pro zobrazování stránky, _čtení_ z databází apod.
// pro změnu zde se nikdy žádná data do databáze _nezapisují_.
// Zde jsou i všechny formuláře.
// Celá prezentace se mi tak vejde do jednoho souboru s případnými includy.
?>
Pak to mám možná udělané špatně.
Mám soubor index.php, kde mám <div>, který použiji na textový obsah stránky a v něm mám podmínky pro vkládání souborů. Nějak takto:
if (isset($_GET['page']))
{
$page = $_GET['page'];
if ($page == "neco") include "neco.php";
else include "jiny.php";
}
a právě v souborech neco.php a jiny.php mám formuláře. Proto když v těch souborech budu mít i zpracování scriptu, nemhou použít header, protože tam již mám HTML tagy.
Indexový soubor používám pro vykreslení stránky, v ostatních souborech, které vkládám, mám čistě jen text.
Ty formuláře jsou na správném místě, ale _zpracování_dat_ z těch formulářů musí být úplně na začátku skriptu a po něm hned header('Location...
Dělám to tak i proto, že často používám NoSQL databáze, které jsou rychlejší, když se otvírají pouze pro čtení. Při zápisu se do nich nikdo jiný nedostane, to je jejich nevýhoda. Proto je pro zápis otvírám na co nejkratší dobu, zapíšu a a hned zase zavírám. Ovšem stejný postup používám i při práci s SQL. Aplikace napsaná tímto způsobem je mnohem čistější, s menší náchylností k programátorským chybám.
Tak snad to chápu správně. Ještě jednou díky za rady a omlouvám se za zbytečně moc dotazů.
Jen mě teď ještě napadlo... když odešlu data databázi a chci uživateli oznámit, že se data odeslala, jak to poté udělat ?
Protože když použiji header("location"), pak nemám šanci pomocí echo něco vypsat, jedině text někam uložit.
Do session ? Do databáze ? Do cookie ? Nevím nevím.
Do session je skvělý nápad. Do databáze by to šlo také. Do cookies bych to nedával, protože na stránce asi nebudeš chtít XSS :-)
V Ajaxu je to jednodušší, tam se data pošlou na výstup a Javascript v prohlížeči je zobrazí. Tam se už header Location nedělá, stačí exit.
Dobře - a bude lepší tedy session nebo databáze ?
A co se týče exit(), je lepší to na konci scriptu psát ?
Session je vlastně databáze, která je určena k ukládání dat vázaných k danému spojení. Takže session.
Na konci skriptu je automaticky exit(). Tedy za předpokladu, že není includován. Takže pokud na konci "neco.php" potřebuješ ukončit běh skriptu, tak ho tam dej, jinak se řízení vrátí do volajícího skriptu.
Normálně však exit() dávám jen tam, kde ho skutečně potřebuji a kde má logiku, tedy např. za header('Location'). Chybové stavy ošetřuji výjimkami, takže u nich exit() nepotřebuji.
To co chceš, se vlastně nazývá "flash message". Jedná se zobrazení informační lišty. Po zpracování nebo tam, kde podstatě chceš použít echo, tak přidáš příkaz k zápisu zprávy do session a při dalším zobrazení stránky se tato zpráva ze session zobrazí.
Když to budu dělat přes to session, jakým nejlepším způsobem to udělat ? Nerad bych, abych to musel potom opravovat.
Napadlo mě udělat to tak, že podmínkou zjistím, zda dané session existuje - pokud ano, vypíše se hodnota a unset($_SESSION) - to se ale prý dělat nemá.
Pak mě napadlo dát podmínku, jestli $_SESSION má nějakou hodnotu - pokud ano, vypíše se a nastavím $_SESSION['neco'] = "" či null.
Jinak asi nic lepšího nevymyslím.
Unsetovat superglobální proměnu se fakt nesmí dělat ;) Je však možné unsetovat jeho část (index).
Takže správně je druhá varianta. Otestovat existenci hodnoty a následně tuto hodnotu vynulovat nebo odstranit. Tedy něco jako:
if ( !empty($_SESSION['neco']) ) {
echo $_SESSION['neco']; // vypisu
$_SESSION['neco'] = null; // bud vynuluji
unset($_SESSION['neco']); // nebo odstranim
}
Nemůžeš udělat unset na celou databázi, ale jen na konkrétní položku, kterou chceš smazat. Tedy unset($_SESSION['neco']);
Tak snad je to z mých otázek vše. Děkuji za pomoc začátečníkovi. :)