سبد (0)

تبلیغات

رسیدگی به خطاها در PHP

رسیدگی یا مدیریت خطاها در php

Wiki

رسیدگی به خطاها در php بسیار ساده است. به صورت پیشفرض اگر خطایی رخ دهد، یک پیغام خطا که توضیح دهنده ی خطا است، همراه با نام فایل و شماره خط به مرورگر فرستاده می شود.

هنگام ایجاد برنامه های تحت وب، بررسی خطاها یک بخش مهم است. اگر کد شما امکان بررسی خطا را نداشته باشد، در این صورت بسیار غیرحرفه ای عمل کرده اید و ممکن است در معرض خطر امنیتی قرار بگیرید.

در زیر بعضی روش های معمول بررسی خطا در php توضیح داده خواهد شد:

  • استفاده از دستور ساده ()die
  • خطاهای معمولی و راه اندازی رسیدگی کننده خطا
  • واقعه نگاری خطاها

استفاده از تابع ()die

Wiki

این تابع متنی را که به عنوان پارامتر برای آن مشخص کرده ایم، چاپ می کند و از کد جاری خارج می شود.

مثال: در این مثال با استفاده از تابع ()fopen یک فایل متنی را به صورت فقط خواندنی باز می کنیم:

<?php
$file=fopen("welcome.txt","r");
?>

اگر فایل وجود نداشته باشد، با خطای زیر مواجه می شویم:

Warning: fopen(welcome.txt) [function.fopen]: failed to open stream:
No such file or directory in C:\webfolder\test.php on line 2

برای اینکه کاربر با پیغام خطای بالا مواجه نشود، قبل از هر چیز، وجود فایل "welcome.txt" را بررسی می کنیم:

<?php
if(!file_exists("welcome.txt"))
die("File not found");
else
$file=fopen("welcome.txt","r");
?>

کد بالا کارامدتر از کد قبلی است، حالا اگر فایل وجود نداشته باشد بعد از اجرای اسکریپت، پیغام خطای زیر نمایش داده می شود:

File not found

توجه: در اسکریپت بالا، بعد از اجرای دستور ()die، ادامه اجرای اسکریپت متوقف می شود.

متوقف کردن اسکریپت، به این سادگی، همیشه راه درست نیست. بیایید نگاهی به توابع تناوبی رفع خطا در php بیندازیم.


ایجاد یک تابع رسیدگی کننده خطا (error handler)

Wiki

ایجاد این تابع کاملاً ساده است، و هرگاه که در کد PHP خطایی رخ داد این تابع فراخوانی می شود.

این تابع باید بتواند حداقل با دو پارامتر کار کند(سطح خطا و پیغام خطا) اما تا پنج پارامتر را بپذیرد(اختیاری: فایل، شماره خط و متن پیغام):

نحوه استفاده:

error_function(error_level,error_message,error_file,error_line,error_context)

پارامتر توضیحات
error_level

الزامی است، سطح گزارش خطا را مشخص می کند. جدول زیر را برای انواع سطوح گزارش خطا ببینید.

error_message

الزامی است، پیغام خطا را برای خطای تعریف شده توسط کاربر مشخص می کند.

error_file

اختیاری است. نام فایلی را که خطا در ان رخ داده است مشخص می کند.

error_line

اختیاری است. شماره خطی را که خطا در آن رخ داده است مشخص می کند.

error_context

اختیاری است. یک آرایه که شامل تمام متغییرهای در حال استفاده هنگام رخداد خطا با مقادیرشان است را مشخص می کند.

سطوح گزارش خطا:

مقدار نام ثابت توضیحات
2 E_WARNING

خطاهای زمان اجرا غیر جدی. اجرای script متوقف نمی شود

8 E_NOTICE

اخطارهای زمان اجرا.script چیزی پیدا کرده که ممکن است خطا باشد? اما می تواند در اجرای معمولی script نیز رخ دهد

256 E_USER_ERROR

خطای جدی کاربرساز. مانند یک E-ERROR که توسط کابر با استفاده از تابع trigger_error( ) در php به وجود می آید.

512 E_USER_WARNING

هشدار غیرجدی کاربرساز. مانند یک E_WARNING است که توسط کابر با استفاده از تابع trigger_error( ) در php به وجود می آید.

1024 E_USER_NOTICE

اخطار کاربرساز. مانند یک E_NOTICE است که توسط کابر با استفاده از تابع trigger_error( ) در php به وجود می آید.

4096 E_RECOVERABLE_ERROR

خطای جدی گرفتنی. مانند یک E_ERROR است اما بوسیله ی رفع خطای تعریف شده توسط کاربر می توان ان را گرفت(set_error_handler( ) را نیز ببینید)

8191 E_ALL

همه ی خطاها و هشدارها?به جز سطح E_STRICT) E_STRICT در php 6.0 جزئی از E_ALL خواهد شد.)

حالا اجازه دهید تا یک تابع برای رسیدگی کردن به خطاها ایجاد کنیم، که شامل ورودی های زیر است:

  • errno$: سطح خطا
  • errstr$: متن خطا

function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Ending Script";
die();
}

کد بالا موقعی که راه اندازی شد، "سطح خطا" و "متن خطا" را می گیرد و سپس با چاپ کردن دو مورد ذکر شده به اجرای اسکریپت پایان می دهد.

در حال حاضر باید تصمیم بگیریم که چه موقع تابع بالا، راه اندازی شود.


تنظیم رسیدگی کننده خطا

Wiki

ما قصد داریم تابع "customError" را به عنوان پیشفرض رسیدگی کننده خطا در PHP معرفی کنیم، این کار به سادگی با استفاده از تابع زیر در PHP امکان پذیر است:

set_error_handler("customError");

نکته: یک پارامتر دوم می تواند برای مشخص کردن سطح خطا به تابع ()set_error_handler اضافه شود، ولی چون می خواهیم که تابع معمولی مان همه ی خطاها را رفع کند، ()set_error_handler تنها با یک پارامتر فراخوانی می شود.

مثال: در زیر سعی کرده ایم با چاپ متغییر "test$" که وجود ندارد تابع "رسیدگی کننده خطا" یا همان "customError" را تست کنیم:

<?php
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr";
}
set_error_handler("customError");
echo($test);
?>

خروجی کد بالا:

Error: [8] Undefined variable: test


راه اندازی یک خطا

Wiki

در اسکریپتی که کاربران می توانند داده وارد کنند، می توان موقع رخداد یک ورودی غیرمجاز خطاها را راه اندازی کرد. در php، این کار با تابع ()trigger_error انجام می شود.

مثال: در این مثال اگر متغییر "test" بزرگتر از "1" باشد، یک خطا رخ می دهد:

<?php
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below");
}
?>

خروجی کد بالا:

Notice: Value must be 1 or below
in C:\webfolder\test.php on line 5

یک خطا می تواند هر جایی در اسکریپت که بخواهید راه اندازی شود و با افزودن پارامتر دوم شما می توانید مشخص کنید که چه سطح خطایی راه اندازی شود.

مثال: در این مثال یک خطا با سطح E_USER_WARNING رخ می دهد، اگر متغییر "test" بزرگتر از "1" باشد، تابع رسیدگی کننده خطا، راه اندازی شده و اسکریپت را خاتمه می دهیم:

<?php
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Ending Script";
die();
}

set_error_handler("customError",E_USER_WARNING);

$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below",E_USER_WARNING);
}
?>

خروجی کد بالا:

Error: [512] Value must be 1 or below
Ending Script

اکنون که طریقه ی رسیدگی به خطاها و چگونگی راه اندازی آن ها را یاد گرفتیم، اجاز دهید نگاهی به واقعه نگاری (Log) خطاها بیندازیم.


واقعه نگاری خطاها (Log)

Wiki

به طور پیش فرض، php یک گزارش خطا به سیستم واقعه نگاری سرورها یا یک فایل، بسته به اینکه پیکر بندی گزارش خطا چگونه درفایل php.ini تنظیم شده است ارسال می کند. با استفاده از تابع ()error_log شما می توانید گزارش های خطا را به به یک فایل مشخص شده یا یک مقصد دور ارسال کنید.

