我为这有点冗长而道歉,但我想展示代码并且不要遗漏任何内容。
目标:用户提交一个注册表单,将表单提交给数据库,该数据库将信息和唯一字符串添加到数据库。用户提交后,会向用户发送一封电子邮件,其中包含指向php页面的链接,该页面最后将该唯一字符串作为URL标识符,如下所示:
xyz.com/activate.php?uid=292ca78b727593baad9a
当用户点击该链接时,他们会在该页面上填写另一个表单,当他们点击提交时,它将激活他们的帐户。
问题:当用户转到提供的链接时,他们会从我的验证页面收到错误,如下所示:
Undefined index: variable in process.php
但是当用户删除URL标识符时,URL显示为:
xyz.com/activate.php
用户没有收到错误,验证页面(process.php)正常工作。我曾尝试将标识符与$_GET['uid']
一起使用,并在运行代码之前检查它是否存在,但结果是相同的。我试图谷歌这个问题时找不到答案所以我很抱歉,如果之前有人问过这个问题。
问题:为什么没有URL标识符但没有使用它?我确实知道URL标识符在页面首次加载时基本上执行$_REQUEST
,这是运行process.php
的内容。有没有办法防止这种情况?
所以你们知道我正在使用的代码我已经在下面发布了它。
activate.php:
<?php
// validate the form.
require_once('process.php');
$validation_rules = array(
'company_name' => array(
'required' => true,
'min-length' => 2
)
);
$db_error = '';
$validate = new validator();
$validate->validate($validation_rules);
if ($validate->validate_result()) {
// the validation passed!
}
?>
<div class="bg v-100 cm-hero-activate">
<div class="v-100">
<div class="v-set v-mid">
<form class="v-mid v-bg-white <?php if(!$validate->validate_result() && $_POST || !empty($error)) { echo "shake"; } ?>" name="activation" action="" method="post">
<fieldset>
<div class="form-content">
<div id="content">
<div class="form-inner in" data-id="1" data-name="activate">
<h1>ACTIVATE YOUR ACCOUNT</h1>
<div class="form-section">
<h2>Personal Info</h2>
<?php if (!empty($db_error)) {
echo $db_error;
} ?>
<div class="field-group">
<input type="text" id="company_name" class="field required" name="company_name" value="<?php $validate->form_value('company_name'); ?>">
<label for="company_name" class="placeholder">Company Name</label>
<?php $validate->error(array('field' => 'company_name', 'display_error' => 'single')); ?>
</div>
</div>
<div class="field-bottom">
<button name="submit" data-name="activate" class="bttn btn-dark btn-hover-gloss">ACTIVATE MY ACCOUNT</button>
</div>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
process.php:
<?php
class validator {
private $validation_rules;
private $errors = array();
private $validate_result = array();
public function validate($rules) {
$this->validation_rules = $rules;
if($this->validation_rules && $_REQUEST) {
foreach($this->validation_rules as $field => $rules) {
$result = $this->process_validation($field, $rules);
if($result == false) {
$this->validate_result[] = 0;
} elseif($result == true) {
$this->validate_result[] = 1;
}
}
}
}
public function form_value($field_name = '') {
if($this->validation_rules) {
if($_REQUEST && $_REQUEST[$field_name]) {
if(!$this->validate_result()) {
echo $_REQUEST[$field_name];
}
}
}
}
public function validate_result() {
if($this->validation_rules) {
if($_REQUEST) {
$final_result = true;
$length = count($this->validate_result);
for($i=0;$i < $length; $i++) {
if($this->validate_result[$i] == 0) {
$final_result = false;
}
}
return $final_result;
}
}
}
private function process_validation($field, $rules) {
$result = true;
$error = array();
foreach($rules as $rule => $value) {
if($rule == 'required' && $value == true) {
if(!$this->required($field, $value)) {
$error[] = "$field - required";
$result = false;
}
} elseif($rule == 'min-length') {
if(!$this->minlength($field, $value)) {
$error[] = "$field - minimun length is $value";
$result = false;
}
}
}
$this->errors[] = array($field => $error);
return $result;
}
public function error($data = '') {
if($this->validation_rules) {
if($_REQUEST) {
foreach($this->errors as $err) {
if(isset($data['field'])) {
foreach($err as $field => $field_error) {
if($data['field'] == $field) {
foreach($field_error as $error_data) {
if(isset($data['display_error']) == 'single') {
echo '<p class="error">' . $error_data . '</p>';
goto next;
} else {
echo '<p class="error">' . $error_data . '</p>';
}
}
next:
}
}
} else {
foreach($err as $field => $field_error) {
foreach($field_error as $error_data) {
if(isset($data['display_error']) == 'single') {
echo '<p class="error">' . $error_data . '</p>';
goto next1;
} else {
echo '<p class="error">' . $error_data . '</p>';
}
}
next1:
}
}
}
}
}
}
private function required($field, $value) {
if(empty($_REQUEST[$field])) {
return false;
} else {
return true;
}
}
private function minlength($field, $value) {
if(strlen($_REQUEST[$field]) < $value) {
return false;
} else {
return true;
}
}
?>
编辑:似乎错误发生在if statement
函数的min-length
上:if(strlen($_REQUEST[$field]) < $value)
编辑2:这也可能有用。文本框中填充了以下内容:<br /><font size='1'><table class='xdebug-error xe-notice' dir='ltr' border='1' cellspacing='0' cellpadding='1'><tr><th align='left' bgcolor='#f57900' colspan=
并在其下面收到此错误:Notice: Undefined index: company_name in C:\...\process.php on line 25 Call Stack #TimeMemoryFunctionLocation 10.0005369632{main}( )...\activate.php:0 20.0029403928validator->form_value( )...\activate.php:80 ">
答案 0 :(得分:2)
$field_name
数组中$_REQUEST
不存在,这就是您收到未定义索引错误的原因。
您没有检查是否设置了值 - 只是通过if语句中的$_REQUEST[$field_name]
访问它。
更改
public function form_value($field_name = '') {
if($this->validation_rules) {
if($_REQUEST && $_REQUEST[$field_name]) {
if(!$this->validate_result()) {
echo $_REQUEST[$field_name];
}
}
}
}
要
public function form_value($field_name = '') {
if($this->validation_rules) {
if($_REQUEST && isset($_REQUEST[$field_name])) {
if(!$this->validate_result()) {
echo $_REQUEST[$field_name];
}
}
}
}
无关的提示。
瞄准更清洁 - 更简洁的可读代码。
$input = [
'name' => 'Matthew',
];
$rules = [
'name' => 'required|string',
];
$v = (new Validator())->validate($input, $rules);
if ($v->fails()) {
// Do something with $v->errors();
return;
}
// Do something with validated input
尽可能避免使用else or elseif
。这可以通过首先寻找负面并且提前退出来实现。尽量不要有太多的嵌套级别。它使您的代码极难阅读并增加了圈复杂度。
另外 - 看一下MVC框架,它可以帮助您构建代码。一个好的开始就像是Laravel https://laravel.com/,有很好的https://laracasts.com/
教程答案 1 :(得分:1)
您收到此错误是因为您有
之类的逻辑if($this->validation_rules && $_REQUEST) {
在PHP中,空数组是 falsy 而非空数组 truthy 。
$_REQUEST
是$_GET
,$_POST
和$_COOKIE
的组合。
当您添加uid
查询参数时,$_REQUEST
将不为空,因此不会 falsy ,您的验证程序将尝试运行但没有预期的POST数据(例如作为company_name
)。
如果您只想验证POST数据,则应该只检查$_POST
。
有关检查是否存在数组键的更安全方法,请参阅Gravy's answer。