Skip to content

Latest commit

 

History

History
658 lines (476 loc) · 22.6 KB

urdu.md

File metadata and controls

658 lines (476 loc) · 22.6 KB

Laravel best practices

You might also want to check out the real-world Laravel example application

ترجمے:

Nederlands (by Protoqol)

한국어 (by cherrypick)

日本語 (by 2bo)

漢語 (by xiaoyi)

ภาษาไทย (by kongvut sangkla)

বাংলা (by Anowar Hossain)

فارسی (by amirhossein baghaie)

Português (by jonaselan)

Українська (by Tenevyk)

Русский

Tiếng Việt (by Chung Nguyễn)

Español (by César Escudero)

Français (by Mikayil S.)

Polski (by Karol Pietruszka)

Türkçe (by Burak)

Deutsch (by Sujal Patel)

Italiana (by Sujal Patel)

Azərbaycanca (by Maharramoff)

العربية (by ahmedsaoud31)

اردو (by RizwanAshraf1)

Laravel example app

انڈیکس

واحد ذمہ داری کا اصول

بڑے models ، چھوٹے controllers!

توثیق

کاروباری منطق service class میں ہونی چاہیے۔

اپنے آپ کو نہ دہرائیں (DRY)

،

Query Builderاور raw SQL queries پر Eloquent استعمال کرنے کو ترجیح دیں ۔ arrays پر collections کو ترجیح دیں۔

بڑے پیمانے پر تفویض

Blade templates میں queries نہ چلایئں اور eager loading کا استعمال کریں (N + 1 مسئلہ)

اپنے کوڈ پر تبصرہ کریں ، لیکن تبصرے پر وضاحتی method اور variables ناموں کو ترجیح دیں

Blade templates میں JS اور CSS نہ ڈالیں اور PHP Classes میں کوئی HTML نہ ڈالیں۔

کوڈ میں ٹیکسٹ کی بجائے config، لینگویج فائلز اور constants استعمال کریں۔

Laravel کے معیاری ٹولز کا استعمال کریں جو کمیونٹی نے قبول کیے ہیں۔

Laravel کےاپنے نام رکھنے کے طریقوں پر عمل کریں .

جہاں ممکن ہو مختصر اور زیادہ پڑھنے کے قابل syntax کا استعمال کریں۔

نئی Class کے بجائے IoC کنٹینر یا facades استعمال کریں۔

.env فائل سے غلطہ راست ڈیٹا حاصل نہ کریں۔

تاریخوں کو معیاری شکل میں محفوظ کریں۔ ڈیٹ فارمیٹ میں ترمیم کرنے کے لیے accessors اور mutators کا استعمال کریں۔

دوسرے اچھے طریقے۔

1

واحد ذمہ داری کا اصول

ایک class اور ایک method کی صرف ایک ذمہ داری ہونی چاہیے۔

❌ غلط طریقہ:

public function getFullNameAttribute(): string
{
    if (auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified()) {
        return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
    } else {
        return $this->first_name[0] . '. ' . $this->last_name;
    }
}

✔️ درست طریقہ:

public function getFullNameAttribute(): string
{
    return $this->isVerifiedClient() ? $this->getFullNameLong() : $this->getFullNameShort();
}

public function isVerifiedClient(): bool
{
    return auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified();
}

public function getFullNameLong(): string
{
    return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
}

public function getFullNameShort(): string
{
    return $this->first_name[0] . '. ' . $this->last_name;
}

🔝 انڈیکس پر واپس جائیں

2

بڑے models ، چھوٹے controllers!

اگر آپ Query Builder یا raw SQL queries استعمال کر رہے ہیں تو تمام DB سے متعلقہ منطق کو Eloquent models یا Repository کی classes میں ڈالیں۔

❌ غلط طریقہ:

public function index()
{
    $clients = Client::verified()
        ->with(['orders' => function ($q) {
            $q->where('created_at', '>', Carbon::today()->subWeek());
        }])
        ->get();

    return view('index', ['clients' => $clients]);
}

✔️ درست طریقہ:

public function index()
{
    return view('index', ['clients' => $this->client->getWithNewOrders()]);
}

class Client extends Model
{
    public function getWithNewOrders()
    {
        return $this->verified()
            ->with(['orders' => function ($q) {
                $q->where('created_at', '>', Carbon::today()->subWeek());
            }])
            ->get();
    }
}

🔝 انڈیکس پر واپس جائیں

3

توثیق

توثیق کو controllers سے Request classes میں منتقل کریں۔

