no-img
آرتیکلر

نکات مهم زبان برنامه نویسی PHP (بخش اول) برای برنامه نویسی تحت وب - آرتیکلر


آرتیکلر
کلاس ریاضی در رشت و بندرانزلی

ادامه مطلب

نکات مهم زبان برنامه نویسی PHP (بخش اول)


وبسایت آرتیکلر در این مقاله قصد دارد به بررسی نکات مهم و کاربردی PHP برای برنامه نویسی تحت وب در سطح مقدماتی که پیش‌نیاز آموزش‌های اندروید نیز هست بپردازد. این آموزش در چند بخش ارائه خواهد شد. شما همچنین میتوانید برای آموزش‌های بیشتر به سایت W3SCHOOLSمراجعه کنید.

نکات مهم زبان برنامه نویسی PHP

زبان برنامه نویسی php

زبان برنامه نویسی php

1. بهتر است از آدرس دهی Relative یا نسبی پرهیز کنید:

توصیه می شود بجای آن یک ثابت تعریف کنید که آدرس کامل/مطلق ROOT سایت شما را بیان می کند.

در زبان برنامه نویسی PHP خیلی وقت ها شده که کدهایی نظیر زیر را مشاهده کرده اید:

require_once('../../lib/some_class.php');

این روش کاستی های بسیاری دارد که در زیر شرح داده می شود:

این تابع ابتدا پوشه هایی را که در include path فایل تنظیمات php تعریف شده اند را جستجو می کند، سپس از پوشه ی جاری جستجو را ادامه می‌دهد.

به همین جهت بسیاری از پوشه ها مورد جستجو قرار می گیرند. زمانی که یک اسکریپت در پوشه ای دیگر، اسکریپت دیگری را دربرمی گیرد، آنگاه اسم پوشه ی پایه (base directory) اسکریپت دوم به اسکیرپت دربرگیرنده (اسکریپت اول) تغییر می یابد.

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

ممکن است پوشه ی والد یا میزبان خود را به عنوان پوشه ی فعال جاری (working directory) نداشته باشد.

از این جهت توصیه می کنیم همیشه path را به صورت کامل و absolute اعلان نمایید:

define('ROOT' , '/var/www/project/');
require_once(ROOT . '../../lib/some_class.php');
//rest of the code

 

حال این path یک آدرس کامل و absolute هست که همیشه ثابت باقی می ماند.

اما دستور فوق هنوز جای بهتر شدن دارد.

دایرکتوری /var/www/project می تواند تغییر کند.

آیا هر بار آن را تغییر می دهیم؟

خیر، بلکه با استفاده از magic constant ها (نظیر __FILE__) به این ثوابت قابلیت حمل (portable) را اعطا می کنیم (ثوابتی که با توجه به بستر جاری خود تغییر می کنند را magic constant گویند).

به نمونه ی زیر دقت کنید:

//suppose your script is /var/www/project/index.php
//Then __FILE__ will always have that full path.
define('ROOT' , pathinfo(__FILE__, PATHINFO_DIRNAME));
require_once(ROOT . '../../lib/some_class.php');
//rest of the code

حال زمانی که پروژه ی خود را به پوشه ی دیگری انتقال دهید.

برای مثال آن را به سرور آنلاین جابجا کنید، همان کد بدون هیچ گونه تغییری اجرا می‌شود.

2. در برنامه نویسی PHP از require، include، require_once یا include_once استفاده نکنید:

اسکریپت شما در می تواند فایل های مختلفی در بالای سلسله مراتب فایل ها داشته باشد.

برای مثال ممکن است class library، فایل هایی حاوی ابزار و توابع کمکی (utility function) نظیر ذیل در ابتدای ساختار سلسله مراتبی خود داشته باشد:

require_once('lib/Database.php');
require_once('lib/Mail.php');
require_once('helpers/utitlity_functions.php');

روش فوق کمی ابتدایی و ناکارامد است.

این کد را می توان به صورت منعطف و کاراتر تنظیم کرد.

