Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > class Exception


Автор: Logree 15.6.2008, 17:01
есть такой класс
(я честно говоря не знаю содержаться ли ошибки из mysqli_connect_error() в mysqli_error()  написал так)

myException
Код

   class MySqliException extends Exception {
    
    protected $conect_error;
    protected $conect_errno;
    
    public function _constrct($message = FALSE,$code = FALSE) 
    {
        if(!$message) {            
            $this->message = mysqli_error();
            $this->conect_error = mysqli_connect_error();
        }
        if(!$code) {
            $this->code = mysqli_errno();
            $this->conect_errno = mysqli_connect_errno();
        }
    }
    
    public function getConnect_Error() 
    {
        return $this->conect_error;
    }
    public function getConnect_Errno() 
    {
        return $this->conect_errno;
    }
  }


далее делаем ошибку(неверный пароль)
Код

    try {
    $db = new mysqli('127.0.0.1','root','pass');
    
} catch (MySqliException $e) {
    echo $e->getConnect_Error().'<br>'.$e->getCode();
}

вылезло
Код

Warning: mysqli::mysqli() [mysqli.mysqli]: (28000/1045): Access denied for user 'root'@'localhost' (using password: YES) in C:\www\index.php on line 47


Почему? Может я не до конца понимаю как это должно работать? Объяснения.

Автор: Feldmarschall 15.6.2008, 17:27
А чего ты ждал?

Автор: Logree 15.6.2008, 17:44
Я ждал что появится Строка ошибки и её код

(Эта строка появляется в любом случае)

при отключенных display_errors не показывает ничего!

но ведь произошла исключительная ситуация значит код ошибки должен быть в классе Exception. почему не так так?

Автор: krundetz 15.6.2008, 19:12
В исключениях не передается никакого кода ошибке обычно на каждую ошибку создается свой класс исключение, тоесть само возникновение именно такой исключительной ситуации и являеется указанием на ошибку. Обычно в более развитых языках делается так.
Код

try
{
//некий блок кода
}
catch(Одно исключени){}
catch(Другое исключение){}
...
catch(Исключение общее для всех){}

Рекомендую прочитать про исключения поподробнее.
Насколько я в курсе mysqli как раз удостаивался коритики за то что там одно исключение на все случае.
Да возможно вам поможет метод toString()

Автор: Glip 15.6.2008, 20:19
Цитата(Logree @  15.6.2008,  17:44 Найти цитируемый пост)
значит код ошибки должен быть в классе Exception

а почему он там должен быть? откуда система знает что нужно генерировать именно MySqliException и если на то пошло Exception вообще.

Хотите вместо ошибок исключения? Определяйте свой обработчик ошибок set_error_handler()

Добавлено через 1 минуту и 14 секунд
Цитата(krundetz @  15.6.2008,  19:12 Найти цитируемый пост)
Обычно в более развитых языках делается так

в php тоже так делается

Автор: Logree 15.6.2008, 20:53
Что-то я совсем запутался, я думал что конструкция
Код

try {

} catch (Exception $e) {

}

при наличие ошибки в блоке try помещает все её(ошибки) составляющие в объект Exception: строку, код, файл, line а далле выполняется блок catch... но если это не так зачем тогда нужно исключение если можно пример.

а чем это отличается от 
Код

if () {
 throw new Exception;
}


?

Цитата

а почему он там должен быть? откуда система знает что нужно генерировать именно MySqliException и если на то пошло Exception вообще.

ну так как Exception встроенно, а MySqliException я includ'ил,

из php.net

Код

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Деление на ноль.');
    }
    else return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Выброшено исключение: ',  $e->getMessage(), "\n";
}

// Продолжение выполнения
echo 'Hello World';
?> 

Результат выполнения данного примера:
0.2
Выброшено исключение: Деление на ноль.
Hello World

Тут же тоже самое что и у меня... или я снова  не понял чего то?

Автор: DizelGenerator 15.6.2008, 21:00
Добрый вечер!

Библиотека Mysqli не генерирует исключений, нет. Сама она их не генерирует, поэтому и поймать их в блоке catch не удастся. Выход видится неплохой: расширяете класс mysqli и "вбрасываете" исключения там, где вам необходимо, а потом уже их ловите например:
Код

class myCoolMysqli extends mysqli {
    
    public function __construct(
        $host = '',
        $username = '',
        $password = '',
        $schema = '',
        $port = '',
        $socket = ''
    ) {
        
        $conn = parent::__construct(
            $host,
            $username,
            $password,
            $schema,
            $port,
            $socket
        );
        
        if (mysqli_connect_error()) {
            
            throw new myCoolMysqliException(
                mysqli_connect_error(), mysqli_connect_errno()
            );
            
        }
        
        return $conn;
        
    }
}


Соответственно, вам придется определить и класс myCoolMysqliException, хотя бы таким нехитрым образом:
Код

class myCoolMysqliException extends Exception {}


Вуаля, ловите исключения при коннекте сколько хотите.

Автор: krundetz 15.6.2008, 21:06
В конструкцию try обычно помещаются действительно код который может вызвать исключения только эти исключения могут быть разных видов и для их обработки необходимо множество catch. В блоке где возможна исключительная ситуация не помешается информация в исключение а создается новое исключение и выкидывается конструкцией throw на верх где может быть обработана. Делается это для того чтобы была возможность все ощибки обработать на наиболее удобном для этого уровне программы(во всяком случае это для меня наиболее ценный аргумент в пользу исключений). В общем опять советую почитать теоретическую часть и посмотреть примеры работы с исключениями.

Автор: Logree 15.6.2008, 21:11
2DizelGenerator

Тоесть "ловля" не получается только для mysqli, значит если я напишу вот так

Код

try {
$f  = fopen('$@#$','r');
} catch(FileException $e) {
    echo $e->getCode();
}

все будет нормально?

интересный пример... ноя думаю для mysqli проще будет обойтись ИФОМ и mysqli_connect_error/no

Автор: DizelGenerator 15.6.2008, 21:22
Цитата(Logree @ 15.6.2008,  21:11)
Тоесть "ловля" не получается только для mysqli, значит если я напишу вот так

Если как вы написали - снова ничего не поймаете, потому что fopen исключений тоже не генерирует, а генерирует ошибку типа Warning. Понимаете, если исключение не "вбросилось", его невозможно поймать. Практически все стандартные функции php исключений не бросают. Поэтому бросать их надо самому. Напишите так (продолжая наш пример с мускули):

Код

try {

  $db = new myCoolMysqli('localhost', 'root', '12345');

} catch(MyCoolMysqliException $e) {

    echo 'Исключение драйвера базы данных: ', $e->getCode();

} catch (Exception $e) {

  echo 'Исключение ', $e;

}


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

Автор: Logree 15.6.2008, 21:34
ВСЁ наконец дошло спасибо всем. особенно DizelGenerator - разжевал.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)