Autor Zpráva
tatyalien
Profil
Dobrý den,
mám otázečku, když používám stránky pomocí šablony (mám jeden soubour index a pak další soubory, které do něj načítám), ve vláknu: Odkaz jsem si četl o zamezení víceuložení pomocí historie prohlížeče, ale pomocí funkce header nemůžu pak přesměrovat stránku, protože už má výstup soubor "index", jak se to jinak tedy řeší u šablon?

//ob_start();
session_start();
require "./include/funkce_all.php";
//
if (!fun_NastavGlobalniHodnoty()) {
	echo "<h3><font color=\"red\">POZOR NEPODAŘILO SE NAČÍST GLOBÁLNÍ HODNOTY!!!!</font></h3><hr>";	
};
// vynulování a vytvoření sessionu
if ($_GET["clanek"]=="prihlaseni") {
  $id = fun_iduzivatele($_POST["prezdivka"], $_POST["heslo"]);
  if ($id<>0) $_SESSION["id"]=$id;
} elseif ($_GET["clanek"]=="odhlaseni") {
  unset($_SESSION["id"]);
};
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>
	xxxx
</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

<style type="text/css">
css styly....
</style>

<body>
	<div id="obal">
  		<div id="zahlavi">
			<img src="<?echo $GLOBALS["CestaProOdkaz"]?>/images/grafika_zahlavi.gif" alt="xxxx" width="377" height="41" />
		</div>
		<div id="navigace">
			<?require "./navigace.php"?>
		</div>
		<div id="obal_obsahu">
			<div id="obsah_vnitrni">
				<?ukazclanek()?>
			</div>
		</div>
		<div id="zapati">zápatí...</div>
	</div>
</body>
</html>
<?//ob_end_flush();?>


pokud použiju jen třeba testovací formulář (jen pro test)
if (!$_POST) {
    $BudemeZobrazovat = true;
} else {
	if ($_POST["btn_odeslano"]) {
        if ($_POST["txt_test"] != "") {
            // přesměrování.... - používám odkazy přez .htaccess... -> RewriteRule ^data/ok index.php?clanek=data_ok
            header("location:/data/ok");
        } else {
		echo "Nic není zadáno.";
		};
	};
};


funkce na načtení článku: (je to z linuxsoftu)
/*= FUNKCE NA NAČTENÍ OBSAHU DO WWW STRÁNKY */
function ukazclanek ()
{ 
  if ((string)$_REQUEST["clanek"]<>'') $mujclanek=$_REQUEST["clanek"]; else $mujclanek="uvod";
  if (is_file("./".$mujclanek.".htm")):
    $nazevclanku=$mujclanek.".htm";
    require $nazevclanku;
  elseif (is_file("./".$mujclanek.".php")):
    $nazevclanku=$mujclanek.".php";
    require $nazevclanku;
  else:
    $nazevclanku=$mujclanek.".php";
    require "notfound.php";
  endif;
};
AM_
Profil
Dotaz je formulovaný dost nesrozumitelně:
protože už má výstup soubor "index"
co to znamená?

Dané vlákno pojednává o tom, že pokud uživatel provede nějakou akci (přidá příspěvek, aktualizuje údaj v databázi ...), mělo by se toto provést skriptem, který se ihned potom přesměruje přes header na takovou URL, která už tuto akci nevyvolá.
např:

seznam_lidi.php --(odkaz)--> pridej_cloveka.php?jmeno=Jan+Novak --(header)--> seznam_lidi.php

přičemž pridej_cloveka.php se díky tomu, že se po provedení akce přesměruje, neuloží v historii prohlížeče a při procházení historií se tedy nepřidá další jan novák. Vůbec nechápu, z jakého důvodu by toto nemělo jít.
tatyalien
Profil
No já pomocí tohoto též upravuji a přidávám data, načtu si do "indexu" "článek" třeba registrace (index mě jen dělá html typu horní box, levé menu, pravý načítací velký box a zápatí), kde přidám uživatele, kde po akci když pužiju header mě to hlásí:

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\www\rma_2\index.php:37)
Na 37 řádku mám cssko.