ارسال پیغام های خطاها به خودتان از طریق email می تواند روش خوبی برای آگاه شدن از خطاهای خاص باشد.

مثال: در این مثال اگر یک خطای خاص رخ دهد ما یک e-mail را همراه با یک پیغام خطا به آدرس مشخص شده می فرستیم و اسکریپت خاتمه خواهد یافت:

<?php
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Webmaster has been notified";
error_log("Error:[$errno]$errstr",1,"این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید","From:این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید");
}

set_error_handler("customError",E_USER_WARNING);

$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below",E_USER_WARNING);
}
?>

خروجی کد بالا:

Error: [512] Value must be 1 or below
Webmaster has been notified

و در ادامه ایمیل دریافت شده چیزی شبیه زیر خواهد بود:

Error: [512] Value must be 1 or below

توجه: این نباید برای همه ی خطاها استفاده شود، خطاهای معین باید با سیستم واقعه نگاری پیش فرض php در سرور ثبت شوند.

برای مشاهده فیلم ها و آموزش های پروژه محور برنامه نویسی PHP کلیک کنید.

دیدگاه‌ها  

+2 # آرمان 1396-01-25 18:52
سلام و خداقوت.درقسمت تنظیم رسیدگی کننده خطا, متغیر $errstr از کجا مقدار میگیره؟ خروجی Undefined variable: test از کجا اومده؟
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+2 # امیر پهلوان صادق 1396-01-26 09:27
سلام اگر یکبار دیگر با دقت به کد مورد نظر دقت کنید، متوجه خواهید شد که ما در حال چاپ متغیری هستیم که تعریف نشده است، بنابراین بصورت اتوماتیک توسط PHP سطح خطا و متن زیر ایجاد خواهد شد:
errno$: (سطح خطا) --> 8
errstr$: (متن خطا) --> Undefined variable: test
اسکریبت مورد نظر:
<?php
function customError($er rno, $errstr)
{
echo "Error: [$errno] $errstr";
}
set_error_handler("customError");
echo($test);
?>
بنابراین زمانی که تابع customError صدا زده می شود، پارامترهای مذکور بصورت اتوماتیک توسط PHP مقداردهی شده اند.
نهایتا وظیفه تابع customError در زیر کاملا واضح است که باعث چاپ همزمان "سطح خطا" و "متن خطا" شده و در انتهای آن با استفاده از تابع die از برنامه خارج می شویم.
function customError($er rno, $errstr)
{
echo "Error: [$errno] $errstr";
echo "Ending Script";
die();
}
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+1 # آرمان 1396-01-27 19:13
اها درسته ممنون.اما مگه اول اموزش نگفتین باید خودمون به خطا رسیدگی کنیم وگرنه php خودش اون دوخط ارور رو چاپ میکنه که از نظر ایمنی مناسب نیست؟یعنی متن خطارو باید خودمون تنظیم کنیم که چی باشه نه بصورن پیش فرض php.مگه هدف از این اموزش همین نبود؟
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+2 # امیر پهلوان صادق 1396-01-28 08:23
لطفا به پیام خطایی که بصورت پیشفرض توسط PHP گزارش می شود یکبار دیگر در زیر دقت کنید:
Warning: fopen(welcome.t xt) [function.fopen ]: failed to open stream:
No such file or directory in C:\webfolder\te st.php on line 2

همان طور که در بالا می بینید، داخل پیام خطا، "نام فایل" و "آدرس فایلی" که خطا در آن اتفاق افتاده است بصورت کامل ذکر شده که از لحاظ امنیتی، نباید نمایش داده شود. اما ما با استفاده از تابع customError می توانیم موارد ذکر شده را از داخل متن خطا حذف کنیم و کلا مدیریت گزارش خطاها را بدست بگیریم.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+3 # فریبا mizraee 1394-09-18 14:28
سلام خسته نباشید
بعد از اجرای کد چنین خطایی دارم ممکنه کمک کنید:Parse error: syntax error, unexpected T_ELSE in C:\xampp\htdocs \f\r.php on line 6529
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+2 # مهرداد صلاحی 1394-09-18 19:43
با سلام و تشکر.
متن کد نیومده! ولی متن خطا داره می‌گه، تو کدها خطای گرامری وجود داره.
یه جایی تو دستور if else احتمالا مرتکب خطا شدید.

این موارد رو چک کنید.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+2 # امین 1394-07-18 12:11
با عرض سلام وخسته مباشید و تشکر بابت سایت خوبتون
میخاستم اگه بشه این کد رو که در بالا نوشته بودید توضیح بدید .ممنون.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+1 # مهرداد صلاحی 1394-07-19 09:20
با سلام.
دقیقا منظور شما کدوم قسمت از کد هست؟؟؟
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+2 # مهدی ربانی 1394-07-07 10:00
من دستور if رو خوب بلدم. شما اصلا سوال بنده رو متوجه نشدید.
من میگم دستور if دو حالت داره. یا شرطش درسته یا غلط.
اینجا اگر شرط درست باشه (فایل وجود نداشته باشه) ، ()die اجرا میشه و بعد از اون هیچ چیزی اجرا نمیشه. (یعنی else اجرا نمیشه)
و اگر شرط غلط باشه (فایل وجود داشه باشه) ، از بلاک if خارج میشه و دستور بعد از if هرچی باشه اجرا میشه و حالت دیگری وجود نداره که else نیاز داشته باشه.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+2 # شهربانو دوستی 1394-07-07 21:29
با سلام
معمول ترین نوع ساختار تصمیم گیری if است. یک دستور if می گوید "اگر شرطی برقرار است کد معینی را انجام بده". دستور if-else به دو شکل می تواند باشد: همراه با else يا بدون آن.
if(expression)
{
statement
}
يا

if(expression)
{
statement
}
else
{
statement
}

بدنبال کلمه if یک پرانتز می آید که عبارت شرط در آن قرار دارد و يک مقدار بولين false يا true توليد می کند (در C به صورت صفر و غير صفر ارزيابی می شود). با درست و غلط بودن عبارت شرطی مسير اجرا تعيين می شود. اگر درست باشد دستور بعد از if اجرا می شود. اگر else وجود داشته باشد در صورت برقرار نبودن شرط دستور بعد از else اجرا می شود.
با توجه به توضیحات ذکر شده، در صورت برقرار نبودن شرط if عبارت جلوی else اجرا می شود. بر اساس سوال شما، یعنی در صورتی که فایل وجود داشته باشد و نخواهیم در صورت وجود فایل کار دیگری انجام دهیم بله می توانیم else را بر داریم.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+2 # مهدی ربانی 1394-07-07 22:31
به نقل از شهربانو دوستی:

با توجه به توضیحات ذکر شده، در صورت برقرار نبودن شرط if عبارت جلوی else اجرا می شود. بر اساس سوال شما، یعنی در صورتی که فایل وجود داشته باشد و نخواهیم در صورت وجود فایل کار دیگری انجام دهیم بله می توانیم else را بر داریم.


نه من نگفتم عبارت جلوی else برداشته بشه. حرف من اینه که خود کلمه ی else از این کد برداشته بشه. یعنی فقط خط سوم رو حذف کنیم. اگر این کار رو بکنیم نتیجه هیچ تغییری نمی کنه. امتحان کنید.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+2 # شهربانو دوستی 1394-07-07 23:28
دقیقا صحبت من هم همین بود. اگر فقط عبارت جلوی else برداشته شود که دستور صحیح نیست. طبق گفته قبل در صورتی که نیازی ندارید در صورت بر قرار نبودن شرط if کار دیگری انجام شود می توانید else به همراه عبارت جلوی آن را بردارید.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+1 # مهدی ربانی 1394-07-08 07:56
به نقل از شهربانو دوستی:
در صورتی که نیازی ندارید در صورت بر قرار نبودن شرط if کار دیگری انجام شود می توانید else به همراه عبارت جلوی آن را بردارید.

من از اول دارم میگم کاری به عبارت جلوی else نداشته باشید. فقط else را بردارید شما دوباره میگید else به همراه عبارت جلوی else.
حرف من این است که اگر نیاز به انجام کاری هم باشد (مثل الآن) ، می توان کلمه ی else را برداشت و عبارت جلوی else بدون else نوشت.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+1 # احسان عباسی 1394-07-08 08:54
با سلام
در تکمیل صحبت های خانم دوستی و همچنین نظرات آقای ربانی:
اینکه آقای ربانی می فرماید که با برداشتن کلمه ی else عبارت شرطی بدون هیچ مشکلی اجرا می شود درسته مثلا می تونید عبارت زیر را امتحان کنید:
< ?php

if (1>2)

echo "1>2";

echo "2>1";
? >


در کدهای بالا در خط کد 7 دستور else را برداشته ایم و عبارت شرطی به درستی عمل می کند.
در زبان پایتون اگر اشتباه نکنم عبارات شرطی به این شکل نوشته می شوند(در یکی از حالت هایش) . به نظرم این طور نوشتن دستورات در php مربوط به نسخه های قدیمی آن باشد. و در php نوین، ذکر شده است که عبارت else را اضافه کنیم.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
0 # مهدی ربانی 1394-02-24 14:40
در سومین کد قسمت استفاده از تابع ()die ، یعنی کد زیر:if(!file_exists("welcome.txt"))
die("File not found");
else
$file=fopen("we lcome.txt","r") ;

مگر بعد از اجراي دستور ()die، ادامه اجراي اسکريبت متوقف نمی شود؟
پس دیگر نوشتن کلمه ی else نیازی نیست! اگر بلوک if اجرا شد ادامه ی اسکریپت اجرا نمی شود و اگر اجرا نشد بقیه اجرا می شود.
پس کاربرد کلمه ی else در اینجا چیست؟
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
-2 # ایمان whnrd 1394-07-06 08:43
مهدی جان فکر می کنم شما باید اول دستور if رو خوب یاد بگیری.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
+1 # امیر پهلوان صادق 1394-02-26 09:24
درسته که در این مثال ما عمداً کاری کردیم که خطا ایجاد شود، یعنی فایل welcome.txt را درست آدرس دهی نکردیم...!
اما توجه داشته باشید که زمانی که آدرس دهی بدرستی انجام شده باشد، باید به قسمت else منتقل شویم و فایل مورد نظرمان را open کنیم.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن
0 # مهدی ربانی 1394-07-07 10:05
منظور من اینه که کلمه ی else رو از کد بالا حذف کنیم هم هیچ اتقاقی نمی افته. یعنی خط 3 حذف بشه باز هم کد به درستی کار می کنه.
پاسخ دادن | پاسخ به نقل قول | نقل قول کردن

آموزش صوتی PHP

بستن
مدرس:
سوال و جواب:

ابزاری که در پیش روی دارید یکی از ابزارهای بسیار کاربردی سایت بیاموز در زمینه آموزش است، این ابزار برای سهولت یادگیری شما کاربران محترم طراحی شده است.

فقط کافی است روی عنوان پاراگراف مورد نظرتان کلیک کنید تا پخش صدا آغاز شود ...!

تمامی محصولات و خدمات این وبسایت، حسب مورد دارای مجوزهای لازم از مراجع مربوطه می‌باشند و فعالیت‌های این سایت تابع قوانین و مقررات جمهوری اسلامی ایران است.
logo-samandehi مجوز نشر دیجیتال از وزرات فرهنگ و ارشاد اسلامی پرداخت آنلاین -  بانک ملت معرفی بیاموز در شبکه سه پرداخت آنلاین - بانک اقتصاد نوین پرداخت آنلاین - بانک سامان
 
دوره های آموزشی راه اندازی کسب و کارهای اینترنتی
تبلیغات اینترنتی