#4 - نکات و اصول مهم در برنامه نویسی PHP
1- برای بدست اوردن میزان حافظه مصرف شده باید از دستور memory_get_usage(FALSE)
استفاده کنید و برای میزان حافظه رزرو شده باید از دستور memory_get_usage(TRUE)
استفاده کنید.
اما این نکته در مستندات سایت PHP.net برعکس توضیح داده شده:
int memory_get_usage ([ bool $real_usage = FALSE ] )
Returns the amount of memory, in bytes, that's currently being allocated to your PHP script.
2- زمانی از دستور strcmp
استفاده کنید که قراره مقدار رشته ها شمارش(کمتر/بیشتر) بشن، درغیراینصورت استفاده از اپراتور ===
برای برابر بودن/نبودن رشته ها بهترین گزینست.
3- آیا میدونید به 4 روش مختلف میتونید تصاویر رو در مرورگر نمایش/output بدید؟
header('Content-Type: image/jpg'); $image = imagecreatefromjpeg('yourfilename.jpg'); header('Content-Length: ' . filesize('yourfilename.jpg')); imagejpeg($image); imagedestroy($image);
و
header('Content-Type: image/jpg'); header('Content-Length: ' . filesize('yourfilename.jpg')); readfile('yourfilename.jpg');
و
header('Content-Type: image/jpg'); header('Content-Length: ' . filesize('yourfilename.jpg')); echo file_get_contents('yourfilename.jpg');
و
header('Content-Type: image/jpg'); header('Content-Length: ' . filesize('yourfilename.jpg')); header('X-Sendfile: ' . 'yourfilename.jpg'); exit;
4- اگر از PHP CLI در محیط text UI سیستم عامل استفاده می کنید و مشکلات output و نمایشی دارید، بهتره از دستور passthru
استفاده کنید.
5- نکته جزیی: فراموش نکنید که تابع json_decode
فقط اعضای public
شی موردنظر رو تبدیل میکنه، و نه private
/ protected
.
6- مفهوم Code refactoring به زبان ساده: تغییر کد، بدون تغییر رفتار کد. یا تغییر کد، بدون شکستن API کد.
7- نکته جزیی: فلسفه استفاده از ابزارهای اتوماسیون build(مثل gradle, maven, phing, ant) تنها کاهش خطاهای انسانی و صرفه جویی در زمان هستش.
8- دو تفاوت اصلی positional placeholder و named placeholder در کتابخانه PDO:
- توسط positional placeholder کد خواناتر و کوتاه میشه.
- در positional placeholder ترتیب پارامترها و ورودی ها باید رعایت بشه.
9- توسط ارسال هدر زیر با PHP میتونید کاربران وبسایت رو در برابر ClickJacking محافظت کنید:
header('X-Frame-Options: DENY'); header("Content-Security-Policy: frame-ancestors 'none'", false);
10- همیشه سعی کنید پارامتر HTTPOnly در تابع setcookie
و setrawcookie
رو TRUE
قرار بدید.
setcookie($name, $value, $expire, $path, $domain, $secure, TRUE); setrawcookie($name, $value, $expire, $path, $domain, $secure, TRUE);
11- مزایای استفاده از dependency injection در طراحی کلاس/متد:
- تمیز شدن کد و افزایش خوانایی کد
- آزاد شدن اتصالات و روابط کلاسها(loosely coupled)
- افزایش reusable شدن کد
- ساده شدن فرایند test کد
12- جهت محافظت از کاربر در برابر برخی حملات XSS هدرهای زیر رو در فایلهای PHP تون قرار بدید:
header('X-XSS-Protection: 1'); // Browser's XSS protection. header('X-Content-Type-Options: nosniff'); // Anti XSS/DriveByDownload.
13- برای تغییر تنظیمات php.ini هنگام runtime، بهتره از دستور ini_set
بجای توابع متفرقه استفاده کنید. (صرفاً جهت افزایش خوانایی و یکدست شدن کدها)
// توابع متفرقه session_name('MYSESSION'); session_save_path('/'); mb_internal_encoding('UTF-8'); // دستور ini_set ini_set('session.name', 'MYSESSION'); ini_set('session.save_path', '/'); ini_set('max_execution_time', 15); ini_set('display_errors', 'Off'); ini_set('default_charset', 'UTF-8'); ini_set('mbstring.internal_encoding', 'UTF-8');
14- جهت دسترسی به cookie/session سایت در همه subdomain های سایت بهتره از کاراکتر نقطه . در ابتدای نام دامنه استفاده کنید.
نکته: دلیل گذاشتن نقطه در domain صرفاً سازگار کردن کوکی سایت با مرورگرهای قدیمی هستش.
15- مرورگرها برای تعیین نحوه پردازش URL از نوع MIME صفحه استفاده می کنن و نه پسوند فایل! بنابراین بسیار مهمه که اسکریپت ها و سرورهای وب، نوع MIME صحیح رو در هدر Content-Type درج کنن.
header('Content-Type: application/json'); header('Content-Type: text/plain'); header('Content-Type: application/pdf');
توجه: اگر این مورد درست پیکربندی نشه، مرورگرها به اشتباه به تفسیر محتوای فایلها می پردازن و خروجی سایتها هم به درستی کار نمی کنن، و حتی ممکنه فایلهای load شده مورد سوء استفاده های امنیتی قرار بگیرن.
16- درصورتیکه از تابع set_error/exception_handler()
استفاده کرده باشید، تابع error_get_last()
خالی و مقدار بازگشتی NULL
خواهد شد.
17- سعی کنید همیشه تاریخ و زمان رو بر اساس UTC در فایل و دیتابیس ذخیره کنید و نه زمان محلی.
https://stackoverflow.com/questions/2532729/daylight-saving-time-and-time-zone-best-practices
https://stackoverflow.com/questions/2580478/storing-date-times-as-utc-in-database
و برای خوانایی و تبدیل بهتر میتونید از فرمت استاندارد ISO-8601 استفاده کنید. date('c');
18- نکته جزیی: فراموش نکنید که داده نوع NULL
همیشه یک مقدار Invalid/نامعتبر هستش و هرچیزی بجز NULL
یک مقدار Valid/معتبر هستش، حنی ""
19- تحت هیچ شرایطی مقدار NULL
رو return
نکنید. درعوض رشته خالی ""
یا 0 یا آرایه خالی []
بازگشت بدید.
20- جهت بررسی خالی یا پر بودن آرایه یا شمارش محتوای آرایه از دستور count
استفاده کنید و نه sizeof
.
نکته: در سایت رسمی PHP گفته شده که این دو دستور aliase هستن، درصورتیکه سرعت انها در بنچمارکها متفاوت هست. همچنین دستور sizeof
برای برنامه نویسان دیگر زبانها (از نظر خوانایی) مفهوم متفاوتی داره.
21- هرگز از اعداد منفی برای تعیین Status/Exit code استفاده نکنید. از انجاییکه برای سیستم هر چیزی جز عدد 0 به FALSE
ترجمه میشه و بسیاری از زبانها قابلیت return
کردن اعداد منفی برای Status/Exit code رو ندارن، بهترین مقدار اعداد 0 یا مثبت هستن.
22- نکاتی راجب الگوهای Dependency Injection, Service Locator, Inversion of Control:
- الگوی Dependency Inversion Principle (DIP) منتسب به تجزیه کردن کد هستش، به این صورت که کلاسهای سطح بالا نباید به قسمت های سطح پایینتر وابستگی مستقیم داشته باشه، بلکه باید توسط لایه abstract یا interface به سطوح پایینتر وابستگی داشته باشند.
- Dependency Injection یک الگو هست اما Container و Inversion of Control یک روش برای اجرای الگوی DI.
- توسط الگوی Inversion of Control قادرید dependency اشیا رو بعد از compile یا در محیط production هم تغییر بدید.
23- تفاوت Service Locator با الگوهای DI:
- Service Locator امکان resolve کردن dependency رو "از داخل کلاس" فراهم میکنه. اما DI امکان inject کردن dependency رو "از خارج کلاس" فراهم میکنه.
- همه dependency ها به Service Locator وابسته میشن(خود یک dependency هستش). اما DI فقط یکبار هنگام startup فراخوانی میشه.
- dependency در DI (نوع constructor) صریح و مشخص inject میشه اما در Service Locator اینطور نیست.
- خوانایی در الگوی Service Locator پایین تر از DI هستش.
24- اگر هنگام کار با CURL از کاربر آدرس URL رو دریافت می کنید، همیشه اونرو validate کنید تا با همچین حمله ای(SRF) مواجه نشید:
$userInputURL = 'file:///etc/passwd' $cURL = curl_init($userInputURL); curl_exec($cURL);
25- تنظیمات مهم هنگام کار با CURL:
- همیشه پروتکل CURL رو CURLPROTO_HTTPS و/یا CURLPROTO_HTTP قرار بدید و بحالت پیشفرض رها نکنید:
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS | CURLPROTO_HTTP);
- همیشه مقدار CURLOPT_MAXREDIRS در CURL رو به 5 یا کمتر کاهش بدید.
- همیشه مقدار CURLOPT_SSL_VERIFYHOST رو 2 قرار بدید.
- همشه مقدار CURLOPT_TIMEOUT رو تعیین کنید (مثلا 60)
نکته: مقدار تنظیم default_socket_timeout در فایل php.ini فقط بر روی socket تاثیرگذار هست، و نه روی Timeout CURL.
26- توسط نرم افزار Selenium می تونید UI وب اپلیکیشن رو تست کنید.
27- در صورت امکان از توابع Anonymous استفاده نکنید. اینها به دلایل زیر bad practice محسوب میشن:
- قابل استفاده مجدد نیستند.
- نام ندارن و بنابراین آنچه انجام میدن رو توصیف نمی کنند. پس خوانایی پایینتری دارن
- این توابع رو نمی توان جداگانه توسط Unit Test آزمایش کرد.
28- جهت امنیت بیشتر اپلیکیشن، همیشه فایل installed.json در مسیر /vendor/composer/ رو حذف کنید.
29- هنگام deploy پروژه در سرور، همیشه OpeCache سرور رو ریست کنید. چون OpCache هیچوقت خودکار فایلهای cache شده قدیمی رو پاکسازی نمیکنه. ابزار: https://github.com/gordalina/cachetool
مقالات مرتبط
نکات و اصول مهم در برنامه نویسی PHP
#2 - نکات و اصول مهم در برنامه نویسی PHP
#3 - نکات و اصول مهم در برنامه نویسی PHP
اگر قبلا در بیان ثبت نام کرده اید لطفا ابتدا وارد شوید، در غیر این صورت می توانید ثبت نام کنید.