می توانید تعدادی تابع کمکی تعریف کرده و با استفاده از آن ها (helper function) آسان تر به ابزار مورد نیاز دسترسی پیدا نموده و آن ها را پروژه بارگذاری نمایید:

  function load_class($class_name)
{
    //path to the class file
    $path = ROOT . '/lib/' . $class_name . '.php');
    require_once( $path );
}
load_class('Database');
load_class('Mail');

کد حاضر قطعا بهتر از نمونه ی قبلی عمل می کند.

هر چند می توانید به روش زیر آن را بهتر نمایید:

  
function load_class($class_name)
{
//path to the class file
$path = ROOT . ‘/lib/’ . $class_name . ‘.php’);
if(file_exists($path))
{
require_once( $path );
}
}

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

  • چندین فایل را جهت دستیابی به class file مورد نظر (یکسان) جستجو کرد.
  • پوشه ی دربردارنده ی class file ها را بدون اینکه کد دچار مشکل شود (بدون شکستن کد)، تغییر داد.
  • از توابع یکسان برای بارگذاری فایل هایی که دربردارنده ی توابع کمکی، محتوای html و غیره … هستند، استفاده کرد.

3. نگهداشت محیط خطایابی و اشکال زدایی (debug environment) در اپلیکیشن

در طول توسعه ی اپلیکیشن پیغام کوئری های دیتابیس را با دستور echo چاپ می کنیم.

متغیرهای مشکل زا را با تابع dump اشکال زدایی نموده (اطلاعاتی نظیر نوع و مقدار متغیر نمایش می دهد).

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

اما توصیه می شود که بگذارید همه چیز به شکل خود باقی بماند و در دراز مدت پروژه را تعمیر و نگهداری نمایید.

در دستگاهی که پروژه ی سایت (development machine) را می نویسید، می توانید به این صورت اقدام نمایید:

define('ENVIRONMENT' , 'development');
if(! $db->query( $query )
{
    if(ENVIRONMENT == 'development')
    {
        echo "$query failed";
    }
    else
    {
        echo "Database error. Please contact administrator";
    }   
}

در سمت سرویس دهنده (server) نیز می توانید کد زیر را بنویسید:

  
define('ENVIRONMENT' , 'production');
if(! $db->query( $query )
{
    if(ENVIRONMENT == 'development')
    {
        echo "$query failed";
    }
    else
    {
        echo "Database error. Please contact administrator";
    }   
}

 

4. منتشر کردن پیغام های مربوط به اطلاعات وضعیت (status message) با استفاده از (متغیر) session

Status message آن دسته از پیغام هایی هستند که پس از انجام یک task یا عملیات خاص تولید شده و اطلاعاتی در خصوص عملیات انجام شده ارائه می دهند.

<!--?php
if($wrong_username || $wrong_password)
{
    $msg = 'Invalid username or password';
}
?-->




<!--?php echo $msg; ?-->


...

کدهایی مانند نمونه ی فوق رایج هستند.

استفاده از متغیر برای ذخیره و نمایش status message ها چندان کارا نبوده و محدودیت های خود را دارد.

در واقع امکان ارسال متغیر از طریق redirect (زمانی که کاربر را به صفحه دیگری هدایت می کنید) وجود ندارد (مگر اینکه آن ها را از طریق متغیرهای GET به اسکریپت بعدی پاس دهید (propagate) که روشی ناکارامد تلقی می شود).

در اسکریپت های بزرگ ممکن است چندین پیغام تولید شود.

بهترین روش برای انتشار (propagate) پیغام ها، خواه بین صفحات مختلف و خواه داخل صفحه جاری، استفاده از متغیر session می باشد.

برای این منظور لازم است در هر صفحه یک تابع session_start وجود داشته باشد.

function set_flash($msg)
{
    $_SESSION['message'] = $msg;
}
function get_flash()
{
    $msg = $_SESSION['message'];
    unset($_SESSION['message']);
    return $msg;

در اسکریپت php شما:

<!--?php
if($wrong_username || $wrong_password)
{
    set_flash('Invalid username or password');
}
?-->




Status is : <!--?php echo get_flash(); ?-->
<form>
...
</form>

5. تعریف توابع انعطاف پذیر:

  
function add_to_cart($item_id , $qty)
{
    $_SESSION['cart'][$item_id] = $qty;
}
add_to_cart( 'IPHONE3' , 2 );

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

به کد زیر دقت نمایید:

function add_to_cart($item_id , $qty)
{
    if(!is_array($item_id))
    {
        $_SESSION['cart'][$item_id] = $qty;
    }
    else
    {
        foreach($item_id as $i_id => $qty)
        {
            $_SESSION['cart'][$i_id] = $qty;
        }
    }
}
add_to_cart( 'IPHONE3' , 2 );
add_to_cart( array('IPHONE3' => 2 , 'IPAD' => 5) );

اکنون تابع قادر است چندین ورودی متفاوت را دریافت کند.

با پیاده سازی روش فوق می توانید کد خود را بسیار سریع و کارا (agile) نمایید.

6. چنانچه تگ بسته ی php آخرین آیتم در اسکریپت جاری می باشد، آن را حذف کنید:

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

<!--?php
echo "Hello";
//Now dont close this tag
?-->

با این کار بسیاری از مشکلات اپلیکیشن شما برطرف می شود. به مثال زیر دقت کنید:

class file super_class.php:

<!--?php
class super_class
{
    function super_function()
    {
        //super code
    }
}
?-->
//super extra character after the closing tag

حال توجه خود را به کد index.php جلب نمایید:

require_once('super_class.php');
//echo an image or pdf , or set the cookies or session data

با این خطا مواجه می شوید: Headers already sent. چرا؟
به این خاطر که رشته ی “super extra character” قبلا چاپ (echo) شده و تمامی header ها همراه با آن ارسال شده اند.
حال فرایند خطایابی و اشکال زدایی را آغاز می کنید. ممکن است ساعت ها طول بکشد تا super extra space را پیدا کنید.

توصیه می شود همیشه تگ بسته ی php را حذف نمایید:

<!--?php
class super_class
{
    function super_function()
    {
        //super code
    }
}
//No closing tag
?php-->

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

7. تمامی خروجی ها را در یک مکان واحد جمع کرده و سپس آن ها را یکجا به مرورگر ارسال کنید:

این تکنیک در اصطلاح output buffering یا ذخیره خروجی ها در حافظه ی میانی خوانده می شود.

فرض کنید که محتوای مورد نظر را از توابع مختلف همچون ذیل به مرورگر (با تابع echo) ارسال می کنید:

  function print_header()
{
    echo "<div id="header">Site Log and Login links</div>";
}
function print_footer()
{
    echo "<div id="footer">Site was made by me</div>";
}
print_header();
for($i = 0 ; $i < 100; $i++)
{
    echo "I is : $i <br>';
}
print_footer();

بهتر است بجای استفاده از روش فوق، ابتدا تمامی خروجی ها را در مکانی واحد جمع آوری کنید.
حال این مقادیر خروجی را یا داخل متغیرهای موجود در توابع ذخیره می کنید و یا از ob_start و ob_end_clean به ترتیب جهت راه اندازی بافر و پاک کردن محتوای آن استفاده می نمایید.

با اعمال تغییرات مذکور، کد ظاهری مشابه زیر خواهد داشت:

function print_header()
{
    $o = "<div id="header">Site Log and Login links</div>";
    return $o;
}
function print_footer()
{
    $o = "<div id="footer">Site was made by me</div>";
    return $o;
}
echo print_header();
for($i = 0 ; $i < 100; $i++)
{
    echo "I is : $i <br>';
}
echo print_footer();

چرا باید از تکنیک output buffering استفاده کنید؟

  1. می توانید خروجی را قبل از ارسال به مرورگر ویرایش نمایید.
    برای مثال تعدادی مقادیر رشته ای را با استفاده از str_replaces جایگزین نمایید یا بر روی مقادیر پیش از ارسال به سرویس گیرنده، تابع preg_replaces را اجرا نمایید و یا مقداری کد html همچون profiler/debugger output به انتهای فایل اضافه نمایید.
  2.  توصیه نمی شود که خروجی (output) به مرورگر ارسال کرده و همزمان ورودی به کد سمت سرور php را پردازش نمایید.
    حتما قبلا با وب سایت هایی رو به رو شده اید که در کامپوننت نوار کناری (sidebar) وب سایت یا در کادری وسط صفحه خطای مهلک رخ می دهد.
    در شرح علت آن باید گفت که در چنین شرایطی پردازش ورودی و ارسال خروجی به مرورگر با هم تداخل پیدا می کنند و سبب رخداد خطا می شوند.

8. به هنگام ارسال خروجی حاوی محتوای غیر html از طریق header:

نوع یا فرمت مناسب (mime type) را برای فایل انتخاب نمایید.

در زیر مقداری محتوای xml را در خروجی چاپ (echo) می کنیم.

$xml = '<!--?xml version="1.0" encoding="utf-8" standalone="yes" ?-->';
$xml = "<response>
<code>0</code>
</response>";
//Send xml data
echo $xml;

گرچه این کد درست عمل می کند، با این حال می توان آن را بهینه سازی کرد:

  
$xml = '<!--?xml version="1.0" encoding="utf-8" standalone="yes" ?-->';
$xml = "<response>
<code>0</code>
</response>";
//Send xml data
header("content-type: text/xml");
echo $xml;

به خط مربوط به header در کد دقت نمایید.

آن خط به مرورگر اعلان می کند که محتوای فایل ارسالی xml است.

به همین جهت مرورگر قادر است محتوای آن را به درستی مدیریت کند.

بسیاری از کتابخانه های JavaScript به اطلاعات header احتیاج داشته و به آن وابستگی دارند.

این امر در مورد ارسال محتوای فایل های javascript، css، jpg image و png image به مرورگر نیز صادق است:

مثال javascript:

header("content-type: application/x-javascript");
echo "var a = 10";

مثال css:

header("content-type: text/css");
echo "#div id { background:#000; }";

 

9. تنظیم سیستم مناسب کد گذاری (character encoding) کاراکترها جهت ذخیره اطلاعات در دیتابیس mysql (اتصال به mysql):

تاکنون با شرایطی مواجه شده اید که کاراکترهای unicode/utf-8 در جدول دیتابیس mysql به درستی ذخیره شده و phpmyadmin نیز اطلاعات را صحیح نمایش می دهد.

با این حال زمانی که شما اطلاعات را واکشی کرده و در صفحه با echo چاپ می کنید، با فرمت صحیح نمایش داده نمی شوند.

مشکل اساسی در زبان تنظیم شده (collation) برای اتصال به mysql است.

$host = 'localhost';
$username = 'root';
$password = 'super_secret';
//Attempt to connect to database
$c = mysqli_connect($host , $username, $password);     
//Check connection validity
if (!$c)
{
    die ("Could not connect to the database host: <br>". mysqli_connect_error());
}       
//Set the character set of the connection
if(!mysqli_set_charset ( $c , 'UTF8' ))
{
    die('mysqli_set_charset() failed');
}

به هنگام اتصال به دیتابیس، توصیه می شود که character set یا مجموعه کاراکتر اتصال (connection) را مشخص نمایید.

این امر به ویژه زمانی که در اپلیکیشن با چندین زبان کار می کنید، یک ضرورت تلقی می شود.

در غیر این صورت با کادرهای متعدد و نوشته های نامفهوم به زبان دیگر، ????????، مواجه می شوید.

10. تابع htmlentities() را با پارامتر characterset مناسب فراخوانی نمایید:

ویرایش های قبل از php 5.4، از ISO-8859-1 به عنوان الگوریتم پیش فرض کدگذاری کاراکترها بهره می گرفتند.

این سیستم قادر به نمایش کاراکترهایی نظیر À â نبود.

$value = htmlentities($this->value , ENT_QUOTES , 'UTF-8');

در ویرایش بعدی php، سیستم کدگذاری مورد استفاده به صورت پیش فرض، UTF-8 می باشد که بیشتر مشکل های مزبور را برطرف می سازد.

با این وجود بهتر از این حقیقت آگاه باشید به خصوص اگر سایت شما چند زبانه می باشد.

این بخش اولین بخش از یادگیری نکات مهم  برنامه نویسی PHP ، است.

امیدواریم این مطلب برای شما مفید واقع شده باشد.

به این مطلب امتیاز دهید!
[تعداد رای: 1 میانگین رای: 5]


موضوعات :

مطالب مرتبط


دیدگاه ها


دیدگاه‌ها بسته شده‌اند.