【问题标题】:Passing MySQLi object to function将 MySQLi 对象传递给函数
【发布时间】:2017-05-20 21:22:27
【问题描述】:

所以我正在为我正在开发的网络应用程序制作登录系统。我有一个register.php 文件,它不是一个类。我有一个AccountInterface.php 文件,它是一个类。

注册.php

<?php
session_start();
if(isset($_SESSION["loggedin"]))
{
    header("http://ezblog.guru");
    return;
}
require_once("../api/AccountInterface.php");
require_once("../api/Utils.php");
use Massively\api\AccountInterface;
$accountAPI = new AccountInterface();
$creds = parse_ini_file("../../config/mysql.ini");
$conn = new mysqli($creds["ip"], $creds["username"], $creds["password"], $creds["db"]);
var_dump($conn);
if($conn->connect_error)
{
    echo "MySQLi connect error:" . $conn->connect_error;
} else
{
    $username = $_POST["username"];
    $email = $_POST["email"];
    $password = $_POST["password"];
    if(filter_var($email, FILTER_VALIDATE_EMAIL) === $email)
    {
      if(!filter_var($username, FILTER_VALIDATE_EMAIL))
      {
        if(!$accountAPI->checkAccount($username, $conn))
        {
            if(!$accountAPI->accountExists($username, $email, $conn))
            {
                $ip = $_SERVER['REMOTE_ADDR']?:($_SERVER['HTTP_X_FORWARDED_FOR']?:$_SERVER['HTTP_CLIENT_IP']);
                $salt = Massively\api\Utils::random_str(40);
                $pin = rand(10000, 99999);
                $accountAPI->registerAccount($username, $email, hash_pbkdf2("sha512", $password, $salt, 27000), $ip, $salt, $pin, $conn);

                $msg = "$username,\nThank you for registering an account with E-Z Blog. Before you get started writing blogs using our beautiful web application, please confirm your e-mail by visiting ezblog.guru/confirm.\nYour pin code is $pin\n/E-Z Blog";
                $msg = wordwrap($msg);
                $headers = "From: ezblog@gmail.com <E-Z Blog>";

                //mail($email, "EZ-Blog - confirmation", $msg, $headers);
                return;
            } else
            {
                echo "This Email address is already taken";
                return;
            }
        } else
        {
            echo "This username is already taken";
            return;
        }
      } else
      {
        echo "Please make sure your username is not an e-mail address";
        return;
      }
    } else
    {
        echo "Please enter a valid Email address";
        return;
    }
}
?>

AccountInterface.php

<?php
namespace Massively\api;
class AccountInterface
{
  public function checkAccount($user, $conn)
  {
    if($conn instanceof mysqli)
    {
      $stmt = $conn->prepare("SELECT id FROM accounts WHERE username=?;");
      $stmt->bind_param("s", $user);
      $stmt->execute();
      $stmt->store_result();
      if($stmt->num_rows === 0)
      {
        $stmt->close();

        return false;
      } else
      {
        $stmt->close();

        return true;
      }
    } else
    {
      return "!instanceof mysqli";
    }
  }

  public function accountExists($user, $email, $conn)
  {
    if($conn instanceof mysqli)
    {
      $stmt = $conn->prepare("SELECT id FROM accounts WHERE username=?;");
      $stmt->bind_param("s", $user);
      $stmt->execute();
      $stmt->store_result();
      if($stmt->num_rows !== 0)
      {
        $foo = "!user";
      } else
      {
        $stmt->free_result();
        $stmt->close();

        $stmt = $conn->prepare("SELECT id FROM accounts WHERE email=?;");
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $stmt->store_result();
        if($stmt->num_rows !== 0)
        {
          $foo = "!email";
        } else
        {
          $foo = false;
        }
      }
      $stmt->free_result();
      $stmt->close();

      return $foo;
    } else
    {
      return "!instanceof mysqli";
    }
  }

  public function getUser($email, $conn)
  {
    if($conn instanceof mysqli)
    {
      $stmt = $conn->prepare("SELECT username FROM accounts WHERE email=?;");
      $stmt->bind_param("s", $email);
      $stmt->execute();
      $stmt->store_result();
      if($stmt->num_rows === 0)
      {
        $stmt->free_result();
        $stmt->close();

        return false;
      } else
      {
        $stmt->bind_result($user);
        while($stmt->fetch())
        {
          $foo = $user;
        }
        $stmt->free_result();
        $stmt->close();

        return $foo;
      }
    } else
    {
      return "!instanceof mysqli";
    }
  }

  public function registerAccount($user, $email, $password, $ip, $salt, $pin, $conn)
  {
    if($conn instanceof mysqli)
    {
      if(!$this->accountExists($user, $email, $conn))
      {
        $stmt = $conn->prepare("INSERT INTO accounts (username, email, password, ip, salt, pin, verified) VALUES (?, ?, ?, ?, ?, ?, ?);");
        $stmt->bind_param("sssssii", $user, $email, $password, $ip, $salt, $pin, 0);
        $stmt->execute();
        $stmt->close();

        return true;
      } else
      {
        return false;
      }
    } else
    {
      return "!instanceof mysqli";
    }
  }

  public function unregisterAccount($user, $conn)
  {
    if($conn instanceof mysqli)
    {
      if($this->checkAccount($user, $conn))
      {
        $stmt = $conn->prepare("DELETE FROM accounts WHERE username=?;");
        $stmt->bind_param("s", $user);
        $stmt->execute();
        $stmt->close();

        return true;
      } else
      {
        return false;
      }
    } else
    {
      return "!instanceof mysqli";
    }
  }

    public function getPin($user, $conn)
  {
    if($conn instanceof mysqli)
    {
        if($this->checkAccount($user, $conn))
        {
          $stmt = $conn->prepare("SELECT pin FROM accounts WHERE username=?;");
          $stmt->bind_param("s", $user);
          $stmt->execute();
          $stmt->store_result();
          $stmt->bind_result($pin);
          while($stmt->fetch())
          {
            $foo = $pin;
          }
        $stmt->free_result();
        $stmt->close();

        return $pin;
        } else
        {
          return false;
        }
    } else
    {
      return "!instanceof mysqli";
    }
  }

    public function login($user, $password, $conn)
  {
    if($conn instanceof mysqli)
    {
      if($this->checkAccount($user, $conn))
      {
        $stmt = $conn->prepare("SELECT id FROM accounts WHERE username=? AND password=?;");
        $stmt->bind_param("ss", $user, $password);
        $stmt->execute();
        $stmt->store_result();
        if($stmt->num_rows === 0)
        {
          $foo = "allowed";
        } else
        {
          $foo = "!allowed";
        }
        $stmt->free_result();
        $stmt->close();

        return $foo;
      } else
      {
        return false;
      }
    } else
    {
      return "!instanceof mysqli";
    }
  }

    public function getSalt($user, $conn)
  {
    if($conn instanceof mysqli)
    {
      if($this->checkAccount($user, $conn))
      {
        $stmt = $conn->prepare("SELECT salt FROM accounts WHERE username=?;");
        $stmt->bind_param("s", $user);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($salt);
        while($stmt->fetch())
        {
          $foo = $salt;
        }
        $stmt->free_result();
        $stmt->close();

        return $foo;
      } else
      {
        return false;
      }
    } else
    {
      return "!instanceof mysqli";
    }
  }

  public function setVerified($user, $conn)
  {
    if($conn instanceof mysqli)
    {
      if($this->checkAccount($user, $conn))
      {
        $stmt = $conn->prepare("UPDATE accounts SET verified=? WHERE username=?;");
        $stmt->bind_param("is", 1, $user);
        $stmt->execute();
        $stmt->close();

        return true;
      } else
      {
        return false;
      }
    } else
    {
      return "!instanceof mysqli";
    }
  }

    public function getVerified($user, $conn)
  {
    if($conn instanceof mysqli)
    {
      if($this->checkAccount($user, $conn))
      {
        $stmt = $conn->prepare("SELECT verified FROM accounts WHERE username=?");
        $stmt->bind_param("s", $user);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($verified);
        while($stmt->fetch())
        {
          $foo = $verified;
        }
        $stmt->free_result();
        $stmt->close();

        return $foo;
      } else
      {
        return false;
      }
    } else
    {
      return "!instanceof mysqli";
    }
  }

  public function getUserObject($user, $conn)
  {
    if($conn instanceof mysqli)
    {
      if($this->checkAccount($user, $conn))
      {
        $stmt = $conn->prepare("SELECT id, email, ip FROM accounts WHERE username=?;");
        $stmt->bind_param("s", $user);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($id, $email, $ip);
        while($stmt->fetch())
        {
          $foo = new Account($id, $user, $email, $ip);
        }
        $stmt->free_result();
        $stmt->close();

        return $foo;
      } else
      {
        return false;
      }
    } else
    {
      return "!instanceof mysqli";
    }
  }
}
?>

我用 PHP 调用的所有函数都返回“!instanceof mysqli”,即使我删除了if($conn instanceof mysqli){},db 也没有任何反应。但是,如果我在register.php 的任何位置添加var_dump($conn),我就会知道它是mysqli 对象。我假设$conn 没有正确传递给AccountInterface 函数?我该怎么做才能解决这个问题?

编辑:

我知道$accountAPI-&gt;checkAccount($username, $conn) 返回"!instanceof mysqli",因为我添加了if($accountAPI-&gt;checkAccount($username, $conn) === "!instanceof mysqli"){ echo "not an instance of mysqli"; },它输出了not an instance of mysqli。我没有在这里展示这个,因为我想展示我的原始代码。

编辑 2:

在使用checkAccount 函数后,我添加了一个var_dump($stmt),结果$stmt 是mysqli_stmt 的一个实例,但仍然没有对数据库做任何事情。

【问题讨论】:

  • 这可能不是唯一的问题,但它是一个开始。与其返回"!instanceof mysqli,不如返回false,看看行为如何变化。因为即使传递了无效的非 mysqli 对象,您也以 if(!$accountAPI-&gt;checkAccount($username, $conn)) 执行它,所以您返回的 string 错误消息将是一个真值。这听起来不像你描述的那个错误,但它本身绝对不正确......
  • 要调试为什么数据库中没有任何变化,您应该检查 MySQLi 对象上的错误。 if (!$stmt) { echo $conn-&gt;error; } 我在发布的代码中看不到它,但 $conn 可能在某个时候被覆盖或关闭。如果是这种情况,那将是 null 并且无法通过您的检查。
  • 将class 命名为AccountInterface 有点误导。我必须仔细阅读才能明白它确实是class 和not an interface
  • @MichaelBerkowski 我添加了一个if($accountAPI-&gt;checkAccount($username, $conn) === "!instanceof mysqli"{},括号内的代码运行了。我将其从中删除以显示我的初始代码。不过,我会编辑帖子以包含它。
  • 你正在使用命名空间,所以试试$conn instanceof \mysqli。

标签: php oop mysqli


【解决方案1】:

您可以通过实际应用依赖注入来解决它。你的代码看起来像这样:

namespace Massively\api;
use MySQLi;

class Authentication
{
    private $connection;

    public function __construct(MySQLi $connection) 
    {
        $this->connection = $connection;
    }


    public function checkAccount($user)
    {
        $sql = 'SELECT id FROM accounts WHERE username=?';
        $stmt = $this->connection->prepare($sql);
        // ... etc.

在您的register.php 中,它看起来像:

$conn = new \MySQLi($creds["ip"], $creds["username"], $creds["password"], $creds["db"]);
$accountAPI = new \Massively\api\Authentication($conn);
// some unimportant code here

if(!$accountAPI->checkAccount($username)) {
    if(!$accountAPI->accountExists($username, $email))
    {
        // more code here
    }
}

而且你真的需要为事物命名。

【讨论】:

  • 是的,我还在学习所有的命名约定和事物之间的细微差别
  • 你可以试试看这个讲座:youtube.com/watch?v=KHBrDWIKW8Q ...这可能会有所帮助。
猜你喜欢
  • 1970-01-01
  • 2015-08-30
  • 2011-12-07
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-22
相关资源
最近更新 更多