আমি কি কোনও সতর্কতা চেষ্টা করতে / ধরতে পারি?


357

কিছু পিএইচপি নেটিভ ফাংশন থেকে নিক্ষেপ করা কিছু সতর্কতা আমাকে ধরতে হবে এবং তারপরে সেগুলি পরিচালনা করতে হবে।

বিশেষ করে:

array dns_get_record  ( string $hostname  [, int $type= DNS_ANY  [, array &$authns  [, array &$addtl  ]]] )

এটি যখন DNS কোয়েরি ব্যর্থ হয় তখন এটি একটি সতর্কতা দেয়।

try/ catchকাজ করে না কারণ একটি সতর্কতা ব্যতিক্রম নয়।

আমার কাছে এখন 2 টি বিকল্প রয়েছে:

  1. set_error_handler ওভারকিলের মতো বলে মনে হচ্ছে কারণ পৃষ্ঠার প্রতিটি সতর্কতা ফিল্টার করতে আমাকে এটি ব্যবহার করতে হবে (এটি কি সত্য?);

  2. ত্রুটি প্রতিবেদন / প্রদর্শন সামঞ্জস্য করুন যাতে এই সতর্কতাগুলি স্ক্রিনে প্রতিধ্বনিত হয় না, তারপরে ফেরতের মানটি পরীক্ষা করে দেখুন; যদি এটি হয় তবে falseহোস্টনামের জন্য কোনও রেকর্ড পাওয়া যায় না।

এখানে সেরা অনুশীলন কি?


1
স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 136899/ … এই জাতীয় জিনিসগুলির বিষয়ে একটি ভাল আলোচনা।
মেজ

নীচে একটি উত্তর আছে যে মুছে ফেলা হয়েছে? হয় মালিক দ্বারা বা কারো দ্বারা?
ব্যবহারকারী 121196

এছাড়াও দেখুন: stackoverflow.com/questions/1087365
dreftymac

@ ব্যবহারকারী 121196: হ্যাঁ। মালিক দ্বারা
অরবিটে হালকা ঘোড়দৌড়

উত্তর:


373

ত্রুটি হ্যান্ডলারটি সেট এবং পুনরুদ্ধার করুন

একটি সম্ভাবনা হ'ল কলের আগে আপনার নিজের ত্রুটি হ্যান্ডলারটি সেট করা এবং পরে এর সাথে পূর্ববর্তী ত্রুটি হ্যান্ডলারটি পুনরুদ্ধার করা restore_error_handler()

set_error_handler(function() { /* ignore errors */ });
dns_get_record();
restore_error_handler();

আপনি এই ধারণাটি তৈরি করতে এবং পুনরায় ব্যবহারযোগ্য ত্রুটি হ্যান্ডলার লিখতে পারেন যা আপনার জন্য ত্রুটিগুলি লগ করে।

set_error_handler([$logger, 'onSilencedError']);
dns_get_record();
restore_error_handler();

ব্যতিক্রমগুলিতে ত্রুটি ঘুরিয়ে দেওয়া

সমস্ত পিএইচপি ত্রুটিগুলি ব্যতিক্রমগুলিতে পরিণত করতে আপনি set_error_handler()এবং ErrorExceptionক্লাসটি ব্যবহার করতে পারেন ।

set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) {
    // error was suppressed with the @-operator
    if (0 === error_reporting()) {
        return false;
    }

    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

try {
    dns_get_record();
} catch (ErrorException $e) {
    // ...
}

আপনার নিজের ত্রুটি হ্যান্ডলারটি ব্যবহার করার সময় গুরুত্বপূর্ণ বিষয়টিটি হ'ল error_reportingসেটিংসটি বাইপাস করে সমস্ত ত্রুটি (নোটিশ, সতর্কতা ইত্যাদি) আপনার ত্রুটি হ্যান্ডলারের কাছে পৌঁছে দেবে। আপনি set_error_handler()কোন ত্রুটি প্রকারটি পেতে চান তা নির্ধারণ করতে বা ... = error_reporting()ত্রুটি হ্যান্ডলারের অভ্যন্তরে বর্তমান সেটিংস অ্যাক্সেস করতে আপনি দ্বিতীয় যুক্তি সেট করতে পারেন ।

সতর্কতা দমন করা

আরেকটি সম্ভাবনা হ'ল @ অপারেটরের সাথে কলটি দমন করা এবং তার dns_get_record()পরে ফেরতের মান পরীক্ষা করা । তবে আমি এর বিরুদ্ধে পরামর্শ দেব কারণ ত্রুটিগুলি / সতর্কতাগুলি পরিচালনা করার জন্য ট্রিগার করা হয়, দমন করা উচিত নয়।


3
ফাংশন কলের ঠিক আগে আমার নিজের ত্রুটি হ্যান্ডলারটি সেট করার পরামর্শ দেওয়া হয়, ত্রুটি পরীক্ষা করার পরে পুনরুদ্ধার_আরার_হ্যান্ডলার?
ব্যবহারকারী 121196

2
যদি সেখানে অনেকগুলি সমবর্তী অনুরোধ থাকে তবে এটি থ্রেডটি নিরাপদ হবে এবং প্রতিটি অনুরোধটি 1.set_error_handler () করে। 2.ডোইট 3. রেস্টোর_অরর_হ্যান্ডলার?
ব্যবহারকারী 121196

3
ধন্যবাদ; এটি সাহায্য করে (এবং তারা বলে যে পিএইচপি কোনও বিপর্যয় নয়))
অ্যারন মিলার

2
ত্রুটি দমন করতে @ ব্যবহার থেকে বিরত থাকার জন্য +1। E_WARNING আসলে একটি মারাত্মক ত্রুটি। সাধারণভাবে আপনার সর্বদা ত্রুটিগুলি যথাযথভাবে পরিচালনা করার চেষ্টা করা উচিত। আপনার অ্যাপ্লিকেশনটিতে যদি সেট_অরর_হ্যান্ডলার ব্যবহারের প্রয়োজন হয় তবে তা করুন। সাধারণত ত্রুটিগুলি লগ করা এবং উত্পাদন পরিবেশে সেগুলির প্রদর্শন অক্ষম করার পরামর্শ দেওয়া হয়। লগগুলি পরীক্ষা করে আপনি দেখতে পাবেন আপনার বিকাশের পরিবেশে কোথায় পরিবর্তন আনতে হবে। অনেকগুলি উদাহরণ যেখানে আমি @ ফপেন / @ লিঙ্কমুক্ত দেখেছি এবং অবাক করেছি কেন বিকাশকারীরা ত্রুটিগুলি এড়াতে বা সেট_ররর_হ্যান্ডলার ব্যবহার করে ত্রুটিটি পরিচালনা করতে চেকগুলি সম্পাদন করেন নি।
fyrye

5
সতর্কবাণীগুলি ব্যতিক্রমগুলিতে রূপান্তরিত করার বিষয়ে একটি নোট: একটি সতর্কতা আপনার অ্যাপ্লিকেশনটি বাতিল করবে না — একটি অব্যক্ত ব্যতিক্রম এটি করবে!
আলভারো গঞ্জালেজ

149

যে সমাধানটি সত্যিই কাজ করে সেগুলি E_WARNINGপ্যারামিটারের সাহায্যে সাধারণ ত্রুটি হ্যান্ডলারটি সেট করে so

set_error_handler("warning_handler", E_WARNING);
dns_get_record(...)
restore_error_handler();

function warning_handler($errno, $errstr) { 
// do something
}

4
এছাড়াও বেনামে callableফাংশন ঘোষণার সাথে স্ট্রিংয়ের পরিবর্তে এখানে ব্যবহার করা যেতে পারে
vp_arth

ধন্যবাদ, তবে আমি কীভাবে সমালোচনামূলক ব্লকের পরে ত্রুটি-হ্যান্ডলারটি সরাতে পারি?
ইয়েভেগেনি আফানসিয়েভ

3
অসাধারণ! ঠিক trow new \Exception($errstr, $errno);ভিতরে warning_handlerফাংশন। ধন্যবাদ।
ভ্লাদিমির ভুকানাক

এটি এখানে সেরা উত্তর!
lewis4u

28

@অপারেটরের সাথে সাবধান হন - যখন এটি সতর্কতাগুলি দমন করে তবে এটি মারাত্মক ত্রুটিগুলিও দমন করে। আমি এমন একটি সিস্টেমে সমস্যার ডিবাগ করার জন্য অনেক সময় ব্যয় করেছি যেখানে কেউ লিখেছিল @mysql_query( '...' )এবং সমস্যাটি হ'ল মাইএসকিএল সমর্থন পিএইচপি-তে লোড করা হয়নি এবং এটি একটি নীরব মারাত্মক ত্রুটি ছুঁড়ে ফেলেছে। এটি সেই জিনিসগুলির জন্য নিরাপদ হবে যা পিএইচপি কোরের অংশ, তবে দয়া করে এটি যত্ন সহ ব্যবহার করুন।

bob@mypc:~$ php -a
Interactive shell

php > echo @something(); // this will just silently die...

আর কোনও আউটপুট নেই - শুভকামনা এটি ডিবাগ করছে!

bob@mypc:~$ php -a
Interactive shell

php > echo something(); // lets try it again but don't suppress the error
PHP Fatal error:  Call to undefined function something() in php shell code on line 1
PHP Stack trace:
PHP   1. {main}() php shell code:0
bob@mypc:~$ 

এবার কেন এটি ব্যর্থ হয়েছে তা আমরা দেখতে পাচ্ছি।


5

আমি চেষ্টা করতে / একটি সতর্কবার্তা ধরতে চেয়েছিলাম, তবে একই সময়ে স্বাভাবিক সতর্কতা / ত্রুটি লগিং রাখি (যেমন /var/log/apache2/error.log); যার জন্য হ্যান্ডলারের ফিরে আসতে হবে false। তবে যেহেতু "নতুন থ্রো ..." বিবৃতিটি মূলত মৃত্যুদন্ড কার্যকর করে, তাই তারপরে একটি "র‌্যাপ ইন ইন ফাংশন" ট্রিকটি করতে হয়, এতে আরও আলোচনা করা হয়:

পিএইচপি পিছু ব্যতিক্রম করার কোনও স্থির উপায় আছে কি?

বা, সংক্ষেপে:

  function throwErrorException($errstr = null,$code = null, $errno = null, $errfile = null, $errline = null) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
  }
  function warning_handler($errno, $errstr, $errfile, $errline, array $errcontext) {
    return false && throwErrorException($errstr, 0, $errno, $errfile, $errline);
    # error_log("AAA"); # will never run after throw
    /* Do execute PHP internal error handler */
    # return false; # will never run after throw
  }
  ...
  set_error_handler('warning_handler', E_WARNING);
  ...
  try {
    mkdir($path, 0777, true);
  } catch (Exception $e) {
    echo $e->getMessage();
    // ...
  }

সম্পাদনা করুন: কাছাকাছি পরিদর্শন পর এটি সক্রিয় আউট এটা কাজ করে না: " return false && throwErrorException ...", মূলত হবে না ব্যতিক্রম নিক্ষেপ, এবং শুধুমাত্র ত্রুটি লগ লগ ইন করুন; " false &&" অংশটিকে ", যেমন " " মুছে ফেলা return throwErrorException ...ব্যতিক্রম ছোঁড়ার কাজটি করে দেবে, তবে ত্রুটি_লগে লগ ইন করবে না ... যদিও আমি এখনও এই পোস্টটি রাখি, যদিও আমি অন্য কোথাও এই আচরণটি নথিভুক্ত দেখিনি।


4

আপনার সম্ভবত সতর্কবার্তাটি সম্পূর্ণরূপে মুক্তি পাওয়ার চেষ্টা করা উচিত, তবে যদি এটি সম্ভব না হয় তবে আপনি @ (যেমন @ dns_get_record (...)) এর মাধ্যমে কলটি প্রতিরোধ করতে পারেন এবং তারপরে সতর্কতাটি ঘটেছে কিনা তা জানতে আপনি যে কোনও তথ্য ব্যবহার করতে পারেন অথবা না.


4

সাধারণভাবে আপনার কখনও কখনও @ ব্যবহার করা উচিত নয় যদি না এটি একমাত্র সমাধান হয়। সেই নির্দিষ্ট ক্ষেত্রে dns_check_record ফাংশনটি রেকর্ডটি বিদ্যমান কিনা তা জানতে প্রথমে ব্যবহার করা উচিত।


3

file_get_contents()কোনও বাহ্যিক url এ কলের চারপাশে কোডের এই লাইনগুলির সংমিশ্রণটি আমাকে " স্ট্রিমটি খুলতে ব্যর্থ হয়েছে: সংযোগের সময়সীমা শেষ হয়েছে " এর মতো সতর্কতাগুলি হ্যান্ডেল করতে সহায়তা করেছিল : আরও ভাল:

set_error_handler(function ($err_severity, $err_msg, $err_file, $err_line, array $err_context)
{
    throw new ErrorException( $err_msg, 0, $err_severity, $err_file, $err_line );
}, E_WARNING);
try {
    $iResult = file_get_contents($sUrl);
} catch (Exception $e) {
    $this->sErrorMsg = $e->getMessage();
}
restore_error_handler();

এই সমাধানটি বস্তুর প্রসঙ্গেও কাজ করে। আপনি এটি একটি ফাংশনে ব্যবহার করতে পারেন:

public function myContentGetter($sUrl)
{
  ... code above ...
  return $iResult;
}

2

যদি dns_get_record()ব্যর্থ হয় তবে এটি ফিরে আসবে FALSE, সুতরাং আপনি সতর্কতাটি দিয়ে দমন করতে পারেন @এবং তারপরে ফেরতের মানটি পরীক্ষা করতে পারেন।


0

এটি কিছু বুলিয়ান মান দেয় কিনা তা খতিয়ে দেখার চেষ্টা করুন তবে আপনি এটিকে কেবল শর্ত হিসাবে রাখতে পারেন। আমি oci_execute (...) এর সাথে মুখোমুখি হয়েছি যা আমার অনন্য কীগুলির সাহায্যে কিছু লঙ্ঘন ফিরিয়ে আনছে।

ex.
oci_parse($res, "[oracle pl/sql]");
if(oci_execute){
...do something
}

0

FolderStructure

index.php //Script File
logs //Folder for log Every warning and Errors
CustomException.php //Custom exception File

CustomException.php

/**
* Custom error handler
*/
function handleError($code, $description, $file = null, $line = null, $context = null) {
    $displayErrors = ini_get("display_errors");;
    $displayErrors = strtolower($displayErrors);
    if (error_reporting() === 0 || $displayErrors === "on") {
        return false;
    }
    list($error, $log) = mapErrorCode($code);
    $data = array(
        'timestamp' => date("Y-m-d H:i:s:u", time()),
        'level' => $log,
        'code' => $code,
        'type' => $error,
        'description' => $description,
        'file' => $file,
        'line' => $line,
        'context' => $context,
        'path' => $file,
        'message' => $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']'
    );
    $data = array_map('htmlentities',$data);
    return fileLog(json_encode($data));
}

/**
* This method is used to write data in file
* @param mixed $logData
* @param string $fileName
* @return boolean
*/
function fileLog($logData, $fileName = ERROR_LOG_FILE) {
    $fh = fopen($fileName, 'a+');
    if (is_array($logData)) {
        $logData = print_r($logData, 1);
    }
    $status = fwrite($fh, $logData . "\n");
    fclose($fh);
//    $file = file_get_contents($filename);
//    $content = '[' . $file .']';
//    file_put_contents($content); 
    return ($status) ? true : false;
}

/**
* Map an error code into an Error word, and log location.
*
* @param int $code Error code to map
* @return array Array of error word, and log location.
*/
function mapErrorCode($code) {
    $error = $log = null;
    switch ($code) {
        case E_PARSE:
        case E_ERROR:
        case E_CORE_ERROR:
        case E_COMPILE_ERROR:
        case E_USER_ERROR:
            $error = 'Fatal Error';
            $log = LOG_ERR;
            break;
        case E_WARNING:
        case E_USER_WARNING:
        case E_COMPILE_WARNING:
        case E_RECOVERABLE_ERROR:
            $error = 'Warning';
            $log = LOG_WARNING;
            break;
        case E_NOTICE:
        case E_USER_NOTICE:
            $error = 'Notice';
            $log = LOG_NOTICE;
            break;
        case E_STRICT:
            $error = 'Strict';
            $log = LOG_NOTICE;
            break;
        case E_DEPRECATED:
        case E_USER_DEPRECATED:
            $error = 'Deprecated';
            $log = LOG_NOTICE;
            break;
        default :
            break;
    }
    return array($error, $log);
}
//calling custom error handler
set_error_handler("handleError");

ঠিক উপরের ফাইলটিকে আপনার স্ক্রিপ্ট ফাইলে অন্তর্ভুক্ত করুন

index.php

error_reporting(E_ALL);
ini_set('display_errors', 'off');
define('ERROR_LOG_FILE', 'logs/app_errors.log');

include_once 'CustomException.php';
echo $a; // here undefined variable warning will be logged into logs/app_errors.log

-2

আমি কেবলমাত্র সতর্কতা দমন করতে @ ব্যবহার করার পরামর্শ দিই যখন এটি একটি সরাসরি অগ্রসর অপারেশন (যেমন $ প্রোপ = @ ($ উচ্চ / ($ প্রস্থ - $ গভীরতা)); শূন্য সতর্কতা দ্বারা বিভাগ এড়াতে)। তবে বেশিরভাগ ক্ষেত্রে এটি পরিচালনা করা ভাল।


2
এটি একবার আপনি অবশ্যই @ ব্যবহার করতে চাইবেন না - অপারেশনের উপর আপনার নিয়ন্ত্রণ রয়েছে এবং এটি শূন্যের দ্বারা ভাগ করার আগে এটি পরীক্ষা করার আগে তা পরীক্ষা করতে পারেন।
ইওরবব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.