❌ غلط طریقہ:

public function store(Request $request)
{
    $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
        'publish_at' => 'nullable|date',
    ]);

    ...
}

✔️ درست طریقہ:

public function store(PostRequest $request)
{
    ...
}

class PostRequest extends Request
{
    public function rules()
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
            'publish_at' => 'nullable|date',
        ];
    }
}

🔝 انڈیکس پر واپس جائیں

4

کاروباری منطق service class میں ہونی چاہیے۔

ایک controller کی صرف ایک ذمہ داری ہونی چاہیے ، لہذا کاروباری منطق کو controller سے service classes میں منتقل کریں۔

❌ غلط طریقہ:

public function store(Request $request)
{
    if ($request->hasFile('image')) {
        $request->file('image')->move(public_path('images') . 'temp');
    }
    
    ...
}

✔️ درست طریقہ:

public function store(Request $request)
{
    $this->articleService->handleUploadedImage($request->file('image'));

    ...
}

class ArticleService
{
    public function handleUploadedImage($image)
    {
        if (!is_null($image)) {
            $image->move(public_path('images') . 'temp');
        }
    }
}

🔝 انڈیکس پر واپس جائیں

5

اپنے آپ کو نہ دہرائیں (DRY)

جب ممکن ہو تو کوڈ کو دوبارہ استعمال کریں۔ SRP آپ کو نقل سے بچنے میں مدد دے رہا ہے۔ نیز ، Blade templates کو دوبارہ استعمال کریں

Eloquent scopesوغیرہ استعمال کریں۔

❌ غلط طریقہ:

public function getActive()
{
    return $this->where('verified', 1)->whereNotNull('deleted_at')->get();
}

public function getArticles()
{
    return $this->whereHas('user', function ($q) {
            $q->where('verified', 1)->whereNotNull('deleted_at');
        })->get();
}

✔️ درست طریقہ:

public function scopeActive($q)
{
    return $q->where('verified', 1)->whereNotNull('deleted_at');
}

public function getActive()
{
    return $this->active()->get();
}

public function getArticles()
{
    return $this->whereHas('user', function ($q) {
            $q->active();
        })->get();
}

🔝 انڈیکس پر واپس جائیں

6

Query Builderاور raw SQL queries پر Eloquentاستعمال کرنے کو ترجیح دیں ۔ arrays پر collections کو ترجیح دیں۔

Eloquent آپ کو پڑھنے کے قابل اور دیکھ بھال کے قابل کوڈ لکھنے کی اجازت دیتا ہے۔ نیز ، Eloquent کے پاس بلٹ ان ٹولز ہیں جیسے soft deletes, events, scopes وغیرہ۔

❌ غلط طریقہ:

SELECT *
FROM `articles`
WHERE EXISTS (SELECT *
              FROM `users`
              WHERE `articles`.`user_id` = `users`.`id`
              AND EXISTS (SELECT *
                          FROM `profiles`
                          WHERE `profiles`.`user_id` = `users`.`id`) 
              AND `users`.`deleted_at` IS NULL)
AND `verified` = '1'
AND `active` = '1'
ORDER BY `created_at` DESC

✔️ درست طریقہ:

Article::has('user.profile')->verified()->latest()->get();

🔝 انڈیکس پر واپس جائیں

7

بڑے پیمانے پر تفویض

❌ غلط طریقہ:

$article = new Article;
$article->title = $request->title;
$article->content = $request->content;
$article->verified = $request->verified;

// Add category to article
$article->category_id = $category->id;
$article->save();

✔️ درست طریقہ:

$category->article()->create($request->validated());

🔝 انڈیکس پر واپس جائیں

8

Blade templates میں queries نہ چلایئں اور eager loading کا استعمال کریں (N + 1 مسئلہ)

❌ غلط طریقہ:

غلط (100 صارفین کے لیے ، 101 DB queries استعمال ہوں گی ):

@foreach (User::all() as $user)
    {{ $user->profile->name }}
@endforeach

✔️ درست طریقہ:

غلط (100 صارفین کے لیے ، 2 DB queries استعمال ہوں گی ):

$users = User::with('profile')->get();

@foreach ($users as $user)
    {{ $user->profile->name }}
@endforeach

🔝 انڈیکس پر واپس جائیں

9

اپنے کوڈ پر تبصرہ کریں ، لیکن تبصرے پر وضاحتی method اور variables ناموں کو ترجیح دیں

❌ غلط طریقہ:

if (count((array) $builder->getQuery()->joins) > 0)

بہتر طریقہ۔:

// Determine if there are any joins.
if (count((array) $builder->getQuery()->joins) > 0)

✔️ درست طریقہ:

if ($this->hasJoins())

🔝 انڈیکس پر واپس جائیں

10

Blade templates میں JS اور CSS نہ ڈالیں اور PHP Classes میں کوئی HTML نہ ڈالیں۔

❌ غلط طریقہ:

let article = `{{ json_encode($article) }}`;

✔️ بہتر طریقہ۔:

<input id="article" type="hidden" value='@json($article)'>

Or

<button class="js-fav-article" data-article='@json($article)'>{{ $article->name }}<button>

کی Javascript فائل میں۔:

let article = $('#article').val();

ڈیٹا منتقل کرنے کے لیے خصوصی PHP to JS package کا استعمال کرنا ہے۔

🔝 انڈیکس پر واپس جائیں

11

کوڈ میں ٹیکسٹ کی بجائے config، لینگویج فائلز اور constants استعمال کریں۔

❌ غلط طریقہ:

public function isNormal()
{
    return $article->type === 'normal';
}

return back()->with('message', 'Your article has been added!');

✔️ درست طریقہ:

public function isNormal()
{
    return $article->type === Article::TYPE_NORMAL;
}

return back()->with('message', __('app.article_added'));

🔝 انڈیکس پر واپس جائیں

12

Laravel کے معیاری ٹولز کا استعمال کریں جو کمیونٹی نے قبول کیے ہیں۔

تھرڈ پارٹی پیکجز اور ٹولز استعمال کرنے کے بجائے بلٹ ان Laravel functionality اور کمیونٹی پیکجز استعمال کرنے کو ترجیح دیں۔ کوئی بھی ڈویلپر جو مستقبل میں آپ کی ایپ کے ساتھ کام کرے گا اسے نئے ٹولز سیکھنے کی ضرورت ہوگی۔ نیز ، جب آپ تھرڈ پارٹی پیکیج یا ٹول استعمال کر رہے ہیں تو Laravel کمیونٹی سے مدد حاصل کرنے کے امکانات نمایاں طور پر کم ہیں۔ اپنے کلائنٹ کو اس کی ادائیگی کرنے پر مجبور نہ کریں ۔

کام معیاری ٹولز تھرڈ پارٹی ٹولز
Authorization Policies Entrust, Sentinel and other packages
Compiling assets Laravel Mix, Vite Grunt, Gulp, 3rd party packages
Development Environment Laravel Sail, Homestead Docker
Deployment Laravel Forge Deployer and other solutions
Unit testing PHPUnit, Mockery Phpspec, Pest
Browser testing Laravel Dusk Codeception
DB Eloquent SQL, Doctrine
Templates Blade Twig
Working with data Laravel collections Arrays
Form validation Request classes 3rd party packages, validation in controller
Authentication Built-in 3rd party packages, your own solution
API authentication Laravel Passport, Laravel Sanctum 3rd party JWT and OAuth packages
Creating API Built-in Dingo API and similar packages
Working with DB structure Migrations Working with DB structure directly
Localization Built-in 3rd party packages
Realtime user interfaces Laravel Echo, Pusher 3rd party packages and working with WebSockets directly
Generating testing data Seeder classes, Model Factories, Faker Creating testing data manually
Task scheduling Laravel Task Scheduler Scripts and 3rd party packages
DB MySQL, PostgreSQL, SQLite, SQL Server MongoDB

🔝 انڈیکس پر واپس جائیں

13

Laravel کےاپنے نام رکھنے کے طریقوں پر عمل کریں

پیروی PSR معیارات

نیز ، Laravel کمیونٹی کے ذریعہ قبول کردہ نام رکھنے کے طریقوں پر عمل کریں:

