PHP

نوشته‏ای درباره MVC و برنامه‏نویسی یک گالری با PHP

فرید احمدیان نوشته خوبی درباره MVC و نوشتن یک گالری با PHP نوشته است. اینجا بخوانید.

تابع‏های جادویی PHP 5

PHP 5 مفهومی با نام متدهای جادویی را معرفی کرده است که پشتیبانی PHP را از برنامه‏نویسی شی‏گرا بسیار افزایش و بهبود می‏دهد. در این نوشتار فهرست این توابع آمده و کد نمونه ساده‏ای از هر کدام نیز آورده شده است. در این نوشتار فرض بر این گذاشته شده است که شما پیش از این با OOP آشنا هستید. ولی با این حال با توجه به این که یکی از خوانندگان این نوشتار، دانش‏آموزانم هستند که تقریبا با OOP آشنایی ندارند، تلاش می‏کنم به شکلی همه فهم توضیح بدهم.

سازنده و ویرانگر: __construct و __destruct

گاهی لازم است که یک سری مقداردهی‏های اولیه در کلاسهایمان در زمان ساخته شدن آنها انجام بشود. نمونه:

class Book {
public $bookname;
public $author;

public function __construct($bookname, $author) {
$this->bookname = $bookname;
$this->author = $author;
}
public function __destruct(); {
echo "You don't like my book?";
}
}

$book1 = new Book('Learning PHP', 'Hoda');
echo $book1->bookname;

نکته: متدهای __construct و __destruct می‏بایست public تعریف شوند؛ چون که قرار است این متدها از بیرون فراخوانی شوند.

__call

این متد هنگامی فراخوانی می‏شود که کاربرِ کلاس متدی را صدا بزند که در کلاس وجود ندارد. فرض کنید در که استفاده‏کننده کلاس متد Open را از کلاس Book که در بالا تعریف شده، فرا بخواند. در این صورت PHP که متد Open را پیدا نمی‏کند، متد __call را در صورت وجود صدا می‏زند و نام متدی که وجود نداشته و کاربر آن را فراخوانی کرده و پارامترهایی که کاربر صدا زده است را به متد __call می‏فرستد.

class Book {
function __call($data,$arguments) {
echo "Mehod Called: $data 
"; echo "Arguments: $arguments"; } } $book1 = new Book; echo $book1->open();

تابع‏های _get و _set

متد _get هنگامی فراخوانی می‏شود که مقدار یک ویژگی یا عضو کلاس تعریف نشده در کلاس خوانده بشود. تابع _set هم وقتی فراخوان می‏شود که در یک عضو یا ویژگی کلاس که تعریف نشده، مقداری ریخته بشود:

class Book {
function __get($data) {
echo "You asked to get member '$data'. But this member does not exist";
}
}

$book1 = new Book;
echo $book1->color;

تابع‏های __isset و __unset

تابع _isset هنگامی صدا زده می‏شود که کاربر بخواهد با تابع isset موجود در PHP چک کند که آیا یک ویژگی مقدار دارد یا نه. تابع _unset هم هنگامی صدا زده می‏شود که کاربر بخواهد با تابع unset موجود در PHP مقدار یک ویژگی را خالی کند.

class Book {
function __isset($var) {
echo "Variable '$var' is not set.";
}
function __unset($var) {
echo "Variable '$var' unset.";
}
}

$book1 = new Book;
isset($book1->color);
unset($book1->color);

تابع __sleep و __wakeup

تابع __sleep هنگامی صدا زده می‏شود که یک کلاس را در حال Serialize کردن هستیم. تابع __wakeup هم زمانی صدا زده می‏شود که یک کلاس را Deserialize می‏کنیم:

class Connection {
protected $link;
private $server, $username, $password, $db;

public function __construct($server, $username, $password, $db)
{
$this->server = $server;
$this->username = $username;
$this->password = $password;
$this->db = $db;
$this->connect();
}

private function connect()
{
$this->link = mysql_connect($this->server, $this->username, $this->password);
mysql_select_db($this->db, $this->link);
}

public function __sleep()
{
return array('server', 'username', 'password', 'db');
}

public function __wakeup()
{
$this->connect();
}
}

$conn1 = new Connection();
$conndata = serialize($conn1);

$conn2 = unserialize($conndata);

تابع __tostring

این تابع هنگامی فراخوانی می‏شود، که بخواهید یک کلاس را چاپ کنید:

class Book {
public $bookname;
public $author;

public function __construct($bookname, $author) {
$this->bookname = $bookname;
$this->author = $author;
}

function __tostring() {
return "Book Name: ".$this->bookname."
Book Author: ".$this->author; } } $book1 = new Book('Learning PHP', 'Hoda'); echo $book1;

نکته: تابع __tostring باید حتما یک مقدار را برگرداند.

تابع __invoke

این تابع هنگامی فراخوانی می‏شود که کاربر کلاس بخواهد یک کلاس را همانند یک تابع به کار بگیرد:

class Book {
function __invoke($value) {
print $value;
}
}

$book1 = new Book;
$book1();

نکته: این تابع تنها در PHP 5.3.0 به بالا در دسترس است. برای دیدن نسخه PHPی که در حال استفاده از آن هستید، می‏توانید تابع phpinfo() را به کار بگیرید.

__clone

در PHP 5 همانند زبانهای دیگر OOP اگر یک شی را به شی دیگری منتسب کنید، تنها یک Reference یا اشاره‏گر از شی اول در شی دوم ریخته می‏شود. به این ترتیب حافظه این دو شی یکسان است و اگر شما یکی از این اشیاء را پاک کنید، دیگری هم پاک خواهد شد. با کمک تابع clone می‏شود یک کپی از یک شی درست کرد و در شی دیگری ریخت. تابع clone موجود در PHP، تابع __clone کلاس را صدا می‏زند تا کار ریختن شی‏های داخلی کلاس اول انجام بشود.

سردرگمی میان Frameworkهای PHP - کدام یک را باید برگزید؟

Frameworkهای بسیار زیادی برای PHP نوشته شده است که هر کدام ویژگی‏ها و امکانات خاص خودشان را دارد. برای برگزیدن یکی از آنها، نیاز به بررسی همه و آشنایی نسبی با آنها دارد. من مدتها بود که داشتم با اینها بازی می‏کردم و ویژگی‏ها و چگونگی کار با هر کدام را می‏آزمودم. در این نوشته پنج Framework مشهور را برگزیده‏‎ام و به بررسی کلی هر کدام از آنها خواهم پرداخت. این بررسی می‏خواهد یک Overview کلی از هر کدام را نشان دهد تا برای دیگران، انتخاب آسان‏تر شود. Framework برگزیده خودم هم در این نوشته مشخص خواهد شد و دلایل گزینش آن را نیز می‏توانید بخوانید.

Zend Framework
طبیعتا Zend Framework سرشناس‏ترین و بالاترین گزینه ما است؛ چون که Zend، شرکتی که پشت PHP است آن را طراحی و تولید کرده است. این Framework امکانات زیادی داشته و بسیار قدرتمند است و هر آن چه که برای تولید یک پروژه بزرگ لازم داشته باشید در خود دارد. License آن هم BSD است که به شدت انعطاف پذیر بوده و شرط می‏کند که در صورت توسعه آن باید کد تولید شده کاملا انعطاف پذیر باشد.

همچنین این Framework از PHP 4 پشتیبانی نمی‏کند و تنها در PHP 5 اجرا می‏شود. با توجه به تلاشهای زیاد اخیر برای ارتقاء به PHP 5 در سرورها شاید این مسئله کمتر به چشم بیاید ولی به هر روی ناهماهنگی با یکی از گسترده‏ترین نسخه‏های PHP در این Framework به چشم می‏خورد.

این Framework و کامپوننت‏های فراوان آن برای پروژه‏های خیلی خیلی بزرگ مناسب است ولی برای خیلی از پروژه‏ها چیزهایی را ارائه می‏کند که خیلی بیشتر از نیاز آنها است و همچنین به طور نسبی از پیچیدگی‏هایی برخوردار است. خیلی از چیزهایی که Zend Framework داره، خیلی کم کاربرد است. در هر حال، گزینه برگزیده من Zend Framework نیست. به باور من Zend Framework خیلی خوش دست نیست و یاد گرفتن آن زمان زیادتری می‏برد و زمان زیادی لازم هست تا بفهمید دقیقا چگونه کار می‏کند. این پیچیدگی مخصوصا اگر بخواهید با یک تیم کار کنید، سبب می‏شود تا زمان زیادی برای آموزش تیم از بین برود. همچنین این Framework شما را به پیروی از MVC اجبار نمی‏کند. این مساله اگر چه از یک سو سبب انعطاف‏پذیری می‏شود ولی از سوی دیگر هم ممکن است کار شما را غیر استاندارد کند.

بد نیست بدانید که در بین سایتهای ایرانی، سایت مشهور کلوب با کمک Zend Framework درست شده است.

CakePHP
یکی از مشهورترین و محبوب‏ترین Frameworkها و یکی از بهترین برابرهای Rails در PHP به شمار می‏آید. از MVC کامل پشتیبانی می‏کند. کاربران خیلی زیاد و فعالی دارد که ویژگی مهمی به حساب می‏آید. اگر چه من اصلا از Mambo خوشم نمی‏آید ولی این CMS محبوب Mambo هم قرار است در نسخه‏های آینده از CakePHP استفاده کند.
اما این سیستم دو تا اشکال کوچک هم دارد. یکی این که بیش از اندازه کند است (برای خواندن گزارش یک Benchmark خوب بین CakePHP، Zend Framework و CodeIgniter اینجا را ببینید). این مساله در صورتی که هزینه سرور برای شما اهمیت داشته باشد، خودش را بیشتر نشان می‏دهد. دوم این که اسامی کلاسهایی CakePHP خیلی عمومی طراحی شده است. برای نمونه کلاس Database که اگر شما هم کلاس مشابهی داشته باشید، سبب ایجاد ناهماهنگی در کد شما می‏شود و به طور کلی چنین اسم‏گذاری و به کار نگرفتن پیشوند مناسب مانند Cake سبب بدبینی نسبی من به طراحی این سیستم شده است.
همچنین ORMی که در CakePHP طراحی شده است، توارث را پشتیبانی نمی‏کند و به باور من چندان استاندارد نیست. (با Hackهایی می‏توان مشکل توارث ORM در CakePHP حل کرد. در این باره رک: Kelnishi.com)

ولی به طور کلی نصب CakePHP خیلی ساده است و راه انداختن اولیه سایت باهاش کار ساده و آسانی است. بر خلاف Zend Framework که نمی‏دانستید از کجا باید آغاز کنید، در CakePHP خیلی سریع می‏توانید یک سایت ساده راه بیاندازید. ولی انجام کارهای پیشرفته‏تر به دلیل نبودن مستندات کافی و راهنماهای مناسب کمی با CakePHP دشوار است. در هر حال گزینه انتخابی من CakePHP هم نیست.

برای خواندن یک آموزش فارسی خوب برای کار با این برنامه رک: الوان وب

Prado
از همه گزینه‏های دیگر متفاوت است. بر پایه MVC درست نشده است. طراح Prado این کار را برای پروژه دکترایش انجام داده است و در طراحی آن Delphi را مد نظر داشته و تلاش کرده تا یک Framework کاملا Object Oriented و Event Driven درست کند. اگر با ASP.NET کار کرده باشید، Prado را خیلی مشابه با آن خواهید یافت. در Prado همه چیز حتی یک Label و Button هم Object است که Propertyها و Eventهای خاص خودش را دارد. همچنین زبانی شبیه به HTML برای طراحی ظاهر صفحات دارد (دقیقا شبیه به ASP.NET و Tagهای asp: این زبان)
من اگر چه ASP.NET را دوست دارم و باهاش کار هم می‏کنم و اگر چه فکر می‏کنم Prado سیستم خیلی قشنگ و تمیزی است ولی Prado هم گزینه برگزیده من نیست؛ چون پشتیبانی یک سیستم از MVC برایم اهمیت زیادی دارد.

CodeIgniter
این Framework خیلی شبیه به CakePHP و از آن ساده‏‎تر و کوچکتر است و به همین خاطر هم از لحاظ سرعت از CakePHP خیلی بهتر است ولی خوب به همان اندازه هم امکانات کمتری دارد. این Framework شما را مجبور به پیروی کامل از MVC نمی‏کند، بنابراین برای یادگیری نوآموزان بهتر است. از Ajax هم مستقیما پشتیبانی نمی‏کند. ولی Code Igniter ویژگی‏های خوبی هم دارد. این Framework در PHP 4 هم کار می‏کند و از لحاظ سبک برنامه‏نویسی به سبک برنامه‏نویسی PHP 4 نزدیک است. به همین خاطر برای Port کردن کدهای قدیمی به یک Framework گزینه مناسبی است. همچنین دارای Community بزرگی است و کامپوننتها و مثالهای فراوانی برایش پیدا می‏شود. این Framework هم همانند CakePHP گزینش من نیست.

symfony
این Framework امکانات بسیار زیادی دارد و ماژول‏های جداگانه را برای انجام کارهای خودش به کار می‏گیرد: مانند DB Layer که با امکانات زیاد خودش واقعا لایه بانک اطلاعاتی شما را به بهترین شکل پشتیبانی می‏کند و امکان نوشتن برنامه مستقل از بانک اطلاعاتی را به شما می‏دهد. (اگر چه این ویژگی در Frameworkهای دیگر هم هست).
برای انجام پروژه‏های بزرگ symfony به خاطر امکانات زیادش، گزینه خیلی خوبی است ولی با این حال، پیچیدگی‏های Zend Framework را هم ندارد. این Framework هم تنها بر روی PHP 5 کار می‏کند. License آن هم MIT است که License خوب و انعطاف‏پذیری به حساب می‏آید. همچنین این Framework به خوبی AJAX را پشتیبانی می‏کند و امکاناتی برای ساختن صفحات Admin سایت دارد که کار طراحی بخش مدیریتی سایت را خیلی آسان می‏کند.

سیمفونی از ORM مشهوری به نام Propel بهره می‏گیرد که به باور من سیستم بسیار قدرتمندی است. اگر چه در CakePHP هم ORM هست ولی در آن جا از یک سیستم داخلی استفاده شده است. به کار گیری یک ORM بیرونی سبب افزایش سرعت توسعه سیمفونی شده است؛ چون که Propel سیستم خیلی مشهوری بوده و به طور عادی خودش در حال توسعه هست. این مساله همچنین هوشمندی طراحان سیمفونی را نشان می‏دهد.

خوب حدس زدنش سخت نیست. Framework برگزیده من symfony است. طراحی دقیق و محکم، سرعت مناسب، امکانات خیلی زیاد، مستندات و Community بزرگ آن، وجود ویژگی Admin Generator و سیستم کنترل دسترسی که سبب می‏شود من بتوانم در زمان طراحی صفحات سایت به مسائل مهمتر و افزودن ویژگی‏های اصلی بپردازم، از دلایل این گزینش من است.

پیوندها

اندر ویژگی‏های شیخنا و مولانا PHP

راستی، هیچ می‏دونستید این سایتها با PHP درست شده‏اند:

  • Facebook
  • Yahoo!
  • Wikipedia
  • Wordpress
  • Tagged
  • Digg

برآورد می‏شود که نزدیک به 20 میلیون سایت با کمک PHP راه افتاده است. این را برای کسانی نوشتم که فکر می‏کنند PHP قدیمی شده است و مثلا ASP.NET بهتر است و دیگر با بودن dot Net زبانی مثل PHP کهنه و قدیمی است. افزون بر همه اینها، PHP بزرگترین گروه کاربران را دارد و بیشترین میزان کدهای موجود در وب با PHP نوشته شده است.

من تازگی‏ها دارم، بیشتر از دو Framework مشهور PHP به نامهای Symfony و CakePHP چیز می‏خوانم و باهاشون کار می‏کنم تا بیشتر باهاشون آشنا بشوم. همین طور که خواندنی‏هایم پیش می‏رود، اینجا خبرش را می‏نویسم.

Syndicate content