PDA

توجه ! این یک نسخه آرشیو شده میباشد و در این حالت شما عکسی را مشاهده نمیکنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : آموزش ساخت يك سيستم وبلاگ دهي



Rezash
July 18th, 2010, 23:20
در اين آموزش قصد دارم در چند مرحله نحوه ساخت يك سيستم وبلاگ دهي رو توضيح بدم.دقت كنيد كه پروژه در رده مقدماتي – متوسط و پيشرفته هست!در واقع از سطح مقدماتي شروع مي كنيم و به بالاتر پيش ميريم.موارد و نكات امنيتي رو در حين كد نويسي ها سعي مي كنم توضيح بدم اما به خاطر اينكه پروژه پيچيده نشه به نكات ابتدايي اكتفا مي كنيم.
توجه كنيد كه اين يك سيستم وبلاگ دهي واقعي نيست(به دليلي سادگي زياد!)!بلكه فقط يك پروژه عملي هست براي افزايش توانمندي مخاطب در برنامه نويسي هست.در واقع ميشه اسمش رو mini blogger بذاريم :d
ملزومات: آشنايي مقدماتي با php و mysql
قسمت اول :
ابتدا يك ديتابيس جديد ميسازيم:

CREATE DATABASE `blogdehi` ;

ساخت جداول :


1. جدول اعضا