کیا کیسے درست طریقہ غلط طریقہ
Controller singular ArticleController ArticlesController
Route plural articles/1 article/1
Route name snake_case with dot notation users.show_active users.show-active, show-active-users
Model singular User Users
hasOne or belongsTo relationship singular articleComment articleComments, article_comment
All other relationships plural articleComments articleComment, article_comments
Table plural article_comments article_comment, articleComments
Pivot table singular model names in alphabetical order article_user user_article, articles_users
Table column snake_case without model name meta_title MetaTitle; article_meta_title
Model property snake_case $model->created_at $model->createdAt
Foreign key singular model name with _id suffix article_id ArticleId, id_article, articles_id
Primary key - id custom_id
Migration - 2017_01_01_000000_create_articles_table 2017_01_01_000000_articles
Method camelCase getAll get_all
Method in resource controller table store saveArticle
Method in test class camelCase testGuestCannotSeeArticle test_guest_cannot_see_article
Variable camelCase $articlesWithAuthor $articles_with_author
Collection descriptive, plural $activeUsers = User::active()->get() $active, $data
Object descriptive, singular $activeUser = User::active()->first() $users, $obj
Config and language files index snake_case articles_enabled ArticlesEnabled; articles-enabled
View kebab-case show-filtered.blade.php showFiltered.blade.php, show_filtered.blade.php
Config snake_case google_calendar.php googleCalendar.php, google-calendar.php
Contract (interface) adjective or noun AuthenticationInterface Authenticatable, IAuthentication
Trait adjective Notifiable NotificationTrait
Trait (PSR) adjective NotifiableTrait Notification
Enum singular UserType UserTypes, UserTypeEnum
FormRequest singular UpdateUserRequest UpdateUserFormRequest, UserFormRequest, UserRequest
Seeder singular UserSeeder UsersSeeder

🔝 انڈیکس پر واپس جائیں

14

جہاں ممکن ہو مختصر اور زیادہ پڑھنے کے قابل syntax کا استعمال کریں۔

❌ غلط طریقہ:

$request->session()->get('cart');
$request->input('name');

✔️ درست طریقہ:

session('cart');
$request->name;

مزید مثالیں:

عام syntax چھوٹا syntax اور زیادہ پڑھنے کے قابل
Session::get('cart') session('cart')
$request->session()->get('cart') session('cart')
Session::put('cart', $data) session(['cart' => $data])
$request->input('name'), Request::get('name') $request->name, request('name')
return Redirect::back() return back()
is_null($object->relation) ? null : $object->relation->id optional($object->relation)->id
return view('index')->with('title', $title)->with('client', $client) return view('index', compact('title', 'client'))
$request->has('value') ? $request->value : 'default'; $request->get('value', 'default')
Carbon::now(), Carbon::today() now(), today()
App::make('Class') app('Class')
->where('column', '=', 1) ->where('column', 1)
->orderBy('created_at', 'desc') ->latest()
->orderBy('age', 'desc') ->latest('age')
->orderBy('created_at', 'asc') ->oldest()
->select('id', 'name')->get() ->get(['id', 'name'])
->first()->name ->value('name')

🔝 انڈیکس پر واپس جائیں

15

نئی Class کے بجائے IoC کنٹینر یا facades استعمال کریں۔

new Class syntax کے درمیان سخت جوڑا coupling ہے اور testing کو پیچیدہ بناتا ہے۔ اس کے بجائے IoC container یا facades استعمال کریں۔

❌ غلط طریقہ:

$user = new User;
$user->create($request->validated());

✔️ درست طریقہ:

public function __construct(User $user)
{
    $this->user = $user;
}

...

$this->user->create($request->validated());

🔝 انڈیکس پر واپس جائیں

16

.env فائل سے غلطہ راست ڈیٹا حاصل نہ کریں۔

config فائلوں کو ڈیٹا منتقل کریں اور پھر ایپلیکیشن میں ڈیٹا استعمال کرنے کے لیے `()config` ہیلپر فنکشن استعمال کریں۔

❌ غلط طریقہ:

$apiKey = env('API_KEY');

✔️ درست طریقہ:

// config/api.php
'key' => env('API_KEY'),

// Use the data
$apiKey = config('api.key');

🔝 انڈیکس پر واپس جائیں

17

تاریخوں کو معیاری شکل میں محفوظ کریں۔ ڈیٹ فارمیٹ میں ترمیم کرنے کے لیے accessors اور mutators کا استعمال کریں۔

❌ غلط طریقہ:

{{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->toDateString() }}
{{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->format('m-d') }}

✔️ درست طریقہ:

// Model
protected $casts = [
    'ordered_at' => 'datetime',
];

public function getSomeDateAttribute($date)
{
    return $date->format('m-d');
}

// ملف العرض
{{ $object->ordered_at->toDateString() }}
{{ $object->ordered_at->some_date }}

🔝 انڈیکس پر واپس جائیں

18

دوسرے اچھے طریقے۔

routes کی فائلوں میں کبھی بھی کوئی منطق نہ ڈالیں۔

Blade templates میں vanilla PHP کا استعمال کم سے کم کریں۔

🔝 انڈیکس پر واپس جائیں