Ce am facut nou rescriind acest formular de contact? Pai…am reusit sa scriem cod procedural reutilizabil. Daca dorim sa devenim programatori PHP trebuie sa ne axam foarte, foarte, foarte mult (am omis cumva sa zic “foarte mult”?) pe acest concept de cod procedural reutilizabil. N-ar strica daca ar deveni un reflex in gandirea noastra atunci cand concepem un cod.
contactf.php
<?php
/*
Titlu: Cum fac un formular de contact? (versiunea 2)
Autor: Marian Barbu aka AccesInterzis
Website: http://www.accesinterzis.ro
2010 (c) Toate drepturile rezervate
*/
//-----specific EXACT cu ce campuri se va lucra
#1
$required_fields = array('name', 'phone_number', 'email', 'message', 'security_code', 'send');
$sent_fields = array_keys($_POST);
//-----creez o sesiune pe server pentru a salva in ea codul generat aleatoriu de sistemul CAPTCHA
#2
session_start();
//-----incarc fisierele include
#3
include('includes/validators.inc.php');
include('includes/filter_it.inc.php');
include('includes/validate_form.inc.php');
include('includes/filtered_urls_and_cookies.inc.php');
//------scriptul PHP se executa doar daca cererea a fost facuta de pe aceeasi pagina pe care se afla formularul si doar daca toate campurile formularului au fos trimise
#4
if ($referer == 'http://'.$_SERVER['HTTP_HOST'].$php_self && $required_fields == $sent_fields) {
//-----procesez datele din formular; rezultatul va fi o lista de erori, o lista cu datele nevalide, o lista cu datele valide
#5
include('includes/process_form.inc.php');
//------daca nu exista niciun fel de erori trimit emailul
#6
if(count($processed_form['issues']) == 0) {
//-----infasor datele in htmlentities() si nl2br() deoarece urmeaza sa le trimit
#6.1
$processed_form['good_data'] = filter_it($processed_form['good_data'], array('htmlentities','nl2br'));
#6.2
$to = 'whovisitedme@gmail.com';
$subject = substr($processed_form['good_data']['message'], 0, 20).'...';
$body = 'This message is received from http://'.$_SERVER['HTTP_HOST'].$php_self.'<br /><br />
<strong>Name</strong>: '.$processed_form['good_data']['name'].'<br />
<strong>Phone number</strong>: '.$processed_form['good_data']['phone_number'].'<br />
<strong>Email address</strong>: '.$processed_form['good_data']['email'].'<br />
<strong>Mesagge</strong>: '.$processed_form['good_data']['message'].'<br /><br />
<strong style="color:#c00;">Infos about sender:</strong><br />
<strong>IP address</strong>: '.$_SERVER['REMOTE_ADDR'].'<br />
<strong>browser and operating system</strong>: '.$browser_os.'<br />
<strong>dispatch hour</strong>: '.date("l, F j, Y, H:i:s");
$headers = "From: ".$processed_form['good_data']['email']."\r\n";
//-----ma asigur ca pot formata emailul cu taguri HTML si reguli CSS aplicate inline
#6.3
$headers .= 'MIME-Version: 1.0'."\r\n";
$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
//------daca emailul a fost intr-adevar trimis se va afisa pe monitor un mesaj de confirmare
#6.4
if (mail($to, $subject, $body, $headers)) {
$confirmation = 'Your message was succesfully sent. We will get in touch with you as soon as possible.';
} else {
$confirmation = 'Something is wrong with the server. Your message wasn\'t sent.';
}
$confirmation .= ' <a href="http://'.$_SERVER['HTTP_HOST'].$php_self.'" title="Back" id="back">Back to contact form</a>';
#6.5
$display = 'style="display:none;"';
}
//-----infasor datele in htmlentities() deoarece urmeaza sa le afisez in formular
#7
$get_my_fields = filter_it($get_my_fields, array('htmlentities'));
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>How do I make a contact form?</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="How do I make a contact form?" />
<meta name="keywords" content="contact,form,php,script,send,email" />
<meta name="abstract" content="How do I make a contact form?" />
<meta name="author" content="AccesInterzis" />
<meta name="copyright" content="AccesInterzis" />
<meta name="robots" content="index,follow" />
<meta name="revisit-after" content="7 days" />
<style type="text/css">
* {
margin:0;
padding:0;
outline:none;
}
html {
color:black;
background-color:white;
font: normal normal normal 12px Verdana;
/*font-style font-variant font-weight font-size font-family*/
}
/*INCEPUT - LINIILE CSS CARE CREEAZA SKINUL FORMULARULUI DE CONTACT*/
div#contactf {
width:530px;
margin:0px auto;
}
div#contactf h1 {
color:black;
font: normal normal normal 24px Verdana;
/*font-style font-variant font-weight font-size font-family*/
padding-bottom:5px;
}
div#contactf div {
margin:0 0 5px 0;
}
div#contactf label {
width:115px;
float:left;
}
div#contactf label span {
color:#c00;
}
div#contactf input {
width:200px;
}
div#contactf textarea {
width:400px;
height:150px;
}
div#contactf input, div#contactf textarea {
border:1px #ccc solid;
}
div#contactf input:hover, div#contactf textarea:hover {
border:1px #666 solid;
}
div#contactf input#send {
width:auto;
color:#FFF;
background-color:#333;
border:1px #000 solid !important;
cursor:pointer;
}
div#contactf input#send:hover {
color:#333;
background-color:#fff;
border:1px #333 solid;
}
/*Inceput - stilurile erorilor*/
div#contactf p {
color:#c00;
font-size:10px;
padding:0 0 0 115px;
text-align:left;
}
div#contactf div#name_field label,
div#contactf div#email_field label,
div#contactf div#phone_number_field label,
div#contactf div#message_field label,
div#contactf div#security_code_field label {
color:#c00;
}
div#contactf div#name_field input,
div#contactf div#email_field input,
div#contactf div#phone_number_field input,
div#contactf div#message_field textarea,
div#contactf div#security_code_field input {
border:1px #c00 solid;
color:#c00;
}
div#contactf div#name_field input:hover,
div#contactf div#email_field input:hover,
div#contactf div#phone_number_field input:hover,
div#contactf div#message_field textarea:hover,
div#contactf div#security_code_field input:hover {
border:1px #c00 solid;
}
div#contactf a#back {
color:#900;
font-weight:bold;
text-decoration:underline;
}
/*Sfarsit - stilurile erorilor*/
/*SFARSIT - LINIILE CSS CARE CREEAZA SKINUL FORMULARULUI DE CONTACT*/
</style>
</head>
<body>
<div id="contactf">
<h1>
<label> </label>
Contact us
</h1>
<?php if (isset($confirmation)) echo '<p>'.$confirmation.'</p>'; ?>
<form action="<?php echo 'http://'.$_SERVER['HTTP_HOST'].$php_self; ?>" method="post" <?php if (isset($display)) echo $display; ?>>
<?php echo (isset($processed_form['issues']['name'])) ? '<p>'.$processed_form['issues']['name'].'</p><div id="name_field">' : '<div>' ; ?>
<label for="name">Name<span>*</span>:</label>
<input name="name" type="text" id="name" value="<?php if (isset($get_my_fields['name'])) echo $get_my_fields['name']; ?>" />
</div>
<?php echo (isset($processed_form['issues']['phone_number'])) ? '<p>'.$processed_form['issues']['phone_number'].'</p><div id="phone_number_field">' : '<div>' ; ?>
<label for="phone_number">Phone number<span>*</span>:</label>
<input name="phone_number" type="text" id="phone_number" value="<?php if (isset($get_my_fields['phone_number'])) echo $get_my_fields['phone_number']; ?>" />
</div>
<?php echo (isset($processed_form['issues']['email'])) ? '<p>'.$processed_form['issues']['email'].'</p><div id="email_field">' : '<div>' ; ?>
<label for="email">Email<span>*</span>:</label>
<input name="email" type="text" id="email" value="<?php if (isset($get_my_fields['email'])) echo $get_my_fields['email']; ?>" />
</div>
<?php echo (isset($processed_form['issues']['message'])) ? '<p>'.$processed_form['issues']['message'].'</p><div id="message_field">' : '<div>' ; ?>
<label for="message">Your message<span>*</span>:</label>
<textarea name="message" rows="1" cols="1" id="message"><?php if (isset($get_my_fields['message'])) echo $get_my_fields['message']; ?></textarea>
</div>
<p>
<img src="includes/captchaimage.inc.php?width=120&height=40&characters=5" />
</p>
<?php echo (isset($processed_form['issues']['security_code'])) ? '<p>'.$processed_form['issues']['security_code'].'</p><div id="security_code_field">' : '<div>' ; ?>
<label for="security_code">Are you human?<span>*</span></label>
<input id="security_code" name="security_code" type="text" />
</div>
<div>
<label> </label>
<input name="send" type="submit" id="send" value="send" />
</div>
</form>
</div>
</body>
</html>
validators.inc.php
<?php
//----------lista de validatori pentru campurile tuturor formularelor
$validators = array('name' => array('required' => true,
'min_chars' => 3,
'max_chars' => 30,
'regex' => '/^[a-z0-9][a-z0-9_ ]*[a-z0-9]$/i'),
'phone_number' => array('required' => true,
'min_chars' => 3,
'max_chars' => 30,
'regex' => '/^[0-9+][0-9. ]*[0-9]$/'),
'email' => array('required' => true,
'min_chars' => 3,
'max_chars' => 30,
'regex' => '/^[a-z0-9][a-z0-9_.]+@[a-z0-9-.]+\.[a-z]{2,4}$/i'),
'website' => array('required' => false,
'min_chars' => 3,
'max_chars' => 30,
'regex' => '/^http:\/\/[a-z0-9.-]+\.[a-z]{2,4}$/i'),
'comment' => array('required' => true,
'min_chars' => 3,
'max_chars' => 20000,
'regex' => '/.*/i'),
'message' => array('required' => true,
'min_chars' => 3,
'max_chars' => 20000,
'regex' => '/.*/i'),
'username' => array('required' => true,
'min_chars' => 3,
'max_chars' => 30,
'regex' => '/^[a-z0-9][a-z0-9_ ]*[a-z0-9]$/i'),
'password' => array('required' => true,
'min_chars' => 5,
'max_chars' => 30,
'regex' => '/^[a-z0-9]*$/i'),
'security_code' => array('required' => true,
'min_chars' => 3,
'max_chars' => 10,
'regex' => '/^[a-z0-9]*$/i'));
?>
filter_it.inc.php
<?php
function filter_it($unfiltered_data, $filters) {
$wrapped_data = array();
foreach ($unfiltered_data as $k => $v) {
foreach ($filters as $filter) {
switch ($filter) {
case 'htmlentities':
$v = htmlentities($v, ENT_QUOTES, 'utf-8');
break;
default:
$v = $filter($v);
}
}
$wrapped_data[$k] = $v;
}
return ($wrapped_data);
}
?>
validate_form.inc.php
<?php
//----------functia care valideaza datele introduse de utilizator
function validate_form ($unverified_form, $validators) {
include('includes/replacers.inc.php');
$issues = array();
$bad_data = array();
foreach ($unverified_form as $k => $v) {
if (empty($unverified_form[$k])) {
if ($validators[$k]['required'] == true) {
$issues[$k] = 'You forgot to enter the <strong>'.$replacers[$k].'</strong>.';
$bad_data[$k] = $unverified_form[$k];
}
} else {
if (strlen($unverified_form[$k]) < $validators[$k]['min_chars']) {
$issues[$k] = 'The <strong>'.$replacers[$k].'</strong> is too short.';
$bad_data[$k] = $unverified_form[$k];
} else {
if (strlen($unverified_form[$k]) > $validators[$k]['max_chars']) {
$issues[$k] = 'The <strong>'.$replacers[$k].'</strong> is too long.';
$bad_data[$k] = $unverified_form[$k];
} else {
if (!preg_match($validators[$k]['regex'], $unverified_form[$k])) {
$issues[$k] = 'The <strong>'.$replacers[$k].'</strong> isn\'t valid.';
$bad_data[$k] = $unverified_form[$k];
}
}
}
}
}
$good_data = array_diff_key($unverified_form, $bad_data);
$result = array('issues' => $issues, 'bad_data' => $bad_data, 'good_data' => $good_data);
return ($result);
}
?>
replacers.inc.php
<?php
//----------lista cuvintelor care inlocuiesc cheile array-ul in mesajele de eroare
$replacers = array('name' => 'name',
'phone_number' => 'phone number',
'email' => 'email address',
'website' => 'website URL',
'comment' => 'comment',
'message' => 'message',
'username' => 'username',
'password' => 'password',
'security_code' => 'security code');
?>
filtered_urls_and_cookies.inc.php
<?php
//-----infasor in strip_tags() si htmlentities() URL-urile obtinute dinamic, http_user_agent-ul si cookie-urile ca sa ma asigur ca nu contin cod malitios
$php_self = htmlentities(strip_tags($_SERVER['PHP_SELF']), ENT_QUOTES, 'utf-8');
$referer = (isset($_SERVER['HTTP_REFERER'])) ? htmlentities(strip_tags($_SERVER['HTTP_REFERER']), ENT_QUOTES, 'utf-8') : NULL;
$browser_os = htmlentities(strip_tags($_SERVER['HTTP_USER_AGENT']), ENT_QUOTES, 'utf-8');
$cookie = (isset($_COOKIE)) ? filter_it($_COOKIE, array('strip_tags', 'htmlentities')) : NULL;
?>
process_form.inc.php
<?php
//-----incarc din lista generala de validatori validatorii pentru campurile formularului meu
$get_my_fields = array_intersect_key($_POST, $validators);
//-----infasor datele in trim() si stripslashes() deoarece urmeaza sa incep procesul de validare
$get_my_fields = filter_it($get_my_fields, array('trim', 'stripslashes'));
//-----rezultatul procesului de validare va fi o lista de erori, o lista cu datele nevalide, o lista cu datele valide
$processed_form = validate_form($get_my_fields, $validators);
?>
Am reusit sa aduc codul la acest nivel datorita lui OriginalCopy. Chiar daca el ar fi dorit sa arate muuuult mai compact. Dar el e un programator foarte bun, de multi ani in aceasta meserie, iar eu sunt doar un anonim care a inceput sa cocheteze cu aceste limbaje de programare web acum circa 2 ani in urma.
Sper ca la versiunea 3 a formularului sa implementez validare client-side cu jQuery, sa adaug un camp in care utilizatorul poate atasa si un fisier la email si sa rescriu codul PHP de asa natura incat sa fie mai compact si mai aproape de conceptul de cod procedural reutilizabil.
Publica acest articol pe Twitter
Articole asemanatoare: