39
تشکر

استاندارد PSR-2 در PHP

PHP – پی اچ پی

PHP – پی اچ پی

در ادامه آشنایی با استانداردهای PSR، در این مطلب میخواهیم با استاندارد PSR-2 آشنا شویم. این استاندارد به نوعی گسترش استاندارد PSR-1 است.

هدف اصلی این استاندارد این است که سردرگمی شما در زمانی که کدهای دیگران را میبینید کمتر شود، که اینکار با رعایت نکات و استایل های کدنویسی توسط تمام برنامه نویسان PHP قابل انجام است.

استفاده از این استانداردها در تمام پروژه های PHP چه متن باز یا تجاری توصیه می‌شود که باعث هماهنگی بیشتر بین برنامه نویسان خواهد شد.

عمومی

پایه استاندارد

استانداردهای PSR-1 باید رعایت شود.

فایل‌ها

تمام فایل‌های PHP باید از Unix LF برای ایجاد خط جدید یا شناسایی پایان خط استفاده کنند (سیستم عامل ویندوز از CR استفاده میکند).

تمام فایل‌های PHP باید دارای یک خط خالی در پایان فایل باشند.

علامت تگ پایان PHP یا باید در فایل‌هایی که تنها، حاوی کد PHP هستند حذف شوند.

خط‌ها

محدودیت شدیدی در طول خط نباید وجود داشته باشد.

محدودیت ملایم بر روی طول خط باید 120 کاراکتر باشد، که در صورتی که بیشتر از 120 کاراکتر شد برنامه باید هشدار بدهد، اما هیچ اجباری مبنی بر رعایت آن نباید وجود داشته باشد.

خط‌ها میتوانند بیشتر از 80 کاراکتر نباشند و خط‌های طولانی‌تر به چند خط تبدیل شوند.

هیچ کاراکتر فاصله‌ای نباید در انتهای خط‌های غیر خالی وجود داشته باشد.

فایل‌های PHP میتوانند دارای خط‌های خالی برای افزایش خوانایی داشته باشند.

در هر خط تنها باید یک statement وجود داشته باشد.

تورفتگی

فایل‌های PHP باید از 4 کاراکتر فاصله برای تورفتگی استفاده کنند. همچنین برای اینکار نباید از Tab استفاده شود.

کلمات کلیدی

کلمات کلیدی PHP باید به صورت حروف کوچک (Lower Case) استفاده شوند.

کلمات کلیدی (ثابت‌های) true, false و null باید به صورت حروف کوچک (Lower Case) استفاده شوند.

فضای نام (Namespace) و Use

زمانی که از namespace استفاده می‌شود باید یک خط خالی بعد از آن وجود داشته باشد.

تمام استفاده از کلمه کلیدی use باید بعد از namespace مورد استفاده قرار بگیرد.

هر use فقط باید برای یک کلاس مورد استفاده قرار بگیرد.

یک خط خالی بعد از استفاده از کلمات کلیدی use باید وجود داشته باشد.

مثال:

<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

// ... additional PHP code ...
&#91;/php&#93;</div>
<h2>کلاس‌ها، خواص و متدها</h2>
لغت کلاس به <span class="en-words">class</span>, <span class="en-words">trait</span> و <span class="en-words">interface</span> اشاره میکند.
<h3>Exteneds و Implements</h3>
کلمات کلیدی <span class="en-words">extends</span> و <span class="en-words">implements</span> باید در همان خطی که کلاس تعریف شده است، مورد استفاده قرار بگیرد.

بریسس (Braces) یا <span class="en-words">{}</span> باید در خط‌های جداگانه تعریف شوند.
<div class="mycode">[php]
<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // constants, properties, methods
}
&#91;/php&#93;</div>
لیست <span class="en-words">implement</span>های کلاس میتواند به چند خط تقسیم شود. در این صورت در هر خط باید یک <span class="en-words">implement</span> تعریف و در خط تعریف کلاس هیچ <span class="en-words">implement</span>یی تعریف نشود، همچنین خط‌های تعریف <span class="en-words">implement</span> باید یک تورفتگی داشته باشند.

این قانون در مورد <span class="en-words">extend</span> از <span class="en-words">interface</span>ها نیز صحیح میباشد (این بخش در PSR-2 Meta آمده است).
<div class="mycode">[php]
<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements
    \ArrayAccess,
    \Countable,
    \Serializable
{
    // constants, properties, methods
}
&#91;/php&#93;</div>
<h3>خواص (Properties)</h3>
نوع میدان دید خواص باید همیشه تعریف شوند (مانند <span class="en-words">public</span>, <span class="en-words">protected</span> و <span class="en-words">private</span>).

کلمه کلیدی <span class="en-words">var</span> نباید در تعریف خواص مورد استفاده قرار بگیرد.

در هر خط باید یک <span class="en-words">property</span> تعریف شود.

ابتدای <span class="en-words">property</span>ها نباید با <span class="en-words">_</span> شروع شود.
<div class="mycode">[php]
<?php
namespace Vendor\Package;

class ClassName
{
    public $foo = null;
}
&#91;/php&#93;</div>
<h3>متدها (Methods)</h3>
نوع میدان دید متدها باید همیشه تعریف شوند (مانند <span class="en-words">public</span>, <span class="en-words">protected</span> و <span class="en-words">private</span>).

ابتدای متدها نباید با <span class="en-words">_</span> شروع شود.

نام متدها باید با یک فاصله بعد از کلمه کلیدی <span class="en-words">function</span> تعریف شوند.

بریسس (Braces) یا <span class="en-words">{}</span> باید در خط‌های جداگانه تعریف شوند.

پرانتزهای باز و بسته کننده در متد باید بدون فاصله از هر دو طرف تعریف شوند.
<div class="mycode">[php]
<?php
namespace Vendor\Package;

class ClassName
{
    public function fooBarBaz($arg1, &amp;$arg2, $arg3 = &#91;&#93;)
    {
        // method body
    }
}
&#91;/php&#93;</div>
<h3>پارامترهای متد (Method Arguments)</h3>
در لیست پارامترهای متد باید یک فاصله قبل از پارامتر وجود داشته باشد و همچنین هیچ فاصله‌ای نباید بعد از پارامتر وجود داشته باشد.

پارامترهایی که دارای مقدار اولیه هستند باید در انتهای لیست تعریف شوند.
<div class="mycode">[php]
<?php
namespace Vendor\Package;

class ClassName
{
    public function foo($arg1, &amp;$arg2, $arg3 = &#91;&#93;)
    {
        // method body
    }
}
&#91;/php&#93;</div>
لیست پارامترهای کلاس میتواند به چند خط تقسیم شود. در این صورت در هر خط باید یک پارامتر تعریف و در خط تعریف متد هیچ پارامتریی تعریف نشود، همچنین خط‌های تعریف پارامتر باید یک تورفتگی داشته باشند.

زمانی که لیست پارامترها به چند خط تقسیم میشود، پرانتز بسته کننده و بریس باز کننده باید با هم در یک خط تعریف شوند.
<div class="mycode">[php]
<?php
namespace Vendor\Package;

class ClassName
{
    public function aVeryLongMethodName(
        ClassTypeHint $arg1,
        &amp;$arg2,
        array $arg3 = &#91;&#93;
    ) {
        // method body
    }
}
&#91;/php&#93;</div>
<h3>کلمات کلیدی abstract, final و static</h3>
کلمات کلیدی <span class="en-words">abstract</span> و <span class="en-words">final</span> باید قبل از کلمات کلیدی میدان دید استفاده شوند.

کلمه کلیدی <span class="en-words">static</span> باید بعد از کلمات کلیدی میدان دید استفاده شوند.
<div class="mycode">[php]
<?php
namespace Vendor\Package;

abstract class ClassName
{
    protected static $foo;

    abstract protected function zim();

    final public static function bar()
    {
        // method body
    }
}
&#91;/php&#93;</div>
<h3>فراخوانی متد و تابع</h3>
زمان فراخوانی تابع یا متد، هیچ فاصله‌ایی نباید بین نام تابع و پرانتز باز کننده وجود داشته باشد. همچنین هیچ فاصله‌ایی بعد از پرانتز باز کننده و قبل از پرانتز بسته کنند نباید باشد.

در لیست آرگومان‌های متد یا تابع باید یک فاصله قبل از آرگومان وجود داشته باشد و همچنین هیچ فاصله‌ای نباید بعد از آرگومان وجود داشته باشد.
<div class="mycode">[php]
<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);

لیست آرگومان‌های تابع یا متد میتواند به چند خط تقسیم شود. در این صورت در هر خط باید یک آرگومان تعریف و در خط فراخوانی تابع یا متد هیچ آرگومانی تعریف نشود، همچنین خط‌های تعریف آرگومان باید یک تورفتگی داشته باشند.

ساختارهای کنترلی

قوانین عمومی زیر برای تمام ساختارهای کنترلی میباشد.

  • یک فاصله باید بعد از کلمه کلیدی ساختار کنترلی وجود داشته باشد.
  • هیچ فاصله‌ایی نباید بعد از پرانتز باز کننده وجود داشته باشد.
  • هیچ فاصله‌ایی نباید قبل از پرانتز بسته کننده وجود داشته باشد.
  • یک فاصله باید بین پرانتز بسته کننده و بریس باز کننده وجود داشته باشد.
  • بدنه ساختار کنترلی باید یک بار تورفتگی داشته باشند.
  • بریس بسته کننده باید در خطی جداگانه وجود داشته باشد.

ساختار if, elseif و else

ساختار if باید به صورت زیر باشد. به جایگاه پرانتزها، فاصله ها و بریس‌ها توجه کنید. همچنین کلمات کلیدی else و elseif در همان خط بریس بسته کننده ساختار قبلی هستند.

<?php
if ($expr1) {
    // if body
} elseif ($expr2) {
    // elseif body
} else {
    // else body;
}
&#91;/php&#93;</div>

کلمه کلیدی <span class="en-words">elseif</span> باید به جای کلمه کلیدی <span class="en-words">else if</span> استفاده شود.
<h3>ساختار switch و case</h3>
ساختار <span class="en-words">switch</span> باید به صورت زیر باشد. به جایگاه پرانتزها، فاصله ها و بریس‌ها توجه کنید. کلمه کلیدی <span class="en-words">case</span> باید یک تورفتگی از <span class="en-words">switch</span> داشته باشند و کلمه کلیدی <span class="en-words">break</span> باید با همان تورفتگی بدنه <span class="en-words">case</span> نوشته شوند.

یک خط کامنت (مانند no break) در <span class="en-words">case</span>هایی که دارای <span class="en-words">break</span> یا <span class="en-words">return</span> نیستند باید وجود داشته باشد.
<div class="mycode">[php]
switch ($expr) {
    case 0:
        echo 'First case, with a break';
        break;
    case 1:
        echo 'Second case, which falls through';
        // no break
    case 2:
    case 3:
    case 4:
        echo 'Third case, return instead of break';
        return;
    default:
        echo 'Default case';
        break;
}

ساختار while و do while

ساختار while باید مشابه زیر باشد. به جایگاه پرانتزها، فاصله ها و بریس‌ها توجه کنید.

<?php
while ($expr) {
    // structure body
}
&#91;/php&#93;</div>
همچنین <span class="en-words">do while</span>
<div class="mycode">[php]
<?php
do {
    // structure body;
} while ($expr);
&#91;/php&#93;</div>
<h3>ساختار for و foreach</h3>
ساختار <span class="en-words">for</span> و <span class="en-words">foreach</span> باید مشابه زیر باشد. به جایگاه پرانتزها، فاصله ها و بریس‌ها توجه کنید.
<div class="mycode">[php]
<?php
for ($i = 0; $i &lt; 10; $i++) {
    // for body
}
&#91;/php&#93;</div>
<div class="mycode">[php]
<?php
foreach ($iterable as $key =&gt; $value) {
    // foreach body
}
&#91;/php&#93;</div>
<h3>ساختار try و catch</h3>
ساختار <span class="en-words">try</span> و <span class="en-words">catch</span> باید مشابه زیر باشد. به جایگاه پرانتزها، فاصله ها و بریس‌ها توجه کنید.
<div class="mycode">[php]
<?php
try {
    // try body
} catch (FirstExceptionType $e) {
    // catch body
} catch (OtherExceptionType $e) {
    // catch body
}
&#91;/php&#93;</div>
<h3>Closures</h3>
در <span class="en-words">closure</span>ها باید یک فاصله بعد از کلمه کلیدی <span class="en-words">function</span> و یک فاصله قبل و بعد از کلمه کلیدی <span class="en-words">use</span> وجود داشته باشد.

بریس باز کننده باید در همان خط تعریف <span class="en-words">closure</span> باشد و بریس بسته کننده آن باید در خطی جداگانه باشد.

هیچ فاصله‌ایی بعد از پرانتز باز کننده و قبل از پرانتز بسته کنند نباید باشد.

در لیست آرگومان‌ها و متغیرهای <span class="en-words">closure</span> باید یک فاصله قبل از آرگومان و متغیر وجود داشته باشد و همچنین هیچ فاصله‌ای نباید بعد از آرگومان و متغیر وجود داشته باشد.

آرگومان‌های اختیاری باید در انتهای <span class="en-words">closure</span> تعریف شوند.

ساختار <span class="en-words">closure</span> باید مشابه زیر باشد. به جایگاه پرانتزها، فاصله ها و بریس‌ها توجه کنید.
<div class="mycode">[php]
<?php
$closureWithArgs = function ($arg1, $arg2) {
    // body
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
    // body
};
&#91;/php&#93;</div>
لیست آرگومان‌ها و متغیرها میتواند به چند خط تقسیم شود. در این صورت در هر خط باید یک آرگومان یا متغیر تعریف و در خط تعریف <span class="en-words">closure</span> هیچ آرگومانی تعریف نشود، همچنین خط‌های تعریف آرگومان و متغیر باید یک تورفتگی داشته باشند.

زمانی که لیست آرگومان‌ها و متغیرها به چند خط تقسیم میشود، پرانتز بسته کننده و بریس باز کننده باید با هم در یک خط تعریف شوند.
<div class="mycode">[php]
<?php
$longArgs_noVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) {
    // body
};

$noArgs_longVars = function () use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // body
};

$longArgs_longVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // body
};

$longArgs_shortVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use ($var1) {
    // body
};

$shortArgs_longVars = function ($arg) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // body
};
&#91;/php&#93;</div>
فرمت‌های بالا باید در زمانی که <span class="en-words">closure</span> در‌ واقع یک آرگومان متد یا تابع است نیز رعایت شوند.
<div class="mycode">[php]
<?php
$foo->bar(
    $arg1,
    function ($arg2) use ($var1) {
        // body
    },
    $arg3
);

همچنین ساختار زیر در استاندارد PSR-2 کاملاً درست است (این بخش در PSR-2 Meta آمده است).

<?php
somefunction($foo, $bar, &#91;
  // ...
&#93;, $baz);

$app->get('/hello/{name}', function ($name) use ($app) { 
    return 'Hello '.$app->escape($name); 
});

نتیجه‌گیری

ساختارها و عناصر بیشتری نیز وجود دارند که در این استاندارد به آن‌ها اشاره‌ایی نشده که شامل زیر است ولی محدود به آن نیست.

  • تعریف متغیرها و ثابت های سراسری
  • تعریف توابع
  • عملوندها و انتساب‌ها
  • کامنت‌ها و بلاک‌های اسناد
  • پیشوند و پسوندهای کلاس
  • بهترین شیو‌ه‌ها
این مطلب از سری مطالب، استانداردهای PSR است
  • mahdirabbani می‌گه:

    ممنون از مطالب خیلی مفیدتون. لطفا هرچه زودتر ادامه اش رو بذارید.

  • سلام به منم سر بزنید tarhche.ir مرسییییییی

  • حسین می‌گه:

    سلام ببخشید که به مطلب ربطی نداره
    میشه یکم در مورد این پروژه تئضیح بدید و کاربدو بگید
    https://www.polymer-project.org

  • علی می‌گه:

    سلام
    اگر بخوایم یه سایت با امکانات اختصاصی (مثلا:تعیین سطح کاربری برای افراد،مدیریت مطالب ارسالی،نظرسنجی،پرداخت آنلاین،وضعیت ارسال کالا و …) درست کنیم،باید از وردپرس و جوملا و … استفاده کنیم یا یک سیستم مدیریت محتوای اختصاصی درست کنیم؟کدوم بهتره؟
    چه زبان هایی لازمه ؟ CMS واسه طراحی و ساخت یک
    کافیه؟ PHP,HTML,CSS,Jquery,AngularJS زبان های
    مثلا برای طراحی یک فروشگاه اینترنتی میشه از وردپرس و … استفاده کرد یا باید یچیزی مثل
    http://aram.profishop.ir/cpanel
    طراحی کنیم؟کدوم یکی بهترین روش حساب میشه(از هر نظر)؟
    یا برای یک رستوران که امکان رزرو میز و استخدام نیرو و… داره؟
    ببخشید یذره طولانی شد
    خواهشا جواب بدید،خیلی سوال مهمیه واسم
    با تشکر

    • امیر حسینی می‌گه:

      دوست عزیز اگه php بلد باشی میتونی کارای طراحی پنل رو انجام بدی(منظور قالب نیست) jquery برای افزایش کارایی به کار میره اما اگه نباشه میشه کار رو انجام داد

      مهم ترین چیز تسلط به کدنویسی با php و ارتباط با database

  • محمد کیانی می‌گه:

    آیا ادیتوری هست که این استاندارد رو رعایت کنه؟ یا یه گزینه ای داشته باشه که این استاندارد رو بشه روی یک فایل اعمال کرد؟

  • علی می‌گه:

    سلام دو تا سوال دارم خواهشا سریع جواب بدید
    با PHP میشه یه پنل مدیریت برای یه سایت ساخت؟
    کلا ساخت یه پنل مدیریت به چه زبان هایی نیاز داره؟
    یچیزی مثل این :http://aram.profishop.ir/cpanel
    من زبان های html,css,jquery,css,php,angularjs رو بلدم و 17 سالمه.از کجا و با چه سایتی شروع کنم؟خواهشا کمکم کنید.این سوالا خیلی درگیرم کرده.اصلا من با این زبان هایی که بلدم و یه سری کار های گرافیکی (در حد یه طراح وب) میتونم درآمد داشته باشم؟چجوری؟
    مرسی مرسی

  • مهرداد می‌گه:

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

  • وحید می‌گه:

    آقای شفیعی باز هم مطلب بنویس علی الخصوص در مورد لاراول
    ممنون

  • آروین می‌گه:

    سلام آقای شفیعی خیلی مطلب جالب بود!

    واقعا ینی یه کد تمیز نوشتن اینقد داستان دارههههه…


  • نظرات این مطلب بسته است.