You might also want to check out the real-world Laravel example application
Nederlands (by Protoqol)
한국어 (by cherrypick)
ภาษาไทย (by kongvut sangkla)
বাংলা (by Anowar Hossain)
فارسی (by amirhossein baghaie)
Українська (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)
Deutsch (by Sujal Patel)
Italiana (by Sujal Patel)
Azərbaycanca (by Maharramoff)
العربية (by ahmedsaoud31)
اردو (by RizwanAshraf1)
واحد ذمہ داری کا اصول
بڑے 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 کا استعمال کریں۔
دوسرے اچھے طریقے۔
ایک 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;
}
🔝 انڈیکس پر واپس جائیں
اگر آپ 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();
}
}
🔝 انڈیکس پر واپس جائیں
توثیق کو 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',
];
}
}
🔝 انڈیکس پر واپس جائیں
ایک 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');
}
}
}
🔝 انڈیکس پر واپس جائیں
جب ممکن ہو تو کوڈ کو دوبارہ استعمال کریں۔ 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();
}
🔝 انڈیکس پر واپس جائیں
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();
🔝 انڈیکس پر واپس جائیں
❌ غلط طریقہ:
$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());
🔝 انڈیکس پر واپس جائیں
❌ غلط طریقہ:
غلط (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
🔝 انڈیکس پر واپس جائیں
❌ غلط طریقہ:
if (count((array) $builder->getQuery()->joins) > 0)
بہتر طریقہ۔:
// Determine if there are any joins.
if (count((array) $builder->getQuery()->joins) > 0)
✔️ درست طریقہ:
if ($this->hasJoins())
🔝 انڈیکس پر واپس جائیں
❌ غلط طریقہ:
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 کا استعمال کرنا ہے۔
🔝 انڈیکس پر واپس جائیں
❌ غلط طریقہ:
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'));
🔝 انڈیکس پر واپس جائیں
تھرڈ پارٹی پیکجز اور ٹولز استعمال کرنے کے بجائے بلٹ ان 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 |
🔝 انڈیکس پر واپس جائیں
پیروی PSR معیارات
نیز ، Laravel کمیونٹی کے ذریعہ قبول کردہ نام رکھنے کے طریقوں پر عمل کریں:
کیا | کیسے | درست طریقہ | غلط طریقہ |
---|---|---|---|
Controller | singular | ArticleController | |
Route | plural | articles/1 | |
Route name | snake_case with dot notation | users.show_active | |
Model | singular | User | |
hasOne or belongsTo relationship | singular | articleComment | |
All other relationships | plural | articleComments | |
Table | plural | article_comments | |
Pivot table | singular model names in alphabetical order | article_user | |
Table column | snake_case without model name | meta_title | |
Model property | snake_case | $model->created_at | |
Foreign key | singular model name with _id suffix | article_id | |
Primary key | - | id | |
Migration | - | 2017_01_01_000000_create_articles_table | |
Method | camelCase | getAll | |
Method in resource controller | table | store | |
Method in test class | camelCase | testGuestCannotSeeArticle | |
Variable | camelCase | $articlesWithAuthor | |
Collection | descriptive, plural | $activeUsers = User::active()->get() | |
Object | descriptive, singular | $activeUser = User::active()->first() | |
Config and language files index | snake_case | articles_enabled | |
View | kebab-case | show-filtered.blade.php | |
Config | snake_case | google_calendar.php | |
Contract (interface) | adjective or noun | AuthenticationInterface | |
Trait | adjective | Notifiable | |
Trait (PSR) | adjective | NotifiableTrait | |
Enum | singular | UserType | |
FormRequest | singular | UpdateUserRequest | |
Seeder | singular | UserSeeder |
🔝 انڈیکس پر واپس جائیں
❌ غلط طریقہ:
$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') |
🔝 انڈیکس پر واپس جائیں
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());
🔝 انڈیکس پر واپس جائیں
config فائلوں کو ڈیٹا منتقل کریں اور پھر ایپلیکیشن میں ڈیٹا استعمال کرنے کے لیے `()config` ہیلپر فنکشن استعمال کریں۔
❌ غلط طریقہ:
$apiKey = env('API_KEY');
✔️ درست طریقہ:
// config/api.php
'key' => env('API_KEY'),
// Use the data
$apiKey = config('api.key');
🔝 انڈیکس پر واپس جائیں
تاریخوں کو معیاری شکل میں محفوظ کریں۔ ڈیٹ فارمیٹ میں ترمیم کرنے کے لیے 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 $dates = ['ordered_at', 'created_at', 'updated_at'];
public function getSomeDateAttribute($date)
{
return $date->format('m-d');
}
// ملف العرض
{{ $object->ordered_at->toDateString() }}
{{ $object->ordered_at->some_date }}
🔝 انڈیکس پر واپس جائیں
routes کی فائلوں میں کبھی بھی کوئی منطق نہ ڈالیں۔
Blade templates میں vanilla PHP کا استعمال کم سے کم کریں۔
🔝 انڈیکس پر واپس جائیں