احسان رضایی

یک توسعه دهنده

مدیریت Route های لاراول در پروژه های بزرگ

laravel routes

روت‌ها/Routes در پروژه های بزرگ لاراولی ممکن هست زیاد و شلوغ بشن، خوانایی پایین بیاد و هنگام ویرایش دچار سردرگمی بشین. در این مطلب سه روش برای حل این مشکل رو توضیح میدم و شما میتونید با توجه به پروژه و ارزیابی خودتون یکی رو انتخاب کنید.

استفاده از RouteServiceProvider

این Provider مسیر های تعریف شده رو در routes/web.php و routes/api.php لود میکنه. میتونید روت‌ها رو به فایل‌های کوچک‌تر تبدیل و در RouteServiceProvider تعریفشون کنید. دقیقا مثل کاری که به طور پیشفرض با web.php و api.php انجام داده. در مثال زیر متد بوت RouteServiceProvider رو ویرایش و posts رو اضافه کردم. در routes/posts.php مسیر های مربوط به ماژول post من قرار داره.

    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::middleware('api')
                ->prefix('api')
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->group(base_path('routes/web.php'));

            // new routes.
            Route::middleware('api')
                ->group(base_path('routes/posts.php'));
        });
    }

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

ادامه...

تفاوت بین Active Record و Data Mapper

هنگامی که موضوع کار با داده ها در application مطرح میشه احتمالا نیاز به یک ORM پیدا خواهید کرد. ORM یک لایه بین پایگاه داده و application شماست. که به وسیله اون عملیات CRUD یا به عبارت دیگه create, read, update,  delete به آسونی انجام میپذیره. بیشتر از این به ORM نمیپردازم چون در حال حاضر اکثر فریمورک های مدرن ازش استفاده میکنن و بعید میدونم شما تا الان با اون کار نکرده باشید.

دو الگو پیاده سازی محبوب ORM ها Active Record و Data Mapper هست. در این مقاله تصمیم دارم به تفاوت بین این دو الگو بپردازم. مزایا و معایبشون چی هست و چطور میشه یکی از این الگو ها رو برای کار خودمون انتخاب کنیم.

ادامه...

مدل سازی داده و طراحی پایگاه داده چند زبانه

Multiple Languages

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

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

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

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

ادامه...

نامگذاری چیزها

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

- مفهوم.

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

1) از نام های دقیق استفاده کنید.

 اگر کسی بدون کامنت های شما نمیتونه ایده و هدف شما رو بفهمه اصلا خوب نیست. بدترین حالت زمانی هست که نام به کسی که اون رو میخونه دروغ بگه!

2) اجتناب از نام های بی معنی.

نام هایی مثل i,j,k و... تنها زمانی قابل قبول هستن که در یک حلقه استفاده بشن. در باقی موارد خوانایی رو سخت میکنن.

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

3) نام کلاس ها، اینترفیس و پراپرتی ها.

نام کلاس میتونه شامل یک یا چند اسم باشه. از فعل(تنها) نباید استفاده کرد. “data”, “manager”, “info”, “processor”, “handler”, “maker”, “util” و موارد مشابه به علت مبهم بودنشون اجتناب کنید.

Interface ها معمولا اسم یا صفت هستن. میتونید از پیشوند (مثلا Interface) هم استفاده کنید.

namespace Psr\Log;

/**
 * Describes a logger instance
 */
interface LoggerInterface
{

property ها اسم یا صفت هستن. برای پراپرتی هایی با مقدار دودویی(0 یا 1) میشه از پسوند هایی مثل “Is”, “Can”یا “Has” در جاهای مناسب استفاده کرد.

نام Method باید شامل یک یا چند فعل باشه و کاری که انجام میده رو توضیح بده. نه اینکه چطور اون کار رو انجام میده.

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

 

 

class Exception {}

class InvalidArgumentException extends Exception {}
ادامه...

فهرستی از نکات امنیتی در PHP

php-security-checklist

- از php 7 یا نسخه های بالاتر استفاده کنید.

یا به عبارت دیگه همیشه از آخرین نسخه php استفاده کنید. کاملا مشخصه که در نسخه های جدیدتر، موارد امنیتی اضافه یا اصلاح و ویژگی های قدیمی و غیر قابل اطمینان دور ریخته میشن.

- تمام داده ها رو فیلتر و اعتبار سنجی کنید.

صرف نظر از اینکه داده ها از کجا اومدن و به کجا خواهند رفت!(داده های ورودی و خروجی منظورمه) یاید فیلترها و اعتبار سنجی های مختلف روی اونها اعمال بشه. اگر از فریمورک های موجود استفاده میکنید ابزار های خوبی رو در این زمینه براتون فراهم کردن. اگر هم استفاده نمیکنید که پیشنهاد میکنم استفاده کنید!

- استفاده از Whitelist به جای Blacklist.

به بیان ساده Blacklist یعنی فیلتر کردن موارد غیر قابل قبول! که به مراتب تعداد این موارد خیلی بیشتر از قابل قبول هاست. اصلا ممکنه نتونید همه رو توی این لیست جا بدین و چیزهایی از قلم بیوفتن. پس هرگز سعی نکنید لیست از مواردی داشته باشید که برای app شما غیر قابل قبول هست(Blacklist) و به جای اون Whitelist بسازید.

- strict typing

اگر از عملگر == برای مقایسه استفاده میکنید مراقب باشید که PHP به علت تبدیل عجیب و غریبی که انجام میده ممکنه اسکریپت شما رو آسیب پذیر کنه. مثلا عدد 1 برابر هست با رشته 1 و خود 1 یعنی true! و... .(Type Hinting)

 - از الگوریتم های امنیتی/رمزنگاری من درآوردی خودت استفاده نکن!

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

ادامه...

درس های yii2 شماره 15: نصب swagger

در ادامه مطلب قبلی.

- داخل packagist عنوان مورد نظرمون(yii2 swagger) رو جستجو میکنیم. مثل همیشه package های زیادی رو مشاهده میکنید. اولین گزینه پر استفاده ترین و محبوب ترین package هست و ما هم اونُ انتخاب میکنیم(light/yii2-swagger).

- برای نصب از طریق composer توضیحات لازم رو داده. من از همون روش اولی که گفته نصب رو انجام میدم یعنی اجرای دستور زیر:

composer require --prefer-dist light/yii2-swagger "~1.0.4" --dev

- داخل یک controller به عنوان مثال SiteController و در متد actions پیکره بندی swagger رو انجام میدیم:

public function actions()
{
    return [
        //The document preview addesss:http://api.yourhost.com/site/doc
        'doc' => [
            'class' => 'light\swagger\SwaggerAction',
            'restUrl' => \yii\helpers\Url::to(['/site/api'], true),
        ],
        //The resultUrl action.
        'api' => [
            'class' => 'light\swagger\SwaggerApiAction',
            //The scan directories, you should use real path there.
            'scanDir' => [
                Yii::getAlias('@api/modules/v1/swagger'),
                Yii::getAlias('@api/modules/v1/controllers'),
                Yii::getAlias('@api/modules/v1/models'),
                Yii::getAlias('@api/models'),
            ],
            //The security key
            'api_key' => 'balbalbal',
        ],
    ];
}

این پیکره بندی شامل موارد زیر میشه:

doc: آدرس صفحه ی مستندات رو مشخص میکنه. با توجه به این نامی که انتخاب کردیم آدرس چیزی شبیه به http://api.yourhost.com/site/doc خواهد شد.

restUrl: آدرس پایه restful api رو تعریف میکنه. به عنوان مثال اگر یک api برای login آماده کنیم درخواست به آدرس http://api.yourhost.com/site/api/login ارسال میشه.

scanDir: مسیر هایی هست که swagger اونها رو برای پیدا کردن api جستجو(scan) میکنه.

api_key: ممکنه api شما نیاز به احراز هویت داشته باشه. در بالای صفحه ی مستندات swagger جایی برای وارد کردن کلید امنیتی وجود داره تا دسترسی ها محدود و امنیت برقرار بشه. به طور پیشفرض اینجا میتونید یک کد امنیتی تعریف و استفاده کنید اما بهتر اینه که کاربران در سیستم login کنن، سپس یک token دریافت و از اون به عنوان کلید امنیتی استفاده کنن. یعنی هر کاربر یک کلید امنیتی منحصر به فرد که با هر بار login تغییر میکنه. بعدا این قسمت رو جدی تر بررسی میکنیم.

مستند سازی خودکار و ایجاد یک محیط تعاملی برای Web API با استفاده از swagger

swagger اجازه میده یک ساختار توصیفی از API خودتون بسازید. چرا مفید، عالی و کاربردی به نظر میرسه؟ چون میتونیم به طور خودکار برای API خودمون مستندات زیبا و یک محیط تعاملی ایجاد کنیم، همچنین امکان تست API رو هم برامون فراهم میکنه. swagger این کارُ با خواندن به اصطلاح حاشیه ها/یادداشت ها یا کامنت های داخل سورس انجام میده.

/**
 * @SWG\Get(
 *   path="/customer/{customerId}/rate",
 *   summary="List customer rates",
 *   operationId="getCustomerRates",
 *   @SWG\Parameter(
 *     name="customerId",
 *     in="path",
 *     description="Target customer.",
 *     required=true,
 *     type="integer"
 *   ),
 *   @SWG\Parameter(
 *     name="filter",
 *     in="query",
 *     description="Filter results based on query string value.",
 *     required=false,
 *     enum={"active", "expired", "scheduled"},
 *     type="string"
 *   ),
 *   @SWG\Response(response=200, description="successful operation"),
 *   @SWG\Response(response=406, description="not acceptable"),
 *   @SWG\Response(response=500, description="internal server error")
 * )
 *
 */
ادامه...

رعایت اصول و سبک کدنویسی

سبک کدنویسی که در فریمورک و extension های رسمی استفاده میشه دارای اصول، قواعد و قانون های خودش هست. پس اگر تصمیم دارید چیزی به هسته اضافه کنید باید این قواعد رو در نظر بگیرید حتی در غیر این صورت هم رعایت این موارد خالی از لطف نیست و توصیه میکنم این کارُ انجام بدین. در حالی که میتونید راحت باشید، شما مجبور به رعایت این سبک در application خودتون نیستید...

نگاه کلی

به طور کلی ما از سبک PSR-2 استفاده میکنیم و هر چیزی که در این سبک وجود داره اینجا هم هست.

- در فایل ها باید از برچسب های php?> و =?> استفاده شود.

- در پایان هر فایل باید یک خط جدید(newline) داشته باشید.

- encoding فایل برای کد های php باید UTF-8 without BOM باشد.

-  به جای tab از 4 فضای خالی(space) استفاده کنید.

- نام کلاس ها باید به صورت StudlyCaps تعریف شوند.

- ثابت های داخل کلاس تماما باید با حروف بزرگ و گاهی با جداکننده "_" تعریف شوند.

- نام متد ها و پراپرتی ها باید به صورت camelCase تعریف شوند.

- پراپرتی های خصوصی(private) باید با "_" شروع شوند.

- همیشه از elseif جای else if استفاده کنید.

 

ادامه...

Hashids، تولید یک شناسه منحصر به فرد از اعداد صحیح (integers)

Hashids یک کتابخانه متن باز و کوچیکه که شناسه هایی کوتاه، منحصر به فرد و غیر متوالی از اعداد را تولید میکند.

به عنوان مثال عدد 347 تبدیل به رشته ی “yr8” یا آرایه ای شامل اعداد [27, 986] تبدیل به “3kTMd” میشه.

شما همچنین میتونید شناسه ها رو decode کنید، یعنی رشته های تولید شده به وسیله Hashids برگشت پذیر خواهند بود. حتی طول رشته تولید شده قابل تعریفه.

مثالی که توی وب شاید بارها دیدین:

https://url.ir/lqY9X

ادامه...

حل مشکل تایپ فارسی در phpstorm

phpstorm از نسخه 2016 به بعد زبان فارسی رو به خوبی پشتیبانی میکنه.
برای حل مشکل فارسی نویسی در نسخه های 9 به بالا (تا قبل از 2016)  مراحل زیرُ انجام بدین:

1- در محل نصب نرم افزار فایل idea.properties رو پیدا کنید
2- با یک ادیتور مثل notepad بازش کنید و خط زیرُ به انتهای فایل اضافه کنید:

editor.new.rendering=true

3- یک بار phpstrom رو ببندید و دوباره باز کنید.

پ.ن: موردی که خیلی وقت پیش نوشته شده بود رو در همون زمان خودم شخصا تست کرده بودم و جواب گرفتم. الان حتما از نسخه های جدید استفاده کنید.

 

کتاب‌ها

کتاب الگوهای طراحی به بیان ساده(design patterns / دیزاین پترن)

در مهندسی نرم افزار، design patterns(الگوهای طراحی) راه حل‌های قابل استفاده برای مشکلاتی هستند که معمولاً در طراحی نرم‌افزار اتفاق می افتند.

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

کتاب refactoring / ریفکتورینگ

Refactoring مجموعه‌ای از تکنیک‌هاست که به منظور اصلاح و بهبود کدهای قبلی بدون تغییر در عملکرد و رفتارشان جهت خوانایی، کارامدی و قابلیت نگهداری بیشتر انجام می‌شود.

در کتاب Refactoring اثر Martin Fowler نوشته شده: refactoring تکنیک مرتب/منظم سازی برای تجدید ساختار کد موجود است. تغییر ساختار داخلی کد بدون تغییر رفتار خارجی آن.

refactoring یک سرمایه‌گذاری و راه حلی برای مقابله با کد کثیف و بدهی فنی است که باعث کاهش هزینه‌های توسعه نرم‌افزار در آینده خواهد شد.