Вход

Просмотр полной версии : Минимальная, одностраничная PHP регистрация: БД, форма, $_POST, $_SESSION


xcislav
01.01.2015, 09:55
Кроме структуры, формируемой header("location:") всё достаточно прямолинейно,
Отправка формы попадает -> соединением с БД (PDO+немного SQL кода)
и
всё происходит методом $_POST и выводится в $_SESSION.

index.php:
<!DOCTYPE html>
<html>
<h1>Register</h1>
<form method="POST">
<input type="text" name="user">
<input type="pass" name="pass">
<input type="submit">
</form>
<?php
session_start();
if(isset($_POST['user'], $_POST['pass'])){
require 'connect.php';
$zr++;
$query = d()->prepare("INSERT INTO u (user, pass, loc) VALUES (:user, :pass, :loc)");
$query->bindParam(':user', $_POST['user']);
$query->bindParam(':pass', $_POST['pass']);
$query->bindParam(':loc', $zr);
if($query->execute()){
$_SESSION['user'] = $row['user'];
$_SESSION['pass'] = $row['pass'];
header("Location: ".$_SERVER['PHP_SELF']);
} else{
echo 'ERROR';
}
}
?>
<h1>Login</h1>
<form method="POST">
<input type="text" name="user">
<input type="pass" name="pass">
<input type="submit">
</form>
<?php
echo $_POST['user'];
if(isset($_POST['user'], $_POST['pass'])){
require 'connect.php';
$query = d()->prepare("SELECT user, pass FROM u WHERE user=:user AND pass=:pass");
$query->bindParam(':user', $_POST['user']);
$query->bindParam(':pass', $_POST['pass']);
$query->execute();
if($row = $query->fetch()){
$_SESSION['user'] = $row['user'];
$_SESSION['pass'] = $row['pass'];
header("Location: ".$_SERVER['PHP_SELF']);
}
}
$us=$_SESSION['user'];
echo 'user ',$us;
?>
<?php
if(isset($_SESSION['user'])){
$us=$_SESSION['user'];
echo '
user ',$us, ' ', '<a href="logout.php">Logout</a>';
echo '
', '<a href="zrs.php">zero session</a>';
}
?>
</html>

connect.php:
<?php
function d(){
try{
$db = new pdo("mysql:host=localhost;dbname=tx;","root","hyuiuik");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
} catch(PDOException $e){
echo 'ERROR', $e->getMessage();
}
}
?>

ВИД на табл. пользователей:
mysql> select * from u;
+----+--------+------+------+
| id | user | pass | loc |
+----+--------+------+------+
| 1 | a | asdf | 0 |
| 2 | b | bsdf | 0 |
| 3 | b | bsdf | 0 |
| 4 | c | csdf | 0 |

Но непонимание на этапе формирования структуры подготовления и отправки собранных данных.
примерный вид:

1.php

<?php
session_start();
К
О
Д
session_write_close();

if( isset($_POST['user'] ){
К
О
Д
}else{
К О Д
}

if( !isset($_POST['user']) ){
header("location: http://" . $_SERVER['HTTP_HOST'] . "/login.php");
}else{
//user установлен
КОД ЗАПУСКА
}

kostyanet
08.01.2015, 10:07
В форме регистрации нет фазы выдачи ранее сохраненных данных, форма заведомо пустая, поэтому все начинается с проверки данных от клиента.


function run()
if(!empty($_POST))
{
// валидация, сохранение, редирект или exception
}
// catch block
// рендер сообщения об ошибке
// рендер формы
}

kostyanet
08.01.2015, 10:18
Ну а вообще - говнокод. Так не делают давным давно.

после

header("Location: ".$_SERVER['PHP_SELF']);

полезно добавить

exit;

После

if(isset($_POST['user'], $_POST['pass'])){


try{
// проверки. Если что-то не понравилось то в любом месте
if($something_wrong)
throw new Exception('Жалоба что не понравилось');
// иначе flow катится как обычно до записи и редиректа с Exit'ом
}
catch(Exception $e) {
echo $e->getMessage();
}


Одно только неясно - зачленом вам pdo в таком гавнокоде.

Обработку прерывания можно сделать системной, или классовой. Но самое простое это трай-катч. А чтобы собирать свои ошибки и рендерить красиво, делается расширения Exception и там все дописывается, как правило __toString() делается свой. Или допустим чтобы собрать сразу все ошибки в массив делается свой приемник, ибо стандартный Exception массивов на входе не понимает.

Vlasenko Fedor
08.01.2015, 16:52
Прочтите статью, найдите что упустили :)
Типичные ошибки при защите сайтов от CSRF-атак (http://habrahabr.ru/post/235247/)
токены нужно вставлять к любой форме сайта. В вышеприведенном случае, чтобы не за спамили регистрацией