目前我正在尝试使用PHP验证表单。问题是,即使输入错误,PHP也会将其解释为正确。显然我现在不知道为什么,虽然我有一个假设。 这是代码:
if(isset($_GET['contact'])){
// Validation functions
// Name
function validate_name(){
$name = $_POST['customer'];
if(strlen($name) > 0){
trim(mysql_real_escape_string($name));
return true;
}else {
return false;
}
}
// Mail
function validate_mail(){
$mail = $_POST['mail'];
if(preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $mail) && strlen($mail) > 0){
return true;
}else {
return false;
}
}
// Message
function validate_message(){
$message = $_POST['message'];
if(strlen($message) > 0){
trim(mysql_real_escape_string($message));
return true;
}else {
return false;
}
}
validate_name();
validate_mail();
validate_message();
if(validate_name == true && validate_mail == true && validate_message == true){
echo "Ok!";
}else{
echo "Error!";
}
}
我知道的一件事是坏事:if(validate_name == true && validate_mail == true && validate_message == true){}
。
但是,如果我没有弄错,这仍然有效,因为PHP可以处理这样的事情(PHP只给出通知,而不是错误)。但如果做得对,必须有更好的方法?
我发现的第二个问题是,PHP基本上调用函数是正确的,但在函数内部,if-else不起作用。为什么?我不明白这个......
答案 0 :(得分:3)
到目前为止我看到了3个问题:
mysql_real_escape_string()
在连接处于活动状态时有效,否则返回FALSE。validate_name
”但它的语法是错误的,如果你想把它作为一个变量或一个函数(缺少括号)拿你的第一个功能,例如,你可以做(如果你有一个有效的连接):
function validate_name($customer){
if(strlen($customer) > 0){
$customer = trim(mysql_real_escape_string($customer));
return $customer;
}else {
return false;
}
}
以及后来:
if(validate_name($_POST['customer'] AND ....)
我看到的另一件事,因为validate_name()
和validate_message()
正在执行相同的操作,为什么不将它作为单个函数(例如validate($postIndex)
),将$ _POST索引作为参数?它更干一点。像:
$name = validate($_POST['customer']);
$message = validate($_POST['message']);
$email = validate_email($_POST['email']);
if($name AND $email AND $message){
// now here you also have the trimmed/escaped values to work with.
}
答案 1 :(得分:3)
第一个问题是,你的函数返回一个布尔结果,它们不会持久地表示一个值。你是否条件基本上只是检查是否定义了常量“validate_name”,“validate_mail”和“validate_message”。遇到未定义的常量时,PHP会将常量设置为等于自身。然后类型强制将字符串值“validate_name”,“validate_mail”和“validate_message”与true进行比较,这是通过将布尔值和字符串值都转换为1值来实现的。然后他们被认为是平等的。
你应该做的是:
$isNameOk = validate_name();
$isMessageOk = validate_message();
$isMailOk = validate_mail();
if($isNameOk && $isMessageOk && $isMailOk)
echo "Ok!";
else
echo "Error!";
第二个不相关的错误就是你正在做的功能。你在函数的范围内设置$ name,$ mail和$ message等变量(这很好),但是你也可以在它们上发出trim和mysql_escape,而实际上将值设置回变量。即它应该是:
$name = trim(mysql_escape_string($name));
最重要的是,您将这些值清理剂应用于您的变量,但您的函数实际上并未对这些变量执行任何操作。我假设您希望稍后在脚本中使用已清理的$ name,$ mail和$ message变量。但是因为它们在本地函数范围内定义,永远不会起作用。
快速解决方法是在全局范围内定义变量,并使用全局关键字在函数中引用它们,但这很难看。更好的解决方案是对代码进行客观化,并使这些值和函数成为类对象的成员。
class Validator {
protected $name;
protected $isNameOk;
protected $mail;
protected $isMailOk;
protected $message;
protected $isMessageOk;
public function validate($data) {
$this->isNameOk = $this->checkAndSanitizeName($data['name']);
$this->isMessageOk = $this->checkAndSanitizeMessage($data['message']);
$this->isMailOk = $this->checkAndSanitizeMail($data['mail']);
if($this->isNameOk && $this->isMessageOk && $this->isMailOk)
return true;
return false;
}
protected function checkAndSanitizeName($name) {
$this->name = trim(mysql_real_escape_string($name));
if(strlen($name) > 0)
return true;
return false;
}
protected function checkAndSanitizeMail($mail) {
$this->mail = trim(mysql_real_escape_string($mail));
if(preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $this->mail) && strlen($this->mail) > 0)
return true;
return false;
}
protected function checkAndSanitizeMessage($message) {
$this->message = trim(mysql_real_escape($mail));
if(strlen($this->message) > 0)
return true;
return false;
}
public function getName() { return $this->name; }
public function getMail() { return $this->mail; }
public function getMessage() { return $this->message; }
public function isMailOk() { return $this->isMailOk; }
public function isNameOk() { return $this->isNameOk; }
public function isMessageOk(){ return $this->isMessageOk; }
}
用法是:
$validator = new Validator();
if($validator->validate($_POST))
{
echo "Ok!";
echo "Thanks " . $validator->getName() . " for posting your message.";
}
else
{
echo "Error!";
if(!$validator->isMailOk())
echo "Mail was invalid";
// etc.
}
我在回复框中输出了这个代码,所以请把它拿出来。可能需要一些拼写错误。
答案 2 :(得分:2)
行。由于是周末,我没有更好的事情要做,我将解决您的问题,并解释您的代码有什么问题。
首先回答您的原始问题:
PHP只发出通知
正如通知所述:
注意:使用未定义的常量validate_name - 在...中假定为'validate_name'
这是因为您所在的行:
if(validate_name == true ...
validate_name
没什么。如果它是一个变量,如果它是一个函数调用它将是$validate_name
,它应该是validate_name()
。所以PHP认为它是一个常数。没有咆哮这是否是PHP试图“帮助”你的聪明举动它做它做的。因此,PHP基本上将其作为常量处理,其值为validate_name
。
PHP的作用如下:
if ('somestring' == true) // this will always be truthy.
现在进一步修复/改进您的代码:
我也不确定你对超全球的使用。您使用$_GET['contact']
和$_POST['customer']
。因此,您要混合_POST
和_GET
。不过这可能是不正确的。
如果您的表单的动作为“/file.php?contact=something”且表单方法设置为post
,则表示完全没问题。
最好将params添加到函数中。所以改变:
function validate_name(){
要
function validate_name($name){
而不是依赖_POST
值。这样您就可以在不需要任何后期数据的情况下测试代码。
在您的validate_name
和validate_message
功能中,您正在执行此操作:
trim(mysql_real_escape_string($name));
trim(mysql_real_escape_string($message));
这有两个问题:
在验证邮件功能中,您可以执行以下操作:
if(preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $mail) && strlen($mail) > 0){
除了我确信正则表达式没有获得所有有效的电子邮件地址之外,最好首先检查字符串是否已填写。
现在在以下代码中更正所有问题:
if(isset($_GET['contact'])){
function validate_name($name)
{
if(strlen($name) === 0) {
return false;
}
return true;
}
function validate_mail($mail)
{
if (strlen($mail) === 0 || filter_var($mail, FILTER_VALIDATE_EMAIL)) {
return false;
}
return true;
}
function validate_message($message)
{
if(strlen($message) === 0) {
return false;
}
return true;
}
if(validate_name($_POST['customer']) && validate_mail($_POST['mail']) && validate_message($_POST['message'])) {
echo "Ok!";
} else {
echo "Error!";
}
}
答案 3 :(得分:2)
validate_name == true
更改为validate_name()
。这将调用该函数并返回布尔值。无需将已经是布尔值的东西与另一个布尔值进行比较以生成布尔值...只需使用返回的值即可。对其他两个函数做同样的事情。trim()
和mysql_real_escape_string()
,但您没有保存这些更改。这些不是通过引用传递的,因此您需要将更改保存回$_POST
变量。这是更新后的代码:
if(isset($_GET['contact'])){
// Validation functions
// Name
function validate_name(){
$name = $_POST['customer'];
if(strlen($name) > 0){
$_POST["customer"] = trim(mysql_real_escape_string($name));
return true;
}else {
return false;
}
}
// Mail
function validate_mail(){
$mail = $_POST['mail'];
if(preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $mail) && strlen($mail) > 0){
return true;
}else {
return false;
}
}
// Message
function validate_message(){
$message = $_POST['message'];
if(strlen($message) > 0){
$_POST["message"] = trim(mysql_real_escape_string($message));
return true;
}else {
return false;
}
}
if(validate_name() && validate_mail() && validate_message()){
echo "Ok!";
}else{
echo "Error!";
}
}
答案 4 :(得分:1)
看起来好像你没有调用你在if-block中编写的函数。你也可以简写那句话。
if( validate_name() && validate_mail() && validate_message() )
{echo 'Ok!';}
因为所有这些都返回布尔结果,所以if语句不需要显式== true检查。此外,您还需要小心清理任何GET / POST变量。
答案 5 :(得分:1)
您需要稍微更改代码的最后一位。像这样:
if(validate_name() && validate_mail() && validate_message()){
//do stuff with the info here
}else{
echo "Error!";
//display error information and show them the form again.
}
答案 6 :(得分:1)
你可以这样做:
它不是最好的解决方案,但没有显示通知或错误。快乐的编码。
if(isset($_GET['contact'])){
// Validation functions
// Name
function validate_name(){
if(!isset($_POST['customer'])) {
return false;
}
if(strlen($_POST['customer']) > 0){
$_POST['customer'] = trim($_POST['customer']);
return true;
}else {
return false;
}
}
// Mail
function validate_mail(){
if(!isset($_POST['mail'])) {
return false;
}
return preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/', $_POST['mail']);
}
// Message
function validate_message(){
if(!isset($_POST['message'])) {
return false;
}
if(strlen($_POST['message']) > 0){
$_POST['message'] = trim($_POST['message']);
return true;
} else {
return false;
}
}
if(validate_name() == true && validate_mail() == true && validate_message() == true){
echo "Ok!";
}else{
echo "Error!";
}
}