对于我的注册脚本,我希望能够提醒用户是否已经采用了名称等等。但是,如果我返回要使用的对象,则脚本停止,我无法调用view()
例如我的网站是boostrapped所以一切都通过索引。索引实例化APP并调用init()。 init将我的url转换为有用的东西,比如控制器,方法和参数,并调用它们。例如site.com/controller/method/param1/param2
class App
{
protected $controller = '';
protected $method = 'index';
protected $params = [];
public function init()
{
if (isset($_GET['url'])) {
$url = explode('/', filter_var(trim($_GET['url'], '/'), FILTER_SANITIZE_URL));
}
else
{
header('Location:/home');
}
if (file_exists(CONTROLLER . $url[0] . '.php'))
{
$this->controller = $url[0];
unset($url[0]);
}
else
{
if (DEVELOPMENT == true)
{
exit(var_dump($url));
}
else
{
header('Location:/home');
}
}
require_once CONTROLLER . $this->controller . '.php';
$this->controller = new $this->controller;
if (isset($url[1]))
{
if (method_exists($this->controller, $url[1]))
{
$this->method = $url[1];
unset($url[1]);
}
}
$this->params = $url ? array_values($url) : [];
call_user_func_array([$this->controller, $this->method], $this->params);
}
public function view($view, $data = '')
{
require_once VIEW . 'header.htm';
require_once VIEW . $view . '.htm';
require_once VIEW . 'footer.htm';
}
}
因此,当我访问site.com/user/register时,我的注册方法会自动调用。
如果我添加return $ this-> alert然后我停止脚本并且视图永远不会被调用,所以我杀了视图并且不回应警报。
如果我没有返回$ this->提醒,那么我可以将$ this->警告作为参数传递给视图但是我无法阻止脚本运行并且即使是警报已经发出。
class User extends App
{
public $alert;
public function register()
{
if (isset($_POST['submit']))
{
$username = trim($_POST['username']);
$usernameActual = strtoupper($username);
$email = trim($_POST['email']);
$password = trim($_POST['password']);
$passwordConfirm = trim($_POST['passwordConfirm']);
if (stripos($username, ' '))
{
$this->alert = '<div class="notice"><p>Usernames cannot contain spaces.</p></div>';
}
else
{
foreach ($results as $r)
{
if ($usernameActual == $r['usernameActual'])
{
$this->alert = '<div class="notice"><p>Sorry. The username you entered is already registered with us.</p></div>';
// $return $this->alert;
}
if ($email == $r['email'])
{
$this->alert = '<div class="notice"><p>Sorry. The email you entered is already registered with us.</p></div>';
// $return $this->alert;
}
}
if (strlen($password) < 8 || strlen($password) > 20 || preg_match("/[0-9]/", $password) === 0 || preg_match("/[A-Z]/", $password) === 0)
{
$this->alert = '<div class="notice"><p>Passwords must meet the following criteria:</p><ul><li>Must be more than 8 characters.</li><li>Must be less than 20 characters.</li><li>Must contain at least 1 number.</li><li>Must contain at least 1 upper case letter.</li></ul></div>';
// $return $this->alert;
}
else
{
if ($password === $passwordConfirm)
{
$hashedPassword = password_hash($password, PASSWORD_BCRYPT, array('cost' => 10));
$insert = $this->con->db->prepare('INSERT INTO users (username, usernameActual, email, password) VALUES(?, ?, ?, ?)');
$insert->bind_param('ssss', $username, $usernameActual, $email, $hashedPassword);
if ($insert->execute())
{
echo 'inserted';
// $this->sendActivationEmail();
}
}
else
{
$this->alert = '<div class="notice"><p>The passwords you entered did not match.</p></div>';
// $return $this->alert;
}
}
}
}
$this->view('user-register', ['alert' => $this->alert]);
}
}
这是视图
<?php if (isset($data['alert'])) { echo $data['alert']; } ?>
<form action="/user/register" method="post">
<input type="text" name="username" placeholder="Username" required class="form-control">
<input type="email" name="email" placeholder="Email" required class="form-control">
<input type="password" name="password" placeholder="Password" required class="form-control">
<input type="password" name="passwordConfirm" placeholder="Confirm Your Password" required class="form-control">
<input type="submit" name="submit" value="Register" class="btn btn-primary pull-right">
</form>
如果有警报并仍然可以查看我的视图,如何停止插入用户的脚本?
答案 0 :(得分:1)
你可以抛出异常。异常导致代码停止执行并跳转到可以处理它们的第一个catch。它们必须包含在try {} catch(Exception $ e){}块中,但这些块可以在调用堆栈中的几个层中。重要的部分是throw停止执行该行,所以你插入将永远不会发生。
class User extends App
{
public $alert;
public function register()
{
if (isset($_POST['submit']))
{
try{
$username = trim($_POST['username']);
$usernameActual = strtoupper($username);
$email = trim($_POST['email']);
$password = trim($_POST['password']);
$passwordConfirm = trim($_POST['passwordConfirm']);
if (stripos($username, ' '))
{
//$this->alert = '<div class="notice"><p></p></div>';
throw new Exception("Usernames cannot contain spaces.");
}
else
{
foreach ($results as $r)
{
if ($usernameActual == $r['usernameActual'])
{
//$this->alert = '<div class="notice"><p>Sorry. The username you entered is already registered with us.</p></div>';
// $return $this->alert;
throw new Exception( "Sorry. The username you entered is already registered with us." );
}
if ($email == $r['email'])
{
// $this->alert = '<div class="notice"><p>Sorry. The email you entered is already registered with us.</p></div>';
// $return $this->alert;
throw new Exception("Sorry. The email you entered is already registered with us.");
}
}
if (strlen($password) < 8 || strlen($password) > 20 || preg_match("/[0-9]/", $password) === 0 || preg_match("/[A-Z]/", $password) === 0)
{
// $this->alert = '<div class="notice"><p>Passwords must meet the following criteria:</p><ul><li>Must be more than 8 characters.</li><li>Must be less than 20 characters.</li><li>Must contain at least 1 number.</li><li>Must contain at least 1 upper case letter.</li></ul></div>';
// $return $this->alert;
// NOTE: I don't recoment embedding html in your exception messages.
throw new Exception("Passwords must meet the following criteria:</p><ul><li>Must be more than 8 characters.</li><li>Must be less than 20 characters.</li><li>Must contain at least 1 number.</li><li>Must contain at least 1 upper case letter.</li></ul>");
}
else
{
if ($password === $passwordConfirm)
{
$hashedPassword = password_hash($password, PASSWORD_BCRYPT, array('cost' => 10));
$insert = $this->con->db->prepare('INSERT INTO users (username, usernameActual, email, password) VALUES(?, ?, ?, ?)');
$insert->bind_param('ssss', $username, $usernameActual, $email, $hashedPassword);
if ($insert->execute())
{
echo 'inserted';
// $this->sendActivationEmail();
}
}
else
{
// $this->alert = '<div class="notice"><p>The passwords you entered did not match.</p></div>';
// $return $this->alert;
throw new Exception( "The passwords you entered did not match." );
}
}
}
} catch (Exception $e ){
$this->alert = '<div class="notice"><p>' . $e->getMessage() .'</p></div>';
}
}
$this->view('user-register', ['alert' => $this->alert]);
}
}
这是我推荐的方法。验证将检查用户名是否有错误,如果发现则抛出异常。在validate方法中没有捕获异常,因此它会弹出validate方法并被register方法中的try-catch捕获。
class AlternateUser extends App
{
public $alert;
public function register()
{
if (isset($_POST['submit']))
{
try
{
$this->validate();
$username = trim($_POST['username']);
$usernameActual = strtoupper($username);
$email = trim($_POST['email']);
$password = trim($_POST['password']);
$passwordConfirm = trim($_POST['passwordConfirm']);
$hashedPassword = password_hash($password, PASSWORD_BCRYPT, array('cost' => 10));
$insert = $this->con->db->prepare('INSERT INTO users (username, usernameActual, email, password) VALUES(?, ?, ?, ?)');
$insert->bind_param('ssss', $username, $usernameActual, $email, $hashedPassword);
if ($insert->execute())
{
echo 'inserted';
// $this->sendActivationEmail();
}
} catch (Exception $e ){
$this->alert = '<div class="notice"><p>' . $e->getMessage() .'</p></div>';
}
}
$this->view('user-register', ['alert' => $this->alert]);
}
private function validate()
{
$username = trim($_POST['username']);
$usernameActual = strtoupper($username);
$email = trim($_POST['email']);
$password = trim($_POST['password']);
$passwordConfirm = trim($_POST['passwordConfirm']);
if (stripos($username, ' '))
{
//$this->alert = '<div class="notice"><p></p></div>';
throw new Exception("Usernames cannot contain spaces.");
}
foreach ($results as $r)
{
if ($usernameActual == $r['usernameActual'])
{
throw new Exception( "Sorry. The username you entered is already registered with us." );
}
if ($email == $r['email'])
{
throw new Exception("Sorry. The email you entered is already registered with us.");
}
}
if (strlen($password) < 8 || strlen($password) > 20 || preg_match("/[0-9]/", $password) === 0 || preg_match("/[A-Z]/", $password) === 0)
{
// NOTE: I don't recoment embedding html in your exception messages.
throw new Exception("Passwords must meet the following criteria:</p><ul><li>Must be more than 8 characters.</li><li>Must be less than 20 characters.</li><li>Must contain at least 1 number.</li><li>Must contain at least 1 upper case letter.</li></ul>");
}
if ($password !== $passwordConfirm) {
throw new Exception( "The passwords you entered did not match." );
}
}
}