مهراد

شیوه‌هایی بهتر در php

مهراد توسعه دهنده وب و علاقه‌مند به تکنولوژی

این محتوا بدون نظارت تیم سکان آکادمی تولید شده و صرفاً نظرات شخصی مهراد می‌باشد.

در هر زبان برنامه‌نویسی‌ای مفهومی به نام Best Practice یا همان روش ایده‌آل وجود دارد، که معمولا این روش از بین چند روشی که برای انجام یک کار میتوان به‌کار بست انتخاب می‌شود.

اینکه چرا باید از Best Practice ها استفاده نمود، دلایل مختلفی از جمله مسائل امنیتی، عملکردی (Performance) و ... می‌تواند داشته باشد.

۱. ذخیره کلمات عبور
از جمله روش‌هایی که برای ذخیره کلمات عبور استفاده می‌شود، استفاده از الگوریتم‌های MD5 و SHA1 است که این روش‌ها امنیت کافی برای ذخیره کلمات عبور را ندارند.

برای ذخیره کلمات عبور از فانکشن password_hash استفاده کنید، چراکه از جدیدترین و بهترین مدتهای هَش سازی استفاده می‌کند.

<?php
    // Hash the password.  $hashedPassword will be a 60-character string.
    $hashedPassword = password_hash('mypassword', PASSWORD_DEFAULT);
 
    password_verify('the wrong password', $hashedPassword); // false
    password_verify('mypassword', $hashedPassword); // true
?>

۲. اتصال به دیتابیس
برای اتصال به دیتابیس از درایور PDO استفاده کنید. این درایور به دیتابیس‌های مختلفی می‌تواند متصل شود و به صورت OOP قابل استفاده است.
در PDO می‌توانید از فانکشن‌های Prepend برای جلوگیری از حملات SQL Injection استفاده نمایید.

<?php
try {
    $link = new \PDO('mysql:host=your-hostname;dbname=your-db;charset=utf8mb4',
    'your-username',
    'your-password',
        array(
            \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
            \PDO::ATTR_PERSISTENT => false
        )
    );

    $handle = $link->prepare('select Username from Users where UserId = ? or Username = ? limit ?');
    
    $handle->bindValue(1, 100, PDO::PARAM_INT);
    $handle->bindValue(2, 'Bilbo Baggins');
    $handle->bindValue(3, 5, PDO::PARAM_INT);
    $handle->execute();
    
    $result = $handle->fetchAll(\PDO::FETCH_OBJ);
    foreach($result as $row) {
        print($row->Username);
    }
} catch(\PDOException $ex) {
    print($ex->getMessage());
}
?>

۳. تگ شروع و پایان PHP
از تگ‌های <? ?> و یا <? =?> استفاده نکنید و بجای آن از شکل کامل <? php?> استفاده کنید. با اینکه شکل کوتاه راحت‌تر به نظر می‌رسد ولی بطور پیش‌فرض در تنظیمات PHP غیرفعال است و برای استفاده از آنها پارامتر short_open_tag باید فعال شود. همینطور ممکن است در سروری که از آن استفاده می‌کنید امکان فعال‌سازی این پارامتر وجود نداشته باشد.

حالت =?> بدون نیاز به فعال بودن short_open_tag کار می‌کند و برای استفاده از آن مشکلی وجود ندارد.

۴. استفاده از autoload
روش قدیمی autoload کردن کلاس‌هایی که لود نشده‌اند استفاده از فانکشن

function __autoload() {}

می‌باشد. مشکل در استفاده از این فانکشن آنجاست که اگر کتابخانه‌ای را وارد پروژه کنید که از این فانکشن استفاده می‌‌کند؛ در این صورت با تداخل (conflict) مواجه خواهید شد.
روش مناسب و صحیح در autoload کردن، تعیین نامی منحصربه‌فرد برای فانکشنی که کار autoload را در کد شما انجام می‌دهد و سپس ثبت آن در

spl_autoload_register()

است.

<?php
// First, define your auto-load function.
function MyAutoload($className) {
    include_once($className . '.php');
}

// Next, register it with PHP.
spl_autoload_register('MyAutoload');

// Try it out!
// Since we haven't included a file defining the MyClass object, our auto-loader will kick in and include MyClass.php.

// For this example, assume the MyClass class is defined in the MyClass.php file.
$var = new MyClass();
?>

۵. سینگِل‌کوتِیشِن در مقابل دابِل‌کوتِیشِن
در PHP سینگِل‌کوتِیشِن‌ها ( ' ) تجزیه (parse) نمی‌شوند، به این معنی که هر کاراکتری که بین آنها قرار دهید مستقیما چاپ می‌شود. در مقابل دابِل‌کوتِیشِن‌ها ( " ) تجزیه می‌شوند و این امکان را دارند تا متغیر بین آنها قرار گیرد. همینطور کاراکترهایی مانند n\ یا t\ در دابِل‌کوتِیشِن‌ها قابلیت اجرایی دارند.
دابِل‌کوتِیشِن‌ها در لحظه‌ی اجرای برنامه ارزیابی (evaluate) می‌شوند، در حالیکه سینگِل‌کوتِیشِن‌ها اینچنین نیستند و به همین دلیل سینگِل‌کوتِیشِن‌ها از نظر عملکرد بهتر هستند. معمولا این تفاوت در عملکرد، در نرم‌افزارهای بسیار بزرگ قابل لمس است و در اکثر پروژه‌ها تفاوتی بین آنها احساس نمی‌شود.

۶. استفاده از const در مقابل فانکشن define
تفاوت‌های const و define :
۱. ()define در زمان run time تعریف می‌شود درحالیکه const در زمان compile time. به همین دلیل const با کمی performance بهتر همراه است (که این موضوع در نرم افزارهای معمول به چشم نمی‌خورد).
۲. از ()define برای تعریف ثوابت در کلاس‌ها نمی‌توان استفاده کرد، همینطور ()define ثابت را در بلاکِ GLOBAL قرار می‌دهد.
۳. امکان استفاده از عملگرهای بیتی در ()define وجود دارد.
۴. از ()define در بلاک‌هایی مانند if می‌توان استفاده نمود درحالیکه از const نمی‌توان.

 <?php 
 // Let's see how the two methods treat namespaces
 namespace MiddleEarth\Creatures\Dwarves; 
 const GIMLI_ID = 1; 
 define('MiddleEarth\Creatures\Elves\LEGOLAS_ID', 2); 

echo(\MiddleEarth\Creatures\Dwarves\GIMLI_ID);  // 1
echo(\MiddleEarth\Creatures\Elves\LEGOLAS_ID);  // 2; note that we used define(), but the namespace is still recognized 
 
// Now let's declare some bit-shifted constants representing ways to enter Mordor. 
define('TRANSPORT_METHOD_SNEAKING', 1 << 0); // OK! 
const TRANSPORT_METHOD_WALKING = 1 << 1; // Compile error! const can't use expressions as values 

// Next, conditional constants. define('HOBBITS_FRODO_ID', 1); 
if($isGoingToMordor) { 
    define('TRANSPORT_METHOD', TRANSPORT_METHOD_SNEAKING); // OK!    
    const PARTY_LEADER_ID = HOBBITS_FRODO_ID // Compile error: const can't be used in an if block 
} 
    
// Finally, class constants 
class OneRing { 
    const MELTING_POINT_CELSIUS = 1000000; // OK!
    define('MELTING_POINT_ELVISH_DEGREES', 200); // Compile error: can't use define() within a class 
} 
?> 

عملا استفاده از ()define انعطاف بیشتری در برنامه‌نویسی به شما می‌دهد مگر اینکه بخواهید در کلاس‌های خود از ثابت استفاده کنید که در این صورت باید از const استفاده کنید. همینطور const خوانایی بیشتری به کدهای شما می‌دهد.

۷. عبارات با قاعده در PHP
در PHP دو روش برای کار با عبارات با قاعده (Regex) وجود دارد. PERL که فانکشن‌های آن با *_preg شروع می‌شوند و POSIX که فانکشن‌های آن با *_ereg شروع می‌شوند.
POSIX از نسخه 5.3 PHP منسوخ شد و به همین دلیل باید از خانواده *_preg استفاده نمایید.

۸. ارسال ایمیل در PHP
فانکشن ()mail از فانکشن‌های موجود در هسته‌ی PHP است که استفاده از آن مشکلات امنیتی دارد. به همین دلیل برای ارسال ایمیل باید از کتابخانه PHPMailer استفاده نمود. این کتابخانه‌ی متن‌باز بسیار محبوب بوده و در استفاده از آن نیازی به نگرانی در مورد مسائل امنیتی نیست.

<?php
// Include the PHPMailer library
require_once('phpmailer-5.2.7/PHPMailerAutoload.php');

// Passing 'true' enables exceptions.  This is optional and defaults to false.
$mailer = new PHPMailer(true);

// Send a mail from Bilbo Baggins to Gandalf the Grey
// Set up to, from, and the message body.  The body doesn't have to be HTML; check the PHPMailer documentation for details.

$mailer->Sender = 'bbaggins@example.com';
$mailer->AddReplyTo('bbaggins@example.com', 'Bilbo Baggins');
$mailer->SetFrom('bbaggins@example.com', 'Bilbo Baggins');
$mailer->AddAddress('gandalf@example.com');
$mailer->Subject = 'The finest weed in the South Farthing';
$mailer->MsgHTML('<p>You really must try it, Gandalf!</p><p>-Bilbo</p>');

// Set up our connection information.
$mailer->IsSMTP();
$mailer->SMTPAuth = true;
$mailer->SMTPSecure = 'ssl';
$mailer->Port = 465;
$mailer->Host = 'my smtp host';
$mailer->Username = 'my smtp username';
$mailer->Password = 'my smtp password';

// All done!
$mailer->Send();
?>

۹. اعتبارسنجی آدرس ایمیل
اغلب برنامه‌نویسان PHP از Regex هایی پیچیده برای بررسی اعتبار فرمت ایمیل‌ها استفاده می‌کنند. اما برای این اعتبارسنجی راه بسیار راحت‌تری وجود دارد.

<?php
filter_var('sgamgee@example.com', FILTER_VALIDATE_EMAIL); // Returns "sgamgee@example.com". This is a valid email address.
filter_var('sauron@mordor', FILTER_VALIDATE_EMAIL); // Returns boolean false! This is *not* a valid email address.
?>

منبع : phpbestpractices

ایدهٔ خود را در سکان‌پلاس بنویسید!

لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
کاربر میهمان
کاربر میهمانمن یک کاربر مهمان هستم
۱۳۹۷/۱۲/۱۶
سلام یک سوالی دارم
اینکه میگن OOP در پی اچ پی اصولی نیست یعنی چی. مثلا میگن که شیئ گرایی در این زبون اصلا به درست و حسابی بودن زبونی مثل روبی یا جاوا نیست
سپاس
کاربر میهمان
علویپورمن یک کاربر مهمان هستم
۱۳۹۷/۱۲/۱۱
عاشق پی اچ پی ام لطفا مطالب در مورد این زبان بیشتر بگذارید به خصوص در مورد چارچوبهای پی اچی پی مثل لاراول و ...
👏👏👏
کاربر میهمان
کاربر میهمانمن یک کاربر مهمان هستم
۱۳۹۷/۱۲/۰۳
آیا به نظرت الان فقط و فقط باید رفت رو نسخه 7 یا با ۵/۶ هم میشه کار کرد؟
masih it
masih it توسعه‌دهنده وب و علاقه‌مند به یادگیری ماشینی
۱۳۹۷/۱۲/۰۲
خیلی مفید بود برام. استفاده هم‌زمان از معادل فارسی و انگلیسی کلمات هم خوندن متن رو راحت‌تر میکرد. متشکر از مقاله خوبتون.
کاربر میهمان
علی سیگارودیمن یک کاربر مهمان هستم
۱۳۹۷/۱۲/۰۲
سلام
کاش یک آموزش در مورد یونیت تست در پی اچ پی مینوشنید
والا یک آموزش به درد بخور در فارسی پیدا نکردیم
کاربر میهمان
کاربر میهمانمن یک کاربر مهمان هستم
۱۳۹۷/۱۲/۰۱
من از این کتابخانه برای ارسال میل استفاده میکنم و راضی هستم
https://github.com/sparkpost/php-sparkpost
کاربر میهمان
حسینمن یک کاربر مهمان هستم
۱۳۹۷/۱۲/۰۱
سلام چند نکته در تکمیل نکاتی که گفتید
در مورد پسورد bcrypt هم هست. در ضمن استفاده از salt هم توصیه میشه
خوبی =? این هست که خودش echo رو داره
namespace هم استفاده ازش کار رو راحت میکنه
ثوابت؟؟؟ عجب جمع مکسری 😆😆😆