Proto jsem přesměrování pak na jinou stránku zavrhl a jen informuji uživatele pomocí echa, že je vše ok. Ale pokud bych dal pak v prohlížeči krok zpět tak bych mohl znovu vkládat a upravovat data co jsem již jednou odeslal.

Nejsem programátor a něco dělám asi špatně, ale nevím co přesně.
AM_
Profil
headery se musí posílat dřív, než generuješ jakýkoliv výstup (HTML, CSS , cokoliv, co se echuje nebo vypisuje). Má to svojí logiku, pokud se uživateli z dané stránky nic nezobrazí a hned ho to přesměruje dál, není důvod, abys mu cokoliv posílal. Korektně napsaný skript by mohl vypadat rámcově takto:
<?php
if ($nejaka_akce){
  zpracuj_akci();
  header('location: tahle_stranka.php');
}
//az do teto chvile neni zadny duvod cokoliv vypisovat
?>
<html>
<head>
...


Samozřejmě v nečistě napsaných programech, kde je HTML skrz na skrz prošpikované výkonným PHP kódem, se takováhle věc dodatečně řeší blbě. Řešení může být použít výstupní buffer: pokud na začátek dáš ob_start() a na konec ob_end_flush(), zajistíš, že celý výstup se pošle až po vykonání celého skriptu, takže mezitím si to můžeš "rozmyslet" a upravit nějaké hlavičky. Přináší to ale zase jiné problémy (především u rozsáhlých stránek), není to ideální řešení, spíš taková nejprimitivnější záplata.

Pokud jak říkáš používáš šablonování index.php který vkládá do těla danou stránku, je nejlepší si stránku rozdělit na 2 části: první PHP vykonat hned na začátku, druhou HTML šablonu zobrazit v těle. Pseudo-příklad:
<?php
session_start();
$stranka = get_active_page($_GET['stranka']);
require 'scripts/$stranka.php'; //sem muzes nacpat skript ktery neco provede a pak se v pripade potreby presmeruje jinam (aplikacni cast)
?>
<html><head>...</head>
<body>
<?php require 'content/$stranka.php'; // sem nacpes zobrazovaci cast stranky ?>
</body></html>
Mastodont
Profil
tatyalien:
- Použij output buffering nebo změň posílání věcí do výstupu.
- Přesměrování po přijetí formuláře a jeho zpracování je naprosto v pořádku.
tatyalien
Profil
No dělal jsem si stránky dle návodu z Odkaz - linuxsoft (ne přímo projek, který tam rozebírají, ale šablona mě zůstala).

Takže mě asi nezbyde nic jiného než dělat to jak říkáš, rozdělit vždy načtenou stránku s kódem na 2 části, ale není mě přesně jasné jak to provést, protože vždy se nejdřív načte "index", kde se generuje výstup (HTML, CSS) a teprve pak se do indexu načte stánka s kódem.

Kam třeba načtu stránku test.php:
if (!$_POST) {
    $BudemeZobrazovat = true;
} else {
    if ($_POST["btn_odeslano"]) {
        if ($_POST["txt_test"] != "") {
            // přesměrování.... - používám odkazy přez .htaccess... -> RewriteRule ^data/ok index.php?clanek=data_ok
            header("location:/data/ok");
        } else {
        echo "Nic není zadáno.";
        };
    };
};
// pokud je předán argumet schovat komplet true, ukončím skript
if (!$BudemeZobrazovat ) return;
echo "<form action='' method='post'>";
echo "<fieldset>";
echo "<legend>Testovací....</legend>";
echo '<table style="margin-left:-1px;" border="0">';
echo fun_formular_Input("lbl_test","txt_test", $_POST["txt_test"],"Testovací:","",50,20,"password");
echo "<tr><td colspan=\"2\"><input type='submit' name='btn_odeslano' value='Odeslat'></td></tr>";
echo '</table>';
echo "</fieldset>";
echo "</form>";
echo "<a href=\"" . $GLOBALS["CestaProOdkaz"] . "/admin\">Přejít na admin nastavení.</a>";


asi to mám blbě poskládanou hierarchii zobrazování webu, ale jinde jsem se o tom nedočetl, jen na odkazu viz linuxsoft.
AM_
Profil
tatyalien:
if (!$BudemeZobrazovat ) return;
místo tohohle je lepší za header() rovnou hodit die();
hlavně to přesměrování musí být ještě dřív, než v indexu začneš s výstupem, nejen v tomhle souboru.

Jinak nevím, proč tu tunu HTML echuješ a nedáš raději mio PHP kód.
tatyalien
Profil
AM:
1) die(); opravím díky ;)
2) Kód z echa vymlátím...
3) to že musím začít dřív než v indexu začnu s výstupem chápu, ale asi to v tomto řešení nejde jednoduše opravit :-(

Není někde nějakej tutoriál, jak by se mělo zkloubit web-php-css-mysql? Protože co jsem si zatím prolezl, tak jen ten tutoš z linuxoftu byl vysvětlen v pohodě.
AM_
Profil
tatyalien:
3) to že musím začít dřív než v indexu začnu s výstupem chápu, ale asi to v tomto řešení nejde jednoduše opravit

a co takhle?

http://example.com/index.php?stranka=cosi

scripts/cosi.php:
    $chyba = '';
    if (!empty($_POST["btn_odeslano"])) {
        if ($_POST["txt_test"] != "") {
            // přesměrování.... - používám odkazy přez .htaccess... -> RewriteRule ^data/ok index.php?clanek=data_ok
            header("location:/data/ok");
            die();
        } else {
            $chyba = 'Nic neni zadano';
        }; //pokud jsi na toto zvyklý z Cčka, možná ti pomůže, že v PHP není středník za složenou závorkou potřeba.
    };


content/cosi.php:
<p class="error"><?php echo $chyba; ?></p>
<form action='' method='post'>
<fieldset>
<legend>Testovací....</legend>
...


index.php viz [#4] AM
tatyalien
Profil
AM:
jo tohle prošlo ;) jen ještě poprosím, dělal jsem to na "tvrdo" protože funkci get_active_page mě to nebralo, to je nějaká tvá napsaná funkce?

Takže by mě stačilo každý skript co nyní mám rozdělit na "2" části jednu jen na část, kde je formulář a druhou kde je jak kontrola, tak zápis do db, atd..

-> jen dotaz, pokud pak chci převést na stránku třeba index.php?ok tak to pak ale tuhle stránku musím mít zase 2x? Jednou u script a jednou u content, protože pak by to házelo chybu v indexu, že daná stránka nebyla nalezene...

Předem díky, každý den se učím nové věci ;)

Ad středníky za závorkou jo byl jsem trochu zvyklej z Cčka, ale už ho taky odendavám ;)
AM_
Profil
tatyalien:
dělal jsem to na "tvrdo" protože funkci get_active_page mě to nebralo
dal sem ji tam pro ilustraci (reálně taková opravdu neexistuje, proto jsem to nazval pseudopříklad :) ), nechtěl jsem tam dát $stranka=$_GET['stranka'], protože to je odstrašující příklad toho, jak se to nedělá. Hacker pak může za určitých podmínek dojít až takto daleko:
index.php?stranka=http://hackeruv-web.cz/backdoor.txt - PHP z tohoto souboru se vykoná a převezme kontrolu nad tvým webem. Je tedy nutné nějaké ošetření názvu stránky, já to třeba dělám takto:
$stranka = isset($_GET['stranka']) ? preg_replace('/[^a-z0-9_\\-]/i', '', $_GET['stranka']) : 'default';
tatyalien
Profil
AM:
Aha ;)
Děkuji
tatyalien
Profil
tak konečná verze je kdyžtak pro ostatní:

index.php
<?php
session_start();
$stranka = isset($_GET['stranka']) ? preg_replace('/[^a-z0-9_\\-]/i', '', $_GET['stranka']) : 'default';
// načtení části skriptu, pokud existuje
if (file_exists("scripts/$stranka.php")) {
    //sem muzes nacpat skript ktery neco provede a pak se v pripade potreby presmeruje jinam (aplikacni cast)
    require "scripts/$stranka.php";
}
?>
<html><head><title>...</title></head>
<body>
<style> 
css...
</style>
html poskládání...
<?php require "content/$stranka.php"; // sem nacpes zobrazovaci cast stranky ?>
</body>
</html>

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: