Как найти причину сбоя mkdir из PHP?

Функция PHP mkdir возвращает только true и false. Проблема в том, что он возвращает false.

Если я работаю с включенными отчетами об ошибках, я вижу сообщение об ошибке на экране. Я также вижу сообщение об ошибке в журнале Apache. Но я хотел бы получить текст сообщения и сделать с ним что-то еще (например, отправить себе через IM). Как получить текст ошибки?

Обновление: Следуя идее Аймана, я пришел к следующему:

function error_handler($errno, $errstr) {
    global $last_error;
    $last_error = $errstr;
}

set_error_handler('error_handler');
if (!mkdir('/somedir'))
    echo "MKDIR failed, reason: $last_error\n";
restore_error_handler();

Однако мне это не нравится, потому что в нем используется глобальная переменная. Любая идея для более чистого решения?


person Milan Babuškov    schedule 29.05.2009    source источник
comment
Ответ Soulmerge — лучший выбор, потому что он сообщает вам об ошибке, не заменяя обработчик.   -  person Robert K    schedule 30.05.2009
comment
Обратите внимание, что обработчики ошибок в PHP хранятся в стеке, а это означает, что вызов restore_error_handler() восстановит предыдущий обработчик ошибок, будь то встроенный обработчик или другой пользовательский обработчик. Таким образом, временная замена обработчика ошибок на set_error_handler() не принесет никаких потерь.   -  person soulmerge    schedule 30.05.2009


Ответы (3)


Вы можете подавить предупреждение и использовать error_get_last():

if (!@mkdir($dir)) {
    $error = error_get_last();
    echo $error['message'];
}
person soulmerge    schedule 30.05.2009
comment
+1, но стоит отметить, что это потенциально хрупко, если между mkdir() и error_get_last() возникает другая ошибка, которая вполне может произойти, когда ваш код становится более сложным (в качестве крайнего, нереалистичного примера, функция тика может запускаться и генерировать ошибка перед вызовом error_get_last()). Это всегда риск каждый раз, когда вы используете какую-либо функцию получения последней ошибки. - person Frank Farmer; 08.01.2010

Вы можете использовать исключения:

Настройте код следующим образом:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

А затем просто выполните:

try {
   mkdir('/somedir');
} catch(ErrorException $ex) {
   echo "Error: " . $ex->getMessage();
}

Это должно делать то, что вы хотите.

Если вы хотите сохранить обработчик ошибок php, то после этого блока try catch просто вызовите:

restore_error_handler()
person Alistair Evans    schedule 30.05.2009
comment
+1 Мне нравится этот подход, я его не проверял, но он кажется надежным. Также это выглядит более дружелюбно к оо ;) - person Daniel Wedlund; 30.05.2009
comment
Кроме того, объектно-ориентированные библиотеки PHP гораздо лучше справляются со всем этим php.net/manual/ ru/class.splfileobject.php - person nick fox; 25.03.2013
comment
@nickfox mkdir не выдает исключение, поэтому специальный обработчик ошибок выдает исключение. Что касается объектно-ориентированных библиотек PHP, да, они, вероятно, делают это лучше. - person Alistair Evans; 25.03.2013
comment
Это правильный ответ, так как он также показывает правильный номер строки в трассировке стека. - person Justin; 15.05.2019

Я использую что-то вроде следующего:

if(! @mkdir('$fileLocation', 0777, $recursive = true)){
    $mkdirErrorArray = error_get_last();
    throw new Exception('cant create directory ' .$mkdirErrorArray['message'], 1);
}
person nick fox    schedule 24.03.2013