CREATE TABLE `blogdehi`.`users` (
`id` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`password` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`email` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`name` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci

دستورات اس كيو ال رو توضيح نمي دم و پيش فرض رو بر اين ميذارم كه با اين دستورات آشنا هستيد.اگر كسي با دستورات مشكل داشت مي تونه از php my admin كمك بگيره
به ازاي هر عضو در سيستم ما قرار هست يك ركورد به جدول اضافه بشه.
هر كاربر داراي يك شناسه (id) از نوع عدد صحيح (int) هست كه بايد منحصر به فرد باشه و براي همين اون رو از AUTO_INCREMENT و PRIMARY KEY تعريف كردم.اين كار باعث ميشه در ارتباط بين جداول،جتسجو و جلوگيري از افزونگي داده ها كمك شاياني بشه.
اطلاعات بيشتر:
Unique key - Wikipedia, the free encyclopedia (http://en.wikipedia.org/wiki/Unique_key)
Unique key - Wikipedia, the free encyclopedia (http://en.wikipedia.org/wiki/Primary_key)
نام كاربري،رمز عبور،پست الكترونيك و نام كاربر رو هم از نوع رشته (varchar) در نظر گرفتم.
جدول وبلاگ ها:
مي تونستيم همون نام كاربري رو به عنوان نام وبلاگ هم در نظر بگيريم ، اما فرض كنيم مثل برخي سيستم هاي وبلاگ دهي ميخواهيم كاري كنيم كه يك كاربر بتونه چند وبلاگ داشته باشه..البته براي اينكه آموزش پيچيده نشه و بخش مديريت پيچيده تري هم نداشته باشيم فعلا پيش فرض رو بر يك وبلاگ مي ذاريم.
اين جدولمون بايد شامل ، شناسه وبلاگ،شناسه صاحب وبلاگ،آدرس وبلاگ،عنوان وبلاگ،توضيحات وبلاگ،كلمات كليدي وبلاگ باشد.


CREATE TABLE `blogdehi`.`blogs` (
`blogid` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`uid` INT( 5 ) NOT NULL ,
`blog` VARCHAR( 255 ) NOT NULL ,
`title` INT( 255 ) NOT NULL ,
`description` TEXT NOT NULL ,
`keys` VARCHAR( 255 ) NOT NULL
) ENGINE = InnoDB CHARACTER SET ucs2 COLLATE ucs2_general_ci

خب اين جدول هم مثل جدول قبل هست و توضيح خاصي نياز نداره...
جدول قالب ها :
هر وبلاگ داراي يك قالب منحصر به فرد هست كه به صورت پيش فرض نمايش داده ميشه و تعدادي قالب پيش فرض كه كاربر مي تونه يكي رو براي وبلاگش انتخاب كنه.
بنابراين جدولي داراي چنين مشخصاتي مي سازيم:
شناسه قالب : شناسه عددي منحصر به فرد براي قالب
شناسه وبلاگ صاحب قالب،
وضعيت قالب : يك عدد كه نشون مي ده قالب فعلي قالب پيش فرض ما هست،يا قالبي هست كه مي تونه توسط بازديد كننده انتخاب بشه (مثل كمبو باكس تغيير قالب در پايين بعضي انجمن ها)، يا يك قالب هست كه در آرشيو نگه داري ميشه.
كد قالب : كه شامل كد HTML و Javascript تگ گذاري شده قالب هست.


CREATE TABLE `blogdehi`.`template` (
`tmpid` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`blogid` INT( 5 ) NOT NULL ,
`active` INT( 1 ) NOT NULL ,
`code` TEXT NOT NULL
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci

جدول مطالب :
شامل شناسه مطلب،شناسه وبلاگ صاحب مطلب،شناسه نويسنده مطلب،عنوان مطلب،شناسه موضوع مطلب،تاريخ مطلب،متن مطلب،متن ادامه مطلب مي باشد.


CREATE TABLE `blogdehi`.`data` (
`postid` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`uid` INT( 5 ) NOT NULL ,
`blogid` INT( 5 ) NOT NULL ,
`title` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`text` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`fulltext` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`cat` INT( 5 ) NOT NULL ,
`date` TIMESTAMP NOT NULL
) ENGINE = InnoDB

جدول موضوعات وبلاگ ها:
شامل شناسه موضوع،شناسه وبلاگ صاحب موضوع،عنوان موضوع مي باشد.


CREATE TABLE `blogdehi`.`cat` (
`catid` INT( 5 ) NOT NULL ,
`blogid` INT( 5 ) NOT NULL ,
`title` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
) ENGINE = InnoDB

جداول ديگري هم مثل جدول مديريت، لينك ها و ... هست كه اگر در حين توضيح پروژه فرصتي براي گسترشش داشتم به پروژه اضافه مي كنم.تا الان هم جزييات زياد اضافي رو وارد برنامه كردم فقط به خاطر اينكه جذاب تر بشه!وگرنه پيچيده گي كار رو بالاتر مي بره.
اميدوارم جدول لازمي از قلم نيوفتاده باشه و اگه افتاده باشه بعدا اضافه مي كنم.
فعلا خودم خسته شدم! (:|و براي اينكه آموزش هم خسته كننده نشه شروع كد نويسي رو به جلسات بعدي موكول مي كنم.
نكته مورد اهميت اين پروژه اينه كه قصد دارم در اين پروژه از به كارگيري HTML در كدهاي PHP خودداري كنم.برنامه رو شي گرا نمي نويسم تا ساده تر باشه اما به تعدادي function كاربردي تبديلش مي كنم.
سپاس

rn4j1m1
July 18th, 2010, 23:45
ممنون
فقط سعی کنید بیشتر توضیح بدید که برای دوستانی که در حال آمورش php هستن بیشتر جنبه آموزشی داشته باشه

Rezash
July 18th, 2010, 23:55
ممنون
فقط سعی کنید بیشتر توضیح بدید که برای دوستانی که در حال آمورش php هستن بیشتر جنبه آموزشی داشته باشه
بخش ديتابيس رو زود از روش گذشتم، ولي php رو از پايه شروع مي كنم،خوشبختانه persiasoft هم آموزش پي اچ پي رو گذاشته و مقدمه كار براي علاقه مندان آمادست و منم سعي مي كنم آموزش ها رو به صورت عملي به كار ببرم وخوشحال ميشم شما دوستان با تجربه هم در حين كار نظرات خودتون رو بگيد تا هم بقيه و هم من استفاده كنيم :)

Rezash
August 1st, 2010, 10:19
آموزش ساخت سيستم وبلاگ دهي - قسمت دوم
و بالاخره قسمت دوم آموزش!ببخشيد دير شد ولي نخواستم با عجله و سريع باشه...
در بخش قبل پايگاه داده رو ايجاد كرديم،در اين قسمت آغاز به شروع كد نويسي مي كنيم.البته شخصا ترجيح ميدم براي ارتباط با پايگاه داده از كلاس هايي كه قبلا نوشتم يا نوشته شده استفاده كنم اما به دليل اهميت آموزش از دستورات و توابع پيش فرض استفاده مي كنم.
مزيت استفاده از كلاس هاي آماده و حرفه اي اين هست كه تا حدود زيادي كار كد نويسي رو آسون مي كنه و به علاوه در اكثر اين كلاس كوئري ها قبل ارسال چك ميشوند و از لحاظ امنيتي مشكلي براي سيستم پيش نمياد.
بذاريد كليت سيستم رو اينجوري خلاصه كنم.ابتدا ما سرور رو طوري تنظيم مي كنيم كه درخواست هاي ساب دومين به صورت زير تبديل بشند.(منظورم همون ساب دومين مجازي هست.)

blogname.domain.com = > domain.com/blog.php?user=blogname
نحوه انجام اين كار رو بعدا توضيح مي دم (هر چند قبلا در انجمن به دفعات ذكر شده!) ، و لزوما هم نياز به سرور اختصاصي نيست و با هاست اشتراكي هم ميشه اين كار رو كرد به خصوص اگه سي پنل نصب باشه كه ا ز همه آسون تر هست.
پس تا اينجا ما username رو به برنامه ارسال مي كنيم، از اينجاست كه كار برنامه نويسي ما آغاز ميشه.
حالا در برنامه usernmer رو داريم و اطلاعاتي از ديتابيس رو بيرون ميكشيم كه مربوط به اين يوزر باشه و نمايش ميديم...
---
شروع كد نويسي:
از بخش تنظيمات اتصال به ديتابيس شروع مي كنم. براي اتصال به ديتابيس بايد از تابع mysql_connect استفاده كنيم.
mysql_connect : اين تابع سه آرگومان (ورودي) اجباري مي گيرد که اولي نام هاست،دومي نام کاربري ديتا بيس و سومي کلمه عبور ديتا بيس مي باشد.
mysql_select_db : ديتابيس شما را با توجه به اطلاعات داده شده در مرحله قبل انتخاب مي کند تا بتواني عملياتي مانند نوشتن،خواندن،حذف و ... را انجام بديد.
مثال :


<?php
$hostname='localhost';
$user='root';
$pass='';
$db='miniblog';
$connect = mysql_connect($hostname, $user, $pass);
mysql_select_db($db,$connect) or die ("Could not select database");
?>

اطلاعات بيشتر در مورد اين توابع مثل ورودي هاي اختياري ضرورتي نداره و از روشون مي گذرم.فقط تنها نكته مهم در اينجا تابع mysql_connect هست كه عمليات اتصال ،mysql_select_db انتخاب يك ديتا بيس مي باشد.
نكته امنيتي : در هنگام ايجاد يك ديتابيس در كنترل پنل يا هرجا، و دادن سطح دسترسي به كاربري كه به ديتابيس متصل ميشه دقت كنيد و از دادن اختيارات اضافي به كاربر جز در مرحله install براي ساخت جداول خودداري كنيد...دليل اين كار اينه كه اگر در جايي از برنامه مشكل امنيتي داشته باشيم و كاربر بتونه sql_injection بزنه ، خيلي دست و پاگير تر هست وقتي نتونه index،drop و ... بكنه ...
عموما دادن چهار ويژگي delete,update,insert,select براي يك كاربر كافي هست.
حتي در مورد سيستم هايي كه قرار نيست ديتا توسط كاربر نوشته بشه ، ميتونيم براي بخش كاربري از يك نام كاربري براي اتصال به ديتابيس استفاده كنيد و براي بخش مديريت از يك نام ديگه با سطح دسترسي بيشتر. و حتي اگه بخش مديريت شخصي باشه ميتونيم با htaccess كل بخش مديريت رو رمز گذاري كنيم.
البته رعايت اصول پايه كفايت مي كنه ولي بزرگترين تيم هاي برنامه نويسي دنيا هم تاحالا اشتباهات كوچك و بزرگي داشته اند ...
در بخش تنظيمات من 4 متغير براي تنظيمات ديتابيس اعمال كردم ولي بهتر هست اين تنظيمات به صوت يك آرايه باشند.
بنابراين با توجه به آموزش "http://www.webhostingtalk.ir/f148/%D8%A2%D8%B1%D8%A7%DB%8C%D9%87-%D9%87%D8%A7-%D8%AF%D8%B1-php-13562/ " من كدم رو به صورت زير اصلاح مي كنم:


<?php
$database = array(
'hostname'=>'localhost',
'user'=>'root',
'pass'=>'mysql',
'db'=>'miniblog',
);
$connect = mysql_connect($database['hostname'], $database[' user'], $database['pass']);
mysql_select_db($$database['db'],$connect) or die ("Could not select database");
?>

فايل زبان:
يكي ازمشكلات برخي از editor ها،پشتيباني نكردن از UTF هست.مدتي editor محبوب من از UTF پشتيباني نمي كرد(ورژن هاي اوليه) و من رو مجبور كرد كلا فارسي نويسي رو در PHP كنار بگذارم و فايل زبان ايجاد كنم!
ايجاد يك فايل زبان به ما اين امكان رو مي ده كه در آينده به راحتي پيغام ها رو عوض كنيم،با مشكلات UTF در editor هاي تحت ويندوزو يا كنترل پنل و ... كنار بيايم...در واقع كافي هست يك فايل رو UTF ذخيره كنيم و در بيقه جاها استفاده كنيم.
بعلاوه ما اين امكان رو داريم كه براحتي سيستممون رو با افزودن چند خط كد چند زبانه كنيم.
در اينجا فايل زبان رو با آرايه و به صورت زير تعريف م كنم و بعدا هر زمان كه بخوايم محتوياتش رو طول آموزش مي نويسيم.


<?php
//lang.fa.php
$lang = array(
'done'=>'عمليات با موفقيت انجام شد.',
'blog_created'=>'وبلاگ شما با موفقيت ايجاد شد.',
);
?>

جدا بودن PHP از HTML:
شخصا اصلا دوست ندارم در كدهاي PHP از HTML استفاده كنم! سختي در ويرايش،عيب يابي ، تعويض قالب،سر در گمي در طول نوشتن برنامه،احتمال بروز خطا و اشتباه،ناخوانا شدن كد و ... از مشكلات استفاده تركيبي از اين دو در يك برنامه هست!
كلاس ها و برنامه هاي متعددي براي اين كار نوشته شده اند ولي در اينجا من كلاسي كه خودم هميشه ازش استفاده مي كنم،رو به كار مي برم.
البته به توضيح اين كلاس نمي پردازم چون سطح ش بالاتر از آموزش هست و فقط از اون استفاده مي كنيم!ولي به تدريج كه جلوتر رفتيم در بخش نمايش وبلاگ با توجه به تگ گذاري خودمون كدها رو مي نويسيم و يك كلاس جديد براي نمايش قالب وبلاگ و درج محتوا در اون مي نويسم.
اين بخش رو بزودي ارسال مي كنم.(زودتر از اين قسمت :D)
در مراحل ابتدايي آموزش مجبور هستم بيشتر حرف بزنم تا كد نويسي...ولي خب براي راه افتادن پروژه لازم هست...بزودي آموزش هاي جانبي مانند توابع مورد نياز مانند mail،انواع كوئري ها رو هم در اين بخش ارسال مي كنم(اگر قبلا ارسال نشده باشند!) تا مقدمات كار وجود داشته باشه...
سپاس

Rezash
August 6th, 2010, 20:34
البته انتظار داشتم استقبال بيشتري از اين آموزش ها بشه،نوشتن هر بخش آموزش چند ساعت وقت ميبره...
توي فروم با تعداد يوزر شايد حتي 1 صدم اينجا حداقل 7-8 نفر آموزش رو دنبال مي كنند ولي متاسفانه اينجا تقريبا فقط كساني استقبال كردند كه خودشون برنامه نويس حرفه اي php هستند و نيازي به اين آموزش ها ندارند!
بهر حال قسمت بعدي رو تا فردا شب قرار مي دم.
قسمت بعدي شامل يك آموزش مختصر از كار با كلاس هاي قالب براي جدا سازي كدهاي html و php از همديگه هست.،و توضيحات بخش ساخت ناحيه كاربري كه اگه خيلي طولاني نشه ثبت نام،ورود و پنل كاربري رو توضيح مي دم.

Rezash
August 26th, 2010, 17:12
در اين بخش قصد دارم استفاده از يك كلاس قالب رو توضيح بدم . اين كلاس رو مدت ها پيش از يك سايت ايراني (rightclick.ir) پيدا كردم كه گويا از يك شمارنده آلماني كپي برداري شده.
در اين مرحله فقط و فقط به توضيح استفاده از كلاس مي پردازيم و از توضيح بدنه كلاس خو دداري ميكنم!
ابتدا يك جمع بندي از جلسات قبل :
- ساختار ديتابيس رو بررسي كرديم
- فايل config.php و lang.php رو ساختيم
* فايل پيوست شامل تمام كدهاي استفاده شده تا الان ، + يك قالب ساده كه طراح اصليش كار آقاي محمد اميري (مدير سابق جاست پرشين) مي باشد.
اول کد کلاس رو ببينيد:


<?php
class Template
{
var $tags = array();
var $required_tags = array();
var $blocks = array();
var $tpl = '';
var $parsed_tpl = '';

function Template( $templatefile = '' )
{
if( !empty( $templatefile ) )
{
if( !file_exists( $templatefile ) )
{
print 'Could not find the template file <i>'. $templatefile ."</i>!\n";
return FALSE;
}
$this->load_file( $templatefile );
}
return TRUE;
}

/*-----------------------------------------------------------------*/

function load_template( $template )
{
$this->tpl .= $template;
}

/*-----------------------------------------------------------------*/

function load_file( $file )
{
if( empty( $file ) )
{
return FALSE;
}

$template = @implode( '', @file( $file ) );
if( $template == FALSE )
{
print 'Could not read the template file!';
return FALSE;
}
$this->tpl .= $template;
}

/*-----------------------------------------------------------------*/

function assign( $input, $value = '', $required = FALSE )
{
if( is_array( $input ) )
{
foreach( $input as $tag => $value )
{
if(empty( $tag ) )
{
print 'Tag name ist empty!';
return FALSE;
}
if( $required == TRUE )
{
$this->required_tags[$tag] = $value;
}
else
{
$this->tags[$tag] = $value;
}
}
}
elseif( is_string( $input ) )
{
if( empty( $input ) )
{
print 'Tag name ist empty!';
return FALSE;
}
else
{
if( $required == TRUE )
{
$this->required_tags[$input] = $value;
}
else
{
$this->tags[$input] = $value;
}
}
}
else
{
return FALSE;
}
return TRUE;
}

/*-----------------------------------------------------------------*/

function add_block($block_name, $block_array)
{
if( !is_string($block_name) || empty($block_name))
{
print 'Block name is not a string or is empty!';
return FALSE;
}
if( !is_array($block_array))
{
print 'Block array is not an array!';
return FALSE;
}
$this->blocks[$block_name][] = $block_array;
}

/*-----------------------------------------------------------------*/

function parse()
{
if( empty( $this->tpl ) )
{
return;
}

# blocks
$tmp_blocknames = array();
foreach( $this->blocks as $block_name => $block_arrays )
{
if( $anzahl = preg_match_all( '/<!-- BEGIN BLOCK '. preg_quote( $block_name, '/' ) .' -->(.*)<!-- END BLOCK '. preg_quote( $block_name, '/' ) .' -->/sU', $this->tpl, $matches ) )
{
for( $i = 0; $i < $anzahl; $i++ )
{
$block_plus_definition = $matches[0][$i];
$block = $matches[1][$i];

if( is_int( strpos( $block, '<!-- IF' ) ) )
{
$parse_control_structures = TRUE;
}

$parsed_block = '';
foreach( $block_arrays as $block_array )
{
$tmp = $block;
if( isset( $parse_control_structures ) )
{
$tmp = $this->_parse_control_structures( $tmp, array_merge( $block_array, $this->tags, $this->required_tags ) );
}
foreach( $block_array as $tag_name => $tag_value )
{
$tmp = str_replace( '{'.$tag_name.'}', $tag_value, $tmp );
}
$parsed_block .= $tmp;
}
$this->tpl = str_replace( $block_plus_definition, $parsed_block, $this->tpl );
$tmp_blocknames[] = $block_name;
unset( $parse_control_structures );
}
}
}
if( count( $this->blocks ) > 0 )
{
$this->tpl = preg_replace( "/<!-- (BEGIN|END) BLOCK (". implode( '|', $tmp_blocknames ) .") -->/", '', $this->tpl );
}

# unbenutze blِcke entfernen
$this->tpl = preg_replace( "/<!-- BEGIN BLOCK ([a-zA-Z0-9_-]+) -->.*<!-- END BLOCK \\1 -->(\r\n|\r|\n)?/msU", '', $this->tpl );

# single tags
foreach( $this->required_tags as $tag_name => $tag_value )
{
if( !is_int( strpos( $this->tpl, $tag_name ) ) )
{
print 'Could not find tag <i>'.$tag_name.'</i> in the template file!';
return FALSE;
}
else
{
$this->tpl = str_replace( '{'.$tag_name.'}', $tag_value, $this->tpl );
}
}
foreach( $this->tags as $tag_name => $tag_value )
{
$this->tpl = str_replace( '{'.$tag_name.'}', $tag_value, $this->tpl );
}

# if & else
$this->tpl = $this->_parse_control_structures(
$this->tpl,
array_merge( $this->tags, $this->required_tags ),
$this->blocks
);


$this->parsed_tpl = $this->tpl;
$this->tpl = '';
}

/*-----------------------------------------------------------------*/

function print_template()
{
if( !empty( $this->tpl ) )
{
$this->parse();
}
print $this->parsed_tpl;
}

/*-----------------------------------------------------------------*/

function get_tpl_as_var()
{
if( !empty( $this->tpl ) )
{
$this->parse();
}
return $this->parsed_tpl;
}

/*-----------------------------------------------------------------*/

function free()
{
$this->tpl = '';
$this->parsed_tpl = '';
$this->tags = array();
$this->required_tags = array();
$this->blocks = array();
}

/*-----------------------------------------------------------------*/

function _parse_control_structures( $tpl, $vars, $blocks = array() )
{
if( $matchnumber = preg_match_all( '/<!-- IF (!?)((BLOCK )?)([_a-zA-Z0-9\-]+) -->(.*)((<!-- ELSEIF !\(\\1\\2\\4\) -->)(.*))?<!-- ENDIF \\1\\2\\4 -->/msU', $tpl, $matches ) )
{
for( $i = 0; $i < $matchnumber; $i++ )
{
//print( $matches[8 ][$i] . '<br />');
if( !empty( $matches[2][$i] ) )
{
$code = 'if( '.$matches[1][$i].'isset($blocks[\''.$matches[4][$i].'\']) )'."\n";
}
else
{
$code = 'if( '.$matches[1][$i].'( isset($vars[\''.$matches[4][$i].'\']) ) )'."\n";
}
$code .= '{ $tpl = str_replace( $matches[0][$i], $this->_parse_control_structures( $matches[5][$i], $vars, $blocks ), $tpl ); }'."\n";
$code .= ' else '."\n";
$code .= '{ $tpl = str_replace( $matches[0][$i], !empty($matches[7][$i]) ? $this->_parse_control_structures( $matches[8][$i], $vars, $blocks ) : \'\', $tpl ); }';
eval( $code );
}
}
return $tpl;
}
}
?>

خوب اول طرض استفادش:
براي اين کار يه مثال ميزنم
فرض کنيد کد بالا رو توي يه فايل به نام Template.php ذخيره کرديم و يه فايل به نام index.php داريم که برنامه اصليمون هست و يه Folder به نام Tpls داريم که تمامي قالب هامون توي اونه، فعلا يه قالب به نام body.html داريم.

گام اول- محتويات فابل index.php :



<?php

include('Template.php');

$MyTpl = new Template();
$MyTpl -> load_file( 'Tpls/body.html' );

$MyTpl -> print_template();

?>


و محتواي body.html:


<html>
<head></head>
<body>

<p align="left">
Name:
<font color="#0000FF">
<b>
Ahmad
</b>
</font>
</p>

</body>
</html>


توضيح گام اول:
در کل يه فايل template رو باز مي کنيم و اونو نمايش مي ديم.
body.html که يه صفحه ساده HTML هست.
توي index.php خط اول که فايل حاوي کلاس Template رو include کرديم.
خط بعد يه Object جديد از اين کلاس رو تعريف کرديم با نام MyTpl :

$MyTpl = new Template();
خط بعد فايل قالب رو Load کرديم:

$MyTpl -> load_file( 'Tpls/body.html' );


دقت کنيد که نام و پسوند فايل قالب اصلا مهم نيست چي باشه. من براي راحتي پسوندش رو HTML گرفتم.

خط بعد کل قالب رو چاپ کرديم:

$MyTpl -> print_template();
خوب اين از گام اول بريم سراغ گام بعد...
ما قالب ها رو مي سازيم که کد HTML رو از کد PHP جدا کنيم و کارمون تميزتر باشه. ولي بايد بتونيم توي قالب تغييرات ايجاد کنيم.

توي اين کلاس چيزهايي که توي کد HTML مربوط به قالب با داده هاي توليد شده در کد PHP جايگزين مي شوند بين {} قرار مي گيرند. مثل قالب وبلاگ ها که چيزايي مثل اين دارند <**> ، <##> ، [] , ...

مثال:
محتويات body.html:

<html>
<head></head>
<body>

<p align="left">
Name:
<font color="#0000FF">
<b>
{TheVarName}
</b>
</font>
</p>

</body>
</html>
در اينجا TheVarName که در ميان {} قرار گرفته است در کد php با داده توليد شده جايگزين مي شه. توجه کنيد که اين کلاس به حروف بزرگ و کوچک حساس است.

کد index.php:

<?php

include('Template.php');

$MyTpl = new Template();
$MyTpl -> load_file( 'Tpls/body.html' );

if( 1 > 2 )
{

$Name = 'Ahamad';

} else {

$Name = 'Mohsen';

}

$MyTpl -> assign( 'TheVarName' , $Name );

$MyTpl -> print_template();

?>
خوب همون طور که مي بينيد يه خط جديد داريم:

$MyTpl -> assign( 'TheVarName' , $Name );


با صدا زدن اين Method توي قالب Load شده هر جا که {TheVarName} ديد اون رو با محتويات متغير Name جايگزين مي کنه.
اگه چند تا متغير داشتيم مي تونيم اين Method رو چند بار Call کنيم ولي يه راه ساده تر هم هست و اون اينه که ورودي آرايه بهش بديم اين طوري:

محتويات body.html:

<html>
<head></head>
<body>

<p align="left">
First name:
<font color="#0000FF">
<b>
{FrstName}
</b>
</font>
</p>
<p align="left">
Last name:
<font color="#0000FF">
<b>
{LstName}
</b>
</font>
</p>

</body>
</html>
محتويات index.php:

<?php

include('Template.php');

$MyTpl = new Template();
$MyTpl -> load_file( 'Tpls/body.html' );


$FName = 'Maryam';
$LName = 'Hamedi';

$NamesArray = array( 'FrstName' => $FName, 'LstName' => $LName);

$MyTpl -> assign( $NamesArray );

$MyTpl -> print_template();

?>
معمولا براي راحتي آرايه رو مستقيما توي ورودي Method تعريف مي کنيم و به يه شکل تميز تر مي نويسيم. براي اين که توي متغير هاي زياد قاطي نکنيم يعني اين طوري:

$FName = 'Maryam';
$LName = 'Hamedi';

$MyTpl -> assign( array(

'FrstName' => $FName,
'LstName' => $LName

)
);
//End of assign template vars -->
گام بعد- IF در قالب.
بعضي وقتا مي خواييم با توجه به شرايطي قسمت هايي از قالبتون نمايش داده نشه. مثال:
کد قالب:

<html>
<head></head>
<body>

<p align="left">
First name:
<font color="#0000FF">
<b>
{FrstName}
</b>
</font>
</p>

<!-- IF LstNameCond -->

<p align="left">
Last name:
<font color="#0000FF">
<b>
{LstName}
</b>
</font>
</p>

<!-- ENDIF LstNameCond -->

</body>
</html>
توي کد قالب به <!-- IF LstNameCond --> و <!-- ENDIF LstNameCond --> دقت کنيد که يک شرط رو بيان مي کنند LstNameCond عنوان دلخواهي براي شرط هست. خوب کد php:

$MyTpl -> assign( array(

'FrstName' => $FName,
'LstName' => $LName,
'LstNameCond' => 1

)
);
//End of assign template vars -->
طبق شرط بالا محتويات ميان IF نمايش داده مي شوند. توجه کنيد که به جاي عدد 1 هرچيز ديگري مي تواند باشد حتي 0 يا false، اما براي عدم نمايش کافيه که توي ليست assign نباشه. مثل اين:

$MyTpl -> assign( array(

'FrstName' => $FName,
'LstName' => $LName,
//'LstNameCond' => 1

)
);
//End of assign template vars -->
گام بعد- تکرار کد HTML.
فک کنم مهمترين قسمت اينجا باشه که ما مي خواهيم يه تعداد داده رو با قالب يکسان زير هم چاپ کنيم. براي اين کار به کد زير توجه کنيد:
کد قالب:

<html>
<head></head>
<body>

<p align="left">
#-
Name
</p>

<!-- BEGIN BLOCK MyBlock -->

<p align="left">
{Row}-
<b>
{Name}
</b>
</p>

<!-- END BLOCK MyBlock -->

</body>
</html>

توي اين کد هم دوقسمت به نام هاي <!-- BEGIN BLOCK MyBlock --> و <!-- END BLOCK MyBlock --> به چشم مي خوره ... هر چي بين اين دو Tag باشه تکرار مي شه مثل وبلاگ ها که براي نمايش پست ها معمولا اسم خود سرويس دهنده وبلاگ رو مي ذارن. MyBlock نام اين قسمت هست که دلخواهه.

کد php:

<?php

include('Template.php');

$MyTpl = new Template();
$MyTpl -> load_file( 'Tpls/body.html' );


$Names = array( 'Ali', 'Morteza', 'Javad' , 'Maryam', 'Ehsan' , 'Fatemeh' , 'Ahmad');
$TotalRecords = count( $Names);

for( $Index = 0 ; $Index != $TotalRecords ; $Index++ )
{
$MyTpl -> add_block('MyBlock', array(

'Row' => $Index + 1,
'Name' => $Names[ $Index ],

)
);
//End of assign template vars -->
}

$MyTpl -> print_template();

?>


براي اين که پيچيده نشه پاي DataBase رو وسط نکشيدم. فرض کنيد داده هاي ما توي آرايه Names هست و تعداد Record هامون هم توي TotalRecords هست. به ازاي هر تکرار داده بايد متد add_block رو صدا بزنيم و همين طور که مي بينيد داده ها رو بهش اختصاص بديم.

نکات قابل توجه:
1- ما ميتونيم مستقيما کدهاي HTML توليد شده رو چاپ نکنيم ... مثلا شايد بخواييم براي خبرناممون يه قالب داشته باشيم و اين رو بايد Mail کنيم. براي اين کار يه Method ديگه وجود داره که محتواي توليد شده رو بر مي گردونه:

$HtmlCode = $MyTpl -> get_tpl_as_var();


2- ما به هر تعداد که بخواييم مي تونيم قالب Load کنيم. يعني متد load_file رو مي تونيم به هر تعداد براي قالب هاي مختلف Call کنيم، تمام قالب ها مثل رشته اي پشت سر هم قرار مي گيرند.
کاربرد: براي جاهايي استفاده مي شه که مثلا شما يه Header و Footer ثابت داريد و فقط قسمت وسط صفحه عوض مي شه، مثل همين صفحه انجمن. مثال:

<?php

include('Template.php');

$MyTpl = new Template();
$MyTpl -> load_file( 'Tpls/Header.html' );

...

switch ( $Action)
{

case 'Login': $Page = 'Login.html'; break;

case 'Logout': $Page = 'Logout.html'; break;

case 'Contacts': $Page = 'Contacts.html'; break;

case 'ContactsSent': $Page = 'ContactsSent.html'; break;

default $Page = 'Index.html';

}

$MyTpl -> load_file( 'Tpls/' . $Page ); //Load the Body of page

...

$MyTpl -> load_file( 'Tpls/Footer.html' );
$MyTpl -> print_template();

?>

فقط توي اين قسمت بايد دقت کنيد که چون اين صفحات پشت سر هم مي آيند توي کد هاي HTML قاطي نشه که از تگ هاي HTML, Head , Body و ... هر کدوم 3 تا وجود داشته باشه.
توجه 1 : آموزش كلاس بالا به طور كامل توسط دوست خوبم آقاي اسكندري (مدير رايت كليك) نوشته شد و من براي اينكه تكرار مطلب نكنم فقط كپي كردم.
توجه 2: اين بخش آموزش تموم نشده ، براي اينكه پست زياد طولاني نشه تا همينجا رو پست مي كنم،ادامه آموزش رو دارم مي نويسم و تا شب فايل ضميمه + ادامه آموزش اين بخش رو با توضيحات كامل قرار مي دم.

bestvps
August 26th, 2010, 17:46
اول تشکر میکنم ! دوم تشکر میکنم و بعدش یه پیشنهاد :d
یه کم اگه موقع توضیح دادن بعضی جاها رو که در مورد PHP هست اگه بیشتر توضیح بدید فکر کنم بهتر باشه چون ممکنه کسانی که علاقه مند باشن هنوز به مراحلی نرسیده باشن که بتونن بعضی جاها رو خوب تشخیص بدن و گیج بشن .
در مورد آموزش PHP و توضیح کلاس و فانکشن و متغیر و ثابت و .. هم اگه بخوای میتونم کمکمت کنم ( بعد نگی ملت فقط گیر میدن ) :d
بازم ممنون خیلی حوصله ی خوبی داشتی :d

Rezash
August 26th, 2010, 18:06
اول تشکر میکنم ! دوم تشکر میکنم و بعدش یه پیشنهاد :d
یه کم اگه موقع توضیح دادن بعضی جاها رو که در مورد PHP هست اگه بیشتر توضیح بدید فکر کنم بهتر باشه چون ممکنه کسانی که علاقه مند باشن هنوز به مراحلی نرسیده باشن که بتونن بعضی جاها رو خوب تشخیص بدن و گیج بشن .
در مورد آموزش PHP و توضیح کلاس و فانکشن و متغیر و ثابت و .. هم اگه بخوای میتونم کمکمت کنم ( بعد نگی ملت فقط گیر میدن ) :d
بازم ممنون خیلی حوصله ی خوبی داشتی :d
خواهش مي كنم
راستش پروژش يكم بزرگ انتخاب شده!شايد بهتر بود يك سيستم ساب دومين دهي رو حداقل در ابتدا توضيح مي دادم.اگر قرار باشه تك تك رو خيلي توضيح بدم فكر كنم بالاي 30 جلسه بشه
البته فايل ضميمه رو كه بذارم و روي اون عملي ادامه بدم زياد سخت نميشه ،اينجوري تئوري محض ـه ! روشي كه خودم اصلا خوشم نمياد
ممنون ميشم كمك كنيد ؛ ميشه تاپيك هاي مختلفي براي اين جور موارد كه گفتيد ايجاد كرد و توي هر كدوم به توضيح يك مبحث خاص پرداخت و اينجا لينكشون كنيم تا آموزش هم براي افرادي كه اطلاعات بيشتري دارند بي خودي طولاني نشه و هم تازه كارها پيش بيان.مثل اين تاپيك رو كه قبلا زدم و تو آموزش لينك كردم:
http://www.webhostingtalk.ir/f148/%D8%A2%D8%B1%D8%A7%DB%8C%D9%87-%D9%87%D8%A7-%D8%AF%D8%B1-php-13562/

shnoit
September 2nd, 2010, 10:19
قسمت بعدی آموزش کی شروع میشه !!! واقعا مفیده.

Rezash
September 2nd, 2010, 11:13
دارم پيش نيازهاش رو آماده مي كنم.مثلا بخش كاربري رو در تاپيك :
آموزش ساخت سيستم كاربري - ورود/عضويت (http://www.webhostingtalk.ir/f148/آموزش-ساخت-سيستم-كاربري-ورود-عضويت-14266/)
در حال توضيح داده شدن هست كه آموزش اصلي خيلي طولاني نشه

n2d
December 17th, 2010, 15:24
سلام !
آقا بی صبرانه منتظریم ها :d
خیلی ارادت داریم ،
نیماد8-}

Rezash
December 17th, 2010, 17:20
سلام !
آقا بی صبرانه منتظریم ها :d
خیلی ارادت داریم ،
نیماد8-}
چشم نيما جان،انشالله قسمت بعدي رو زودتر مي نويسم :53:

vimax
December 17th, 2010, 18:09
رضا جان دستت درد نکنه :)
میگم این سیستم راش هم یاد بده دی: