PDO + header vraag
Wanneer een gebruiker zich registreert en de registratie is succesvol dan wil ik de pagina opnieuw laden d.m.v. header('Location:www.url.nl'). Hier is echter waar het fout gaat. Ik heb een user class met een register method. Wanneer deze slaagt moet er worden doorverwezen om opnieuw verzenden van het formulier middels F5 of een refresh te voorkomen. Maar omdat het try-catch blok midden op de pagina staat is er al ouput geweest en krijg ik de bekende cannot modify headers error.
Dit zou betekenen dat wanneer je gebruik maakt van exceptions dus nooit kunt door verwijzen of dat je alle try-catch blokken bovenaan de pagina moet zetten? Dit laatste doet dan weer de werking van try-catch teniet, namelijk het weergeven van errors op de positie waar de fout zich voordoet.
Hieronder de code:
config.inc.php:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
#===== Show Errors =====#
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors',true);
#===== Debug Mode =====#
$debug_mode = false; // Turn debug mode on/off -> true=on, false=off
#===== Database Settings =====#
define('DB_HOST', 'db.***.nl'); // Database host
define('DB_USER', '***'); // Database username
define('DB_PASS', '***'); // Database password
define('DB_DB', '***'); // Database name
define('PDO_DSN', 'mysql:host=db.***.nl;port=3307;dbname=***');
#===== Define paths =====#
define('BASE_PATH', $_SERVER['DOCUMENT_ROOT']); // T.b.v. includes
define('BASE_DIR', 'http://www.***.nl'); // T.b.v. navigatie en header redirects
#===== Sessie Starten =====#
session_start();
#===== Include SafePDO Class =====#
// include('class/safe_pdo.class.php');
// Safe connect to the database with defined constants
// $db = new SafePDO(PDO_DSN, DB_USER, DB_PASS);
#===== Connect to the database =====#
try
{
$db = new PDO('mysql:host=db.***.nl;dbname=***', DB_USER, DB_PASS);
}
catch(PDOException $e)
{
echo $e->getMessage();
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
#===== Include Classes and Functions =====#
include(BASE_PATH . '/inc/includes.inc.php');
#===== Sessie updaten =====#
$user = new User;
if($user->isLogged()){
// Update LoginTime
$_SESSION['timeout'] = time()+3600;
$object = new User($_SESSION['userId']);
}
// Uitloggen
if(isset($_GET['action']) && ($_GET['action']=='logoff')) {
session_destroy();
// Doorsturen om 'ingelogd blijven' te voorkomen.
header('Location:'.BASE_DIR.'/login.php');
exit();
}
?>
#===== Show Errors =====#
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors',true);
#===== Debug Mode =====#
$debug_mode = false; // Turn debug mode on/off -> true=on, false=off
#===== Database Settings =====#
define('DB_HOST', 'db.***.nl'); // Database host
define('DB_USER', '***'); // Database username
define('DB_PASS', '***'); // Database password
define('DB_DB', '***'); // Database name
define('PDO_DSN', 'mysql:host=db.***.nl;port=3307;dbname=***');
#===== Define paths =====#
define('BASE_PATH', $_SERVER['DOCUMENT_ROOT']); // T.b.v. includes
define('BASE_DIR', 'http://www.***.nl'); // T.b.v. navigatie en header redirects
#===== Sessie Starten =====#
session_start();
#===== Include SafePDO Class =====#
// include('class/safe_pdo.class.php');
// Safe connect to the database with defined constants
// $db = new SafePDO(PDO_DSN, DB_USER, DB_PASS);
#===== Connect to the database =====#
try
{
$db = new PDO('mysql:host=db.***.nl;dbname=***', DB_USER, DB_PASS);
}
catch(PDOException $e)
{
echo $e->getMessage();
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
#===== Include Classes and Functions =====#
include(BASE_PATH . '/inc/includes.inc.php');
#===== Sessie updaten =====#
$user = new User;
if($user->isLogged()){
// Update LoginTime
$_SESSION['timeout'] = time()+3600;
$object = new User($_SESSION['userId']);
}
// Uitloggen
if(isset($_GET['action']) && ($_GET['action']=='logoff')) {
session_destroy();
// Doorsturen om 'ingelogd blijven' te voorkomen.
header('Location:'.BASE_DIR.'/login.php');
exit();
}
?>
Register.php:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php include('inc/config.inc.php'); ?>
<h1>Registreren</h1>
<!-- Register Form -->
<form action="http://www.***.nl/register.php?action=register" method="post">
<label for="email">E-mail:</label>
<input type="text" name="email" id="email" value="" size="23" />
<label for="password">Wachtwoord:</label>
<input type="text" name="password" id="password" size="23" />
<input type="submit" />
</form>
<?php
// Registreren
if(($_SERVER['REQUEST_METHOD']=='POST') && isset($_GET['action']) && $_GET['action']=='register') {
try
{
$user->register($_POST);
}
catch(PDOException $e)
{
if($debug_mode) {
echo '<pre>';
echo 'Regelnummer: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage().'<br>';
echo '</pre>';
} else {
echo '<p>Fout: '.$e->getMessage().'</p>';
}
}
}
?>
<h1>Registreren</h1>
<!-- Register Form -->
<form action="http://www.***.nl/register.php?action=register" method="post">
<label for="email">E-mail:</label>
<input type="text" name="email" id="email" value="" size="23" />
<label for="password">Wachtwoord:</label>
<input type="text" name="password" id="password" size="23" />
<input type="submit" />
</form>
<?php
// Registreren
if(($_SERVER['REQUEST_METHOD']=='POST') && isset($_GET['action']) && $_GET['action']=='register') {
try
{
$user->register($_POST);
}
catch(PDOException $e)
{
if($debug_mode) {
echo '<pre>';
echo 'Regelnummer: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage().'<br>';
echo '</pre>';
} else {
echo '<p>Fout: '.$e->getMessage().'</p>';
}
}
}
?>
user_controller.class.php (aangepast):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
class UserController{
public function register($p)
{
$error = false;
// Controleer of alle velden zijn ingevuld.
if(!$p['password']) {
throw new PDOException('U dient een wachtwoord in te vullen.');
$error = true;
}
if(!$p['email']) {
throw new PDOException('U dient een e-mailadres in te vullen.');
$error = true;
}
// Valideer e-mailadres
if(!filter_var($p['email'], FILTER_VALIDATE_EMAIL)) {
throw new PDOException('U dient een geldig e-mailadres in te vullen.');
$error = true;
}
// Contoleer of het e-mailadres reeds staat geregistreerd
$sql = $this->_db->prepare("SELECT email FROM users WHERE email = :email");
$sql->bindParam(":email", $p['email']);
$sql->execute();
if($sql->rowCount() > 0){
throw new PDOException('Dit e-mailadres is reeds in gebruik. Kies een ander e-mailadres.');
$error = true;
}
// Usergegevens in de database plaatsen
if(!$error) {
$password = md5($p['password']);
$sql = $this->_db->prepare("INSERT INTO users (password, email) VALUES (:password, :email)");
$sql->bindParam(":password", $password);
$sql->bindParam(":email", $p['email']);
if(!$sql->execute()) {
// Foutmelding weergeven
throw new PDOException('U bent niet geregistreerd.');
} else {
// Succesmelding weergeven
$_SESSION['sMess'] = 'U bent succesvol geregistreerd.';
// Doorsturen naar pagina 'uitgelogd blijven' te voorkomen
header('Location:'.BASE_DIR.'/login.php');
// Script stoppen om wissen van sessie te voorkomen
exit();
}
}
}//--> register
}
?>
class UserController{
public function register($p)
{
$error = false;
// Controleer of alle velden zijn ingevuld.
if(!$p['password']) {
throw new PDOException('U dient een wachtwoord in te vullen.');
$error = true;
}
if(!$p['email']) {
throw new PDOException('U dient een e-mailadres in te vullen.');
$error = true;
}
// Valideer e-mailadres
if(!filter_var($p['email'], FILTER_VALIDATE_EMAIL)) {
throw new PDOException('U dient een geldig e-mailadres in te vullen.');
$error = true;
}
// Contoleer of het e-mailadres reeds staat geregistreerd
$sql = $this->_db->prepare("SELECT email FROM users WHERE email = :email");
$sql->bindParam(":email", $p['email']);
$sql->execute();
if($sql->rowCount() > 0){
throw new PDOException('Dit e-mailadres is reeds in gebruik. Kies een ander e-mailadres.');
$error = true;
}
// Usergegevens in de database plaatsen
if(!$error) {
$password = md5($p['password']);
$sql = $this->_db->prepare("INSERT INTO users (password, email) VALUES (:password, :email)");
$sql->bindParam(":password", $password);
$sql->bindParam(":email", $p['email']);
if(!$sql->execute()) {
// Foutmelding weergeven
throw new PDOException('U bent niet geregistreerd.');
} else {
// Succesmelding weergeven
$_SESSION['sMess'] = 'U bent succesvol geregistreerd.';
// Doorsturen naar pagina 'uitgelogd blijven' te voorkomen
header('Location:'.BASE_DIR.'/login.php');
// Script stoppen om wissen van sessie te voorkomen
exit();
}
}
}//--> register
}
?>
Daarnaast wil ik in ontwikkelingsfase een andere error weergeven dan na live-gang. Is het handig om dit op deze manier te realiseren? Dus d.m.v en dan een if-else in het try-catch blok? Of is daar een betere manier voor?
Gewijzigd op 11/01/2011 14:49:57 door The Ultimate
kun je niet ipv header(Location) niet gewoon een meta refresh doen?
Waarom verzamel je niet de output en verstuur je die pas op het einde naar de browser?
Thomas van den Bulk op 11/01/2011 15:15:00:
Nee, dit is geen optie. Meta-refresh wordt sowieso niet aangeraden.kun je niet ipv header(Location) niet gewoon een meta refresh doen?
TJVB tvb op 11/01/2011 15:17:26:
Je bedoelt MVC? Omdat ik daar nog niet helemaal aan toe ben ben ik bang...In dat geval zou ik namelijk meteen overstappen op Zend.Je zegt eigenlijk al wat het probleem is, je hebt al output. Waarom verzamel je niet de output en verstuur je die pas op het einde naar de browser?
Je kunt het ook gewoon los in een variabele plaatsen en die aan het einde naar de browser sturen.
TJVB tvb op 11/01/2011 15:21:08:
Maar dan krijg je toch een class/method die alle output verzamelt en vervolgens naar de browser doorstuurt en dat lijkt m.i. toch wel zeer sterk op MVC. Bovendien zal ik dit dan voor alle pagina's toe moeten gaan passen.MVC zegt niks over wanneer je de output verstuurd. Je kunt het ook gewoon los in een variabele plaatsen en die aan het einde naar de browser sturen.
Wellicht is het dan handiger om verzenden van het formulier bovenaan de pagina's af te handelen en eventuele (fout)meldingen in sessie te zetten. Alleen gaat daarmee het idee van exceptions/try-catch eraan aangezien je dan nog de fouten niet weergeeft op de plaats waar deze zich voordoet. Dan zou ik net zo goed de foutmelding direct in de functie al in een sessie kunnen plaatsen in plaats van een exceptie te gooien.
Gewijzigd op 11/01/2011 15:28:24 door The Ultimate
En je kunt hier nog veel makkelijker het oplossen door het formulier naar onderen te plaatsen.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php include('inc/config.inc.php');
$output = '';//vul het ergens met je head etc
// Registreren
if(($_SERVER['REQUEST_METHOD']=='POST') && isset($_GET['action']) && $_GET['action']=='register') {
try
{
$user->register($_POST);
}
catch(PDOException $e)
{
if($debug_mode) {
echo '<pre>';
echo 'Regelnummer: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage().'<br>';
echo '</pre>';
} else {
echo '<p>Fout: '.$e->getMessage().'</p>';
}
}
}
$output .= '<h1>Registreren</h1>
<!-- Register Form -->
<form action="http://www.***.nl/register.php?action=register" method="post">
<label for="email">E-mail:</label>
<input type="text" name="email" id="email" value="" size="23" />
<label for="password">Wachtwoord:</label>
<input type="text" name="password" id="password" size="23" />
<input type="submit" />
</form>';
echo $output;
?>
$output = '';//vul het ergens met je head etc
// Registreren
if(($_SERVER['REQUEST_METHOD']=='POST') && isset($_GET['action']) && $_GET['action']=='register') {
try
{
$user->register($_POST);
}
catch(PDOException $e)
{
if($debug_mode) {
echo '<pre>';
echo 'Regelnummer: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage().'<br>';
echo '</pre>';
} else {
echo '<p>Fout: '.$e->getMessage().'</p>';
}
}
}
$output .= '<h1>Registreren</h1>
<!-- Register Form -->
<form action="http://www.***.nl/register.php?action=register" method="post">
<label for="email">E-mail:</label>
<input type="text" name="email" id="email" value="" size="23" />
<label for="password">Wachtwoord:</label>
<input type="text" name="password" id="password" size="23" />
<input type="submit" />
</form>';
echo $output;
?>
En waarom denk je dat je nog niet toe bent aan MVC? Pak een standaard framework zoals Kohana en maak je controllers aan, lees wat tutorials en je bent er al snel. Je bent hier al bijna langer mee bezig denk ik.
Gewijzigd op 11/01/2011 15:39:16 door TJVB tvb
Jaja, op die manier. Alles in 1 variabele proppen en aan het einde echoeen.
Zijn frameworks zoals Zend en Kohana ook te gebruiken als je een externe host hebt? De website wordt namelijk gehost door Mijndomein.nl
En waarom raad jij Kohana aan?
Zend Framework is gigantisch uitgebreid maar heeft daarmee ook veel overhead.
Ik ben zelf zeer enthousiast over Kohana omdat het duidelijk PHP5 code is en makkelijk uit te breiden is met eigen modules terwijl de basis (MVC, ORM etc) er al in zitten.
Maar het belangrijkste is wat voor eisen heb je en ga eens vergelijken.
echo 'test';
$content = ob_get_contents();
ob_flush();
Zo kan het ook, output buffering is alleen ook weer niet optimaal..