Na PHP skriptu http://grelek.wz.cz/nova-verze/navstevni-kniha/index.php
mi při snaze odeslat zprávu do knihy vyskočí hláška 503.
Nebude to něco s databází? Podle mě jsem já sám od rána od osmi asi 20 pokusnými zápisy nepřekročil limit...
Databáze MySQL na WZ je soustavně přetížena, zřejmě velkým množstvím špatně napsaných skriptů uživatelů. Dobře na WZ funguje databáze SQLite.
Fungovalo to do té doby než jsem do skriptu přidal "ochranu" proti spamu.
Do formuláře jsem přidal checkbox bez kterého se to neodešle.
PHP skript vypadá takhle:
<?php
require("../externi/config.txt");
$_POST['jmeno']=$jmeno;
$_POST['zprava']=$zprava;
$_POST['email']=$email;
$_POST['web']=$web;
$_POST['guard']=$guard;
htmlspecialchars ($jmeno);
htmlspecialchars ($zprava);
htmlspecialchars ($email);
htmlspecialchars ($web);
if ($_POST['odeslat'])
{
if ($guard=="")
{
echo "<strong class='cervena'>Nezaškrtli jste ochranu proti spamu</strong><em><br />Registrovaní uživatelé nemusí zaškrtávat ochranu<br /></em>";
exit();
}
if ($jmeno=="")
{
echo "<strong class='cervena'>Nevyplnili jste jméno</strong><em><br />Registrovaným uživatelům se jméno vyplňuje automaticky<br /></em>";
exit();
}
if ($zprava=="")
{
echo "<strong class='cervena'>Nevyplnili jste zprávu</strong><br />";
exit();
}
Zbytek jsem neměnil, nechal jsem ho tak jak fungoval.
Začátek toho skriptu vypadá hodně podivně. Vůbec třeba nechápu tohle:
$_POST['jmeno']=$jmeno;
ani tohle:
htmlspecialchars ($jmeno);
Jako ochrana dobře funguje prázdné skryté pole nazvané 'nick'. Uživatel ho nevidí, robot do něj často něco nacpe.
$_POST['jmeno']=$jmeno;
Knihu jsem začal psát jako můj druhý projekt.. ještě jsem to nepřepsal (sám nevím proč..)
htmlspecialchars($jmeno);
To je funkce v PHP... http://php.net/manual/en/function.htmlspecialchars.php
V prvním případě přepisuješ předaný parametr nějakou nedefinovanou proměnnou $jmeno. To je úplný nesmysl.
Ve druhém případě voláš funkci, ale nikam neukládáš její výsledek. Další nesmysl. Tu funkci samozřejmě znám, ale použil jsi ji špatně.
<?php
require("../externi/config.txt");
$jmeno=htmlspecialchars($_POST['jmeno']);
$zprava=htmlspecialchars($_POST['zprava']);
$email=htmlspecialchars($_POST['email']);
$web=htmlspecialchars($_POST['web']);
if ($_POST['odeslat'])
{
if ($guard=="
Zbytek kódu byl podle tebe v pořádku tak ho sem nevkládám..
Byla to nějaká chyba na serveru, už to v pohodě funguje.
Teď akorát musím udělat "select" z databáze a je to na světě (konečně...).
Je to mnohem lepší, nesmyslné části kódu zmizely. Až na to, že místo htmlspecialchars() by zřejmě byla daleko vhodnější funkce mysql_real_escape_string() nebo ještě lépe použít parametrizované dotazy. U těch není vůbec potřeba takové opičárny dělat, ale je potřeba místo ovladače MySQL použít MySQLi nebo PDO.
Doporučuji přejít alespoň na MySQLi. Umí toho víc než ovladač MySQL a navíc se s ním dá pracovat objektově. Je i o něco rychlejší.
Funkce htmlspecialchars() se používá při generování výstupu HTML. Při ukládání dat do tabulek SQL by se používat neměla.
A ještě mám problém se spamováním.
Ochrana checkboxem funguje ale když zmáčkneš F5 a dáš Znovu odeslat, tak se mi to zapíše znovu.. zkoušel jsem to nějak přez header() ale nevím si s tím rady.....
To se dělá tak, že se po zpracování vstupních dat (bez výstupu HTML) pošle
header('Location: URL');
exit;
Tím se natáhne nová stránka, která si už nepamatuje, co se posílalo. Dokonce se stránka odesílající data ani neuloží v historii prohlížeče.
Místo URL napiš adresu, kam se má stránka po zpracování dat přesměrovat.
Tohle je jeden z mála případů, kdy připouštím použití příkazu exit nebo funkce die(). Funkci die() nepoužívám vůbec, podle mne od PHP verze 5 nemá smysl.
Tak já exit() používám jenom když nemám všechny potřebné informace pro splnění skriptu.. jinak jsem se ještě nesetkal s nutností použít exit() mimo tento případ. die() jsem ještě nikdy nepoužil a ani to nijak neplánuji.
Akorát jak říkáš, od verze 5. Docela jsem se zarazil nad tímto:
http://grelek.wz.cz/PHPINFO.php
a
http://p-rd.unas.cz/PHPINFO.php
To je sakra rozdíl ne? PHP se na servery instaluje zadarmo ne? Tak proč si s tím někdo nedá tu práci a neaktualizuje PHP (aspoň na verzi 5...)
Když na doméně wz.cz změnili PHP4 na PHP5, přestaly mi fungovat skripty. Musel jsem je opravit. Takže upgrade není úplně přímočarý. Další problém je v tom, že PHP5 zatěžuje server o něco víc než PHP4. Server by to kvantum webů v nové konfiguraci nemusel utáhnout. Po opravě skriptů se to obrátí ve prospěch PHP5, ale málokdo si ty skripty opraví.
WZ průběžně upgraduje PHP. Není to jen pouhý upgrade, ale v takovém rozsahu musí na té nové verzi udělat před nasazením dost úprav. Bohužel je tady zaregistrováno hodně individuí, jejich největší radostí by bylo ten server shodit. Na běžně instalovaném PHP to není velký problém.
Zmínil jsem PHP5, protože teprve v pětce je úžasná náhrada za exit a die v podobě klíčových slov try, catch a throw. Při např. nedostupnosti databáze místo zabití aplikace vyrobíš náhradní blok textu a pokračuješ dál v generování stránky. Když to uděláš dobře, návštěvník ani nemusí poznat, že server měl nějaké potíže. V každém případě to může vypadat mnohem lépe, než suché oznámení, že se nepodařilo připojit k databázi. Také se tyto chyby pomocí výjimek dobře logují.
Také doufám, že i obsluha domény vyrobce.cz časem získá PHP5. Zatím to tak není. Nezbývá, než čekat a doufat.
Doma jedu s PHP 5.3.5 a to je úplně jiné kafe. Hlavně v dostupnosti nových funkcí, pomocí kterých se zbavuji cyklů. Není problém např. bez cyklů vygenerovat z vícerozměrného pole dynamickou tabulku. A takové anonymní funkce jsou také pěkná vychytávka.
Dobrá sranda je vyladit aplikaci tak, aby bez problémů jela na všech běžně se vyskytujících verzích.
Problém s headerem...
Warning: Cannot modify header information - headers already sent by (output started at /7p/wz.cz/g/grelek/nova-verze/externi/ikonky.txt:8) in /7p/wz.cz/g/grelek/nova-verze/navstevni-kniha/index.php on line 110
Ve formuláři mám tlačítko na odeslání pojmenované Odeslat.
PHP vypadá takhle.
if ($_POST['Odeslat'])
{
if ($_POST['guard']=="")
{
echo "Nezaškrtli jste ochranu proti spamu";
exit();
}
...
...
...
...
// vykonani SQL vyrazu pridani zpravy
if (!mysql_query(sprintf($dotaz_pridat_zpravu, $jmeno, $zprava, Date("Y-m-d H:i:s"), $email, $web )))
{
echo 'Error in executing ' . $dotaz_pridat_zpravu;
echo 'Error: ' . mysql_errno($link) . mysql_error($link);
exit();
};
header('Location: http://grelek.wz.cz/nova-verze/navstevni-kniha/index.php');
exit;
}
?>
Ale na začátek kódu to nemám dát kam, aby se mi to odeslalo..
Před header() nesmí být žádný výstup (echo).
Vždycky se to dá dát na začátek. Popravdě zpracování čehokoli by mělo být mimo zobrazovaní stránky. Nejlepší princip dynamické stránky je takový - nejdříve se zpracuji všechny nevizuální operace, připraví se všechny činnosti pro zobrazení a nakonec se vše nechá zobrazit. Není dobré to míchat nebo dávat dohromady. V zobrazovací části by měly být pouze věci pro zobrazení a ne pro zpracování.
Inspirovat se můžeš zde, kde se tohle podstatě řeší: http://www.webzdarma.cz/forum/read.php?f=2&i=45203&t=45203
Osvědčila se mi následující konstrukce skriptů PHP:
<?php
if(isset($_POST['odeslat'])) {
zpracování dat z formulářů, zápis to session a databází
header('Location: ...');
exit;
}
// vybrat požadované údaje z databází
// nacpat je do proměnných
// a teprve potom začít generovat stránku
// včetně formulářů
echo <<<EOT
<!DOCTYPE html>
<head>
$hlavicky
</head>
<body>
$nadpis
$menu
$telostranky
</body>
EOT;
?>
A ještě bych se chtěl zeptat, jestli nevíte na jaké doméně kromě xxx.wz.cz je PHP 5?
Greleku proč tam includuješ připojení z db v textovém souboru?
To si může každý přečíst,radši to změn na php
No jo, napoprvé mi to nešlo, tak jsem Greleka nevaroval. Myslel jsem si, že to uvádí jen jako příklad.
Grelek: Všechny includované soubory v PHP musí mít příponu.php , jinak je riziko stažení přístupových kódů útočníkem. Teď už vím, že tvé heslo končí na 's'. Změň si heslo do databáze a oprav příponu skriptu s heslem.
<HTML>php5 - momentalne na:
euweb.cz
kvalitne.cz
mysteria.cz
webz.cz
webzdarma.cz
wz.cz
xf.cz</HTML>
Ale mě se tam pak vkládá ten vydrbanej banner :-/..
Ok, nějak to pořešim..
A můžu se zeptat proč to tak je? Myslím s tím texťákem..
Tak jsem změnil vkládání reklamy vkládám ji do souboru http://grelek.wz.cz/nova-verze/externi/reklama.php
A tam ani nikde jinde se reklama neobjevila...
Banner se tu řešil několikrát: V Administraci si nastavíš zobrazování banneru nahoře, do souboru třeba banner.html a ten v požadovaném místě naincluduješ.
Ta striktní reklama se občas odmítá vložit, tak jí musíš občas trochu pomoci. Pokud ji ještě v nějakém souboru máš, tak si ji tam prostě nakopíruj.
A hlavně přejmenuj ten config.txt, ať ti piráti nelezou do databáze. A změň si do ní heslo.
Včera jsem narazil na jednu zajímavou diskuzní skupinu, ve které se řešilo bezpečné ukládání hesel do databáze. Diskuze to byla zajímavá, ale každý zmíněný kousek SQL obsahoval zranitelnost SQL injection. Až jsem málem zapochyboval, jestli nejsem zbytečně paranoidní. Nejsem.
Viděl jsem kdysi jednoho takového útočníka, jak s ledovým klidem smazal komusi celou databázi jenom proto, že tvrdil, že ji má bezpečnou. Nechal jsem si od něj tenkrát napadnout i své fórum. 3x se mu to povedlo, než jsem vychytal chyby.
Includy se dají zabezpečit ještě jedním způsobem: Vloží se do adresáře, ve kterém je soubor .htaccess s obsahem "deny from all". Stejným způsobem je na WZ i jinde nutné chránit databáze DBA, SQLite a vlastně všechny datové soubory, které nemají být stáhnutelné přímo.