重构如果地狱

时间:2013-12-25 21:02:27

标签: php if-statement login refactoring

TL; DR:我可以遵循什么策略来简化请求的if地狱?

我特指one of my github files。它可以处理不同的用户操作。我正在尝试重构它,但我不确定什么是最好的方法。代码的一小部分:

// The users returned from validating
if (!empty($_SESSION['service_connect']))
  {
  // If the service is a valid one
  if (in_array($_SESSION['service'], $UMConfig->services))
    {
    // Include the needed files.
    include $UMConfig->path . "/services/" . $_SESSION['service'] . "/verify.php";
    }
  }
// One service has set an email
if (isset($_SESSION['service_email']))
  {
  // The user is already in the database
  if (Validate::is_user($_SESSION['service_email']))
    {
    // User is logged in
    $_SESSION['email'] = $_SESSION['service_email'];
    include 'actions/login.php';
    }
  // The user is not in the database and didn't submit anythign
  elseif (empty($_POST))
    {
    // !POST
    $UMLog = "We are trying to register you with a service.";
    // Check if the popup has been submited or not
    include 'actions/service_verified.php';
    }
  // The user has submitted something with POST
  else {
    include 'actions/register_service.php';
    $UMLog = "Registering with " . $_SESSION['service'] . ".";
    }
  }

// No user was in the session but there's a user in the cookies
elseif (isset($_COOKIE['email']))
  {
  // The email is in the database
  if (Validate::is_user($_COOKIE['email']))
    {
    // If there's a token
    if (isset($_COOKIE['token']))

我现在的想法是将代码简化为更小的块并单独调用它们。这是我打算做的一般想法:

// Get what kind of action is needed
require 'request.php';
$action = request($_POST, $_SESSION, $_COOKIE);

if (file_exists($action_path = "actions/" . $action . ".php"))
  include $action_path;
else
  throw new Exception("Action was not valid: " . $action);

然而,这只是稍微简化了一下,因为我只是将地狱移动到'request.php'。它的优点是以这种方式测试更容易。

我已经阅读了多态如何简化某些if,但我不认为它可以在这种情况下应用。 我可以遵循哪些策略来简化此if地狱?

编辑:如果有人想知道,我有很多ifs,因为除了常规登录/注册,我允许用户使用外部服务登录/注册为facebook / google / etc,需要更多步骤并使其更加困难。

1 个答案:

答案 0 :(得分:0)

我决定遵循这一策略:一个函数request(),确定以最简单的形式提出哪种请求。只有以最简单的形式识别操作并返回此内容。

然后,调用它的脚本include.php包含来自包含所有操作的目录的操作。每个可调用操作都有许多方法可以验证它们是否有效。

<强> request.php:

<?php

// Find if there was any action to be done with the data provided
// Importance of requests: post > session > cookie (there're no get requests)

function request($Post, $Session, $Cookie)
  {
  // The user is trying to log out
  if ($Post->logout)
    {
    return "log_user_out";
    }

  // The user wants to edit the profile
  if ($Post->edit)
    {
    return "edit_user_data";
    }

  // Someone is trying to log in
  if ($Post->login)
    {
    return "log_user_in";
    }

  // Someone is trying to log in
  if ($Post->recover)
    {
    return "recover_password";
    }

  // Someone is trying to register
  if ($Post->register)
    {
    return "register_with_form";
    }

  // First time the user attempts to connect with a service
  // This should be vefore register_with_service in case someone clicked
  // a service but later wants to register with another service
  if ($Post->service_connect)
    {
    return "service_connect";
    }

  // Someone is trying to register with a service
  if ($Post->service && $Session->service_email)
    {
    return "register_with_service";
    }

  // The service returned green light
  if ($Session->service_connect)
    {
    return "verify_service";
    }

  // The user just landed here after confirming in the service
  if ($Session->service_email)
    {
    return "service_is_verified";
    }

  // There's already a user logged in. Simply retrieve the user
  if ($Session->email)
    {
    return "retrieve_user";
    }

  // There's apparently a user in the cookies
  if (isset($Cookie['email']))
    {
    return "login_with_cookie";
    }

  // If nothing from the above was submitted
  return null;
  }