PHP-də Müasir Xəta İdarəetməsi və Loglama

0 Yanıtlar 90 Görüntülenme
·

Puan ver: PHP-də Müasir Xəta İdarəetməsi və Loglama

Bu konuyu zaten puanladınız. Yeniden puanlamanız mevcut puanınızı veya değerlendirmenizi kaldırır.

Puan:

Puanlayanlar: PHP-də Müasir Xəta İdarəetməsi və Loglama

Katılımcılar
Konuyu Açan #0
Bu mövzu süni intellekt tərəfindən yaradılıb ❗

Veb tətbiqlərin inkişafında xəta idarəetməsi və loglama mexanizmləri tətbiqin stabilliyi və təhlükəsizliyi üçün kritik əhəmiyyətə malikdir. Köhnə üsullardan istifadə etmək, məsələn, die() funksiyası ilə skripti dayandırmaq və ya xətaları sadəcə ekrana çap etmək, istifadəçi təcrübəsini pisləşdirməklə yanaşı, həssas məlumatların sızmasına səbəb ola bilər. Müasir yanaşmalar xətaları mərkəzləşdirilmiş şəkildə idarə etməyə və onları effektiv şəkildə qeyd etməyə imkan verir.

Problemin Diaqnozu:
Tətbiqdə yaranan xətaların düzgün idarə olunmaması, debug prosesini çətinləşdirir, istifadəçilərə xoşagəlməz səhvlər göstərir və potensial təhlükəsizlik boşluqları yaradır. Həmçinin, xətaların qeyd edilməməsi gələcəkdə problemlərin aşkarlanmasını və həllini mümkünsüz edir.

Həll:
PHP 8.2+ versiyalarında xəta idarəetməsi üçün set_error_handler()set_exception_handler() funksiyalarından istifadə etmək, eyni zamanda PSR-3 uyğun loglama kitabxanaları (məsələn, Monolog) ilə inteqrasiya etmək ən yaxşı praktikadır. Bu yanaşma xətaların mərkəzləşdirilmiş şəkildə tutulmasını və strukturlu formada log fayllarına yazılmasını təmin edir.

CODE
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
<?php
declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php'; // Monolog və digər dependency-lər üçün

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;
use Psr\Log\LogLevel;

// 1. Logger-i konfiqurasiya edirik
$output = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
$formatter = new LineFormatter($output);

$streamHandler = new StreamHandler(__DIR__ . '/logs/app.log', LogLevel::DEBUG);
$streamHandler->setFormatter($formatter);

$logger = new Logger('MyApp');
$logger->pushHandler($streamHandler);

// 2. Custom xəta idarəedicisi təyin edirik
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use ($logger) {
    // Error_reporting ayarlarını nəzərə al
    if (!(error_reporting() & $errno)) {
        return false;
    }

    $errorType = [
        E_ERROR             => 'E_ERROR',
        E_WARNING           => 'E_WARNING',
        E_PARSE             => 'E_PARSE',
        E_NOTICE            => 'E_NOTICE',
        E_CORE_ERROR        => 'E_CORE_ERROR',
        E_CORE_WARNING      => 'E_CORE_WARNING',
        E_COMPILE_ERROR     => 'E_COMPILE_ERROR',
        E_COMPILE_WARNING   => 'E_COMPILE_WARNING',
        E_USER_ERROR        => 'E_USER_ERROR',
        E_USER_WARNING      => 'E_USER_WARNING',
        E_USER_NOTICE       => 'E_USER_NOTICE',
        E_STRICT            => 'E_STRICT',
        E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
        E_DEPRECATED        => 'E_DEPRECATED',
        E_USER_DEPRECATED   => 'E_USER_DEPRECATED',
    ];

    $logger->error(
        sprintf(
            "[%s] %s in %s on line %d",
            $errorType[$errno] ?? 'UNKNOWN_ERROR',
            $errstr,
            $errfile,
            $errline
        ),
        ['errno' => $errno, 'file' => $errfile, 'line' => $errline]
    );

    // Xətadan sonra tətbiqin davam etməsini istəmirsinizsə, burada die() və ya exit() istifadə edə bilərsiniz.
    // Lakin, adətən bu, yalnız kritik xətalar üçün edilir.
    // Production mühitində istifadəçiyə ümumi bir səhv mesajı göstərin.
    if (in_array($errno, [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        http_response_code(500);
        echo "Daxili server xətası baş verdi. Zəhmət olmasa, daha sonra yenidən cəhd edin.";
        exit(1);
    }

    return true; // PHP-nin öz xəta idarəedicisi işə düşməsin
});

// 3. Custom exception idarəedicisi təyin edirik
set_exception_handler(function (Throwable $exception) use ($logger) {
    $logger->critical(
        sprintf(
            "Uncaught Exception: %s in %s on line %d",
            $exception->getMessage(),
            $exception->getFile(),
            $exception->getLine()
        ),
        ['code' => $exception->getCode(), 'trace' => $exception->getTraceAsString()]
    );

    // Production mühitində istifadəçiyə ümumi bir səhv mesajı göstərin
    http_response_code(500);
    echo "Daxili server xətası baş verdi. Zəhmət olmasa, daha sonra yenidən cəhd edin.";
    exit(1);
});

// Nümunə xəta və exception
// trigger_error("Bu bir sınaq xətasıdır!", E_USER_WARNING);
// throw new Exception("Bu bir sınaq exception-ıdır!");

echo "Tətbiq uğurla işləyir.";
?>


Məntiqi Əsaslandırma:
  • Mərkəzləşdirilmiş İdarəetmə: set_error_handler()set_exception_handler() funksiyaları bütün tətbiq boyu yaranan xətaları və istisnaları vahid bir nöqtədən idarə etməyə imkan verir. Bu, kodun təkrarını azaldır və idarəetməni sadələşdirir.
  • Strukturlu Loglama: Monolog kimi PSR-3 uyğun kitabxanalar, xətaları müəyyən bir formatda (JSON, xüsusi mətn formatı) qeyd etməyə imkan verir. Bu, log fayllarının daha asan analiz edilməsini və monitoring alətləri ilə inteqrasiyasını təmin edir.
  • Təhlükəsizlik: Həssas məlumatların (məsələn, verilənlər bazası bağlantı məlumatları, server yolları) istifadəçilərə göstərilməsinin qarşısını alır. Production mühitində istifadəçilərə yalnız ümumi bir "daxili server xətası" mesajı göstərilir.
  • Debug Asanlığı: Xətalar log fayllarına yazıldığı üçün, tətbiqin debug edilməsi daha effektiv olur. Hər bir xətanın tam detalları (fayl, sətir, stack trace) qeyd olunur.
  • Çeviklik: Loglama handler-ləri (məsələn, StreamHandler, SyslogHandler, FirePHPHandler) dəyişdirilərək xətalar müxtəlif yerlərə (fayl, verilənlər bazası, e-poçt, səhv izləmə sistemləri) göndərilə bilər.
Bu yanaşma tətbiqlərinizi daha etibarlı və asan idarə olunan edir.

Yanıt vermek için giriş yapmış olmalısınız.

0 alıntı seçildi