Ожидаемое сообщение исключения, не отображаемое в PHP

Я хочу написать программу с подключением базы данных и обработкой исключений в PHP. Если я ввешу неправильное имя пользователя, тогда оно должно отобразить соответствующее сообщение об ошибке, и если я вставлю неправильную базу данных, он должен отобразить соответствующее сообщение об ошибке.

Но в следующей программе, вставляю ли я неверную базу данных или неправильное имя пользователя, отображается только сообщение "Не удалось подключиться к базе данных".

<?php
   $hostname = "localhost";
   $username = "root1";
   $password = "";
   $database = "php_thenewboston";
   $conn = mysqli_connect($hostname,$username,$password);
   $conn_db = mysqli_select_db($conn,$database);
   class ServerException extends Exception{}  
   class DatabaseException extends Exception{}
   try{
       if(!$conn){
           throw new ServerException('Could not connect to server.');
       }elseif(!$conn_db){
           throw new DatabaseException('Could not connect to database.');
       }else{
           echo "Connected.";
       }
   }catch(ServerException $ex){
       echo "Error :".$ex->getMessage();        
   }catch(DatabaseException $ex){
       echo "Error :".$ex->getMessage();
   }
?>

Я новичок в PHP. Пожалуйста, прокомментируйте ниже для любого запроса.

ИЗМЕНИТЬ

Как просили @Hatef Ниже var_dump $conn, когда имя пользователя неверно, пароль правильный и имя базы данных правильно

object(mysqli)#1 (19) {
  ["affected_rows"]=>
  int(-1)
  ["client_info"]=>
  string(79) "mysqlnd 5.0.12-dev - 20150407 - $Id: 241ae00989d1995ffcbbf63d579943635faf9972 $"
  ["client_version"]=>
  int(50012)
  ["connect_errno"]=>
  int(0)
  ["connect_error"]=>
  NULL
  ["errno"]=>
  int(1044)
  ["error"]=>
  string(68) "Access denied for user ''@'localhost' to database 'php_thenewboston'"
  ["error_list"]=>
  array(1) {
    [0]=>
    array(3) {
      ["errno"]=>
      int(1044)
      ["sqlstate"]=>
      string(5) "42000"
      ["error"]=>
      string(68) "Access denied for user ''@'localhost' to database 'php_thenewboston'"
    }
  }
  ["field_count"]=>
  int(0)
  ["host_info"]=>
  string(20) "localhost via TCP/IP"
  ["info"]=>
  NULL
  ["insert_id"]=>
  int(0)
  ["server_info"]=>
  string(21) "5.5.5-10.1.16-MariaDB"
  ["server_version"]=>
  int(50505)
  ["stat"]=>
  string(132) "Uptime: 1072  Threads: 1  Questions: 16  Slow queries: 0  Opens: 18  Flush tables: 1  Open tables: 11  Queries per second avg: 0.014"
  ["sqlstate"]=>
  string(5) "00000"
  ["protocol_version"]=>
  int(10)
  ["thread_id"]=>
  int(9)
  ["warning_count"]=>
  int(0)
}

Ниже приведен параметр var_dump $conn, когда имя пользователя верное, пароль правильный и имя базы данных неверно.

object(mysqli)#1 (19) {
  ["affected_rows"]=>
  int(-1)
  ["client_info"]=>
  string(79) "mysqlnd 5.0.12-dev - 20150407 - $Id: 241ae00989d1995ffcbbf63d579943635faf9972 $"
  ["client_version"]=>
  int(50012)
  ["connect_errno"]=>
  int(0)
  ["connect_error"]=>
  NULL
  ["errno"]=>
  int(1049)
  ["error"]=>
  string(36) "Unknown database 'php_thenewboston1'"
  ["error_list"]=>
  array(1) {
    [0]=>
    array(3) {
      ["errno"]=>
      int(1049)
      ["sqlstate"]=>
      string(5) "42000"
      ["error"]=>
      string(36) "Unknown database 'php_thenewboston1'"
    }
  }
  ["field_count"]=>
  int(0)
  ["host_info"]=>
  string(20) "localhost via TCP/IP"
  ["info"]=>
  NULL
  ["insert_id"]=>
  int(0)
  ["server_info"]=>
  string(21) "5.5.5-10.1.16-MariaDB"
  ["server_version"]=>
  int(50505)
  ["stat"]=>
  string(132) "Uptime: 1417  Threads: 1  Questions: 18  Slow queries: 0  Opens: 18  Flush tables: 1  Open tables: 11  Queries per second avg: 0.012"
  ["sqlstate"]=>
  string(5) "00000"
  ["protocol_version"]=>
  int(10)
  ["thread_id"]=>
  int(10)
  ["warning_count"]=>
  int(0)
}

Ответы

Ответ 1

По умолчанию mysql автоматически выдает исключение. Чтобы выбросить исключение вручную, вам нужно написать следующую строку вверху файла Это вызовет исключение даже в mysqli_connect. Поэтому вам нужно добавить метод connect в блок try. mysqli_report(MYSQLI_REPORT_STRICT);

UPDATE: в вашем случае не пишите вышеприведенную строку, меняйте имя хоста, и вы получите ошибку сервера в вашем блоке catch.

Ответ 2

В соответствии с вашим кодом вы играете хорошего программиста oops. Ну, каждый язык программирования имеет свой собственный набор правил и стандартов.

Давайте рассмотрим ваш код

   $conn = mysqli_connect($hostname,$username,$password);
   $conn_db = mysqli_select_db($conn,$database);
   class ServerException extends Exception{}  
   class DatabaseException extends Exception{}

Здесь вы пытаетесь инициировать соединение. Затем в блоке try catch вы проверяете возможность подключения.

Поместите ваше соединение также в блок try catch и поймайте исключение.

Например:

try
{
    if ($db = mysqli_connect($hostname_db, $username_db, $password_db))
    {
        //do something
    }
    else
    {
        throw new Exception('Unable to connect');
    }
}
catch(Exception $e)
{
    echo $e->getMessage();
}

Ответ 3

Используя mysqli_connect, вы сможете передать имя базы данных внутри этой же функции, поэтому для цели подключения вам не нужно ждать mysqli_select_db()

Существует много кода ошибки, который вы получите после попытки подключения, и на основе этого вы сможете указать правильное сообщение.

Я обновил ваш код и условия, чтобы вы поняли

<?php
       $hostname = "localhost";
       $username = "root1";
       $password = "";
       $database = "php_thenewboston";
       $conn = mysqli_connect($hostname,$username,$password,$database);
       $error = mysqli_connect_errno();
       //$conn_db = mysqli_select_db($conn,$database);
       class ServerException extends Exception{}  
       class DatabaseException extends Exception{}
       try{
           if($error == 1044){
               throw new ServerException('Could not connect to server. Check Username');
           }elseif($error == 1045){
               throw new DatabaseException('Could not connect to server. Check Password');
            }elseif($error == 1049){
               throw new DatabaseException('Could not connect to database. Check Database Name');
           }else{
               echo "Connected.";
           }
       }catch(ServerException $ex){
           echo "Error :".$ex->getMessage();        
       }catch(DatabaseException $ex){
           echo "Error :".$ex->getMessage();
       }
?>

Надеюсь, это поможет вам.

Ответ 4

Использовать инструкции PDO. В нижнем примере вы узнаете, какая ошибка возникает при использовании настройки try/catch.

Подключить PDO с кодом ниже:

$mysqli_pdo = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS, array(
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    ));

Затем сверните свой SQL в настройке try/catch, как показано ниже:

try {
    //$mysqli_pdo->beginTransaction(); If you need transaction
    $sql = $mysqli_pdo->prepare("[YOUR SQL]");
    $sql->bindValue(1, $INT_VAL, PDO::PARAM_INT);
    $sql->bindValue(2, $STR_VAL, PDO::PARAM_STR);
    $sql->execute();
    //$mysqli_pdo->commit(); Don't forget if you use transaction
    }
catch(Exception $e) {
    echo $e->getMessage();
    //$mysqli_pdo->rollBack(); Don't forget if you use transaction
    exit();
    }

Ответ 5

Попробуйте использовать следующее для подключения.

<?php
$mysqli = new mysqli("localhost", "root", "", "php_thenewboston");


try{ 
      if(!$mysqli){
           throw new ServerException('Could not connect to server.');
       }else{
           echo "Connected.";
       }
   }catch(ServerException $ex){
       echo "Error :".$ex->getMessage();        
   }catch(DatabaseException $ex){
       echo "Error :".$ex->getMessage();
   }
?>

Ответ 6

Расширение MySQLi предоставляет информацию об ошибках.

Если $conn == false, вызовите mysqli_connect_error() после получения сообщения об ошибке.

Если вы хотите использовать свое собственное сообщение, mysqli_connect_errno() вернет код ошибки, который вы можете использовать для его обработки, как вы хотите.

Из документов PHP: http://php.net/manual/en/mysqli.errno.php

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

if (!mysqli_query($link, "SET a=1")) {
    printf("Errorcode: %d\n", mysqli_errno($link));
}

/* close connection */
mysqli_close($link);
?>