当url标识符存在时,PHP未定义变量

时间:2016-08-11 06:00:56

标签: php html forms

我为这有点冗长而道歉,但我想展示代码并且不要遗漏任何内容。

目标:用户提交一个注册表单,将表单提交给数据库,该数据库将信息和唯一字符串添加到数据库。用户提交后,会向用户发送一封电子邮件,其中包含指向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 ">

2 个答案:

答案 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