导入的变量在函数中不可见


Imported variable not visible within function

我正在创建一个简单的注册脚本,该脚本具有检查用户名和电子邮件是否已被占用的功能。我导入php文件,该文件创建了到DB的mysqli连接,并将其保存到$mysqli变量中。现在的问题是,为什么我在函数中看不到$mysqli变量?我必须把它作为参数传递,这样我才能使用它

<?php
require_once "./incl/db.php";
require_once "./Logger.class.php";
$logger = new Logger("register.php.log");
function isTaken($username, $email, $mysqli){
  $ret = 0;
  if($stmt = $mysqli->prepare("SELECT email,nick FROM users WHERE email = ? OR nick = ? LIMIT 1")){
    $stmt->bind_param("ss", $email, $username);
    if($stmt->execute()){
      $stmt->store_result();
      if($stmt->num_rows === 0){
        $stmt->free_result();
        return $ret;
      }else{
        $stmt->bind_result($dbEmail, $dbNick);
         while($stmt->fetch()){
          if(strcmp(strtolower($dbEmail), strtolower($email)) == 0)
            $ret+= 1;
          if(strcmp(strtolower($dbNick), strtolower($username)) == 0)
            $ret+= 2;
          return $ret;
         }
      }
    }else{
      $logger->logError("Error executing stmt(isTaken)! ".$mysqli->error.$logger->newLine.$stmt->error);
      die("stmt error");
    }
  }else{
    $logger->logError("Error preparing stmt(isTaken)! ".$mysqli->error.$logger->newLine.$stmt->error);
    die("Error preparing stmt!");
  }
}
session_start();
ob_start();
header ('HTTP/1.1 302 Found');
if(isset($_POST["registrovat"]) && !empty($_POST["mail"])
  && !empty($_POST["password"]) && !empty($_POST["username"])){
    $email = trim($_POST["mail"]);
    $username = trim($_POST["username"]);
    $password = trim($_POST["password"]);
    for($i = 0; $i < 10; $i++){
      $password = hash("sha256", $password);
    }
    if(filter_var($email, FILTER_VALIDATE_EMAIL)){
      //echo "E-mail valid";
      $isTaken = isTaken($username, $email, $mysqli);
      if($isTaken === 0){
        if($stmt = $mysqli->prepare("INSERT INTO users (id, nick, password, email, rights) VALUES(NULL, ?, ?, ?, 0)")){
          if($stmt->bind_param("sss", $username, $password, $email)){
            if($stmt->execute()){
              $id = $stmt->insert_id;
              header('Location: http://'.$_SERVER["SERVER_NAME"].'/profil/'.$id);
            }else{
              $logger->logError("Error executing stmt! ".$mysqli->error.$logger->newLine.$stmt->error);
              die("Error executing stmt");
            }
          }else{
            $logger->logError("Error binding params(reg): ".$mysqli->error.$logger->newLine.$stmt->error);
            die("error");
          }
          $stmt->close();
        }else{
          $logger->logError("Error preparing stmt(reg)! ".$mysqli->error.$logger->newLine.$stmt->error);
          die("error stmt!");
        }
      }else{
        $text;
        switch($isTaken){
          case 1: $text = "E-mail already exists"; break;   
          case 2: $text = "Username already exists"; break;         
          case 3: $text = "E-mail and username already exists"; break;
          default: $text = "default"; break;
        }
        die($text);
      }
    }else{
      $logger->logError("E-mail not valid: ".$email);
      $logger->logInfo(var_export($_POST, true));
      die("E-mail not valid");
    }
}else{
  $logger->logError("Fields empty.");
  $logger->logInfo(var_export($_POST, true));
  die("Fields empty!");
}
ob_end_flush();
?>

如果要访问全局变量而不将其作为参数传递,则必须使用global声明:

function isTaken($username, $email){
    global $mysqli;

因为除非导入它或将其声明为全局,否则它不在函数的范围内。

每个函数都是一个封装的代码块,它只知道自己,除非您将变量插入函数或声明,否则您只能看到函数中设置的变量或$_POST等超级全局变量

global $mysqli;

在函数内部,告诉它使用外部的变量

变量不在函数的范围内。你可以这样做,也可以像Barmar所说的那样将其作为一个全局变量:

function isTaken($username, $email){
    require_once "./incl/db.php";
    ...
}