Code Monkey home page Code Monkey logo

laravel-best-practices's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-best-practices's Issues

Validation FormRequest

Hi!
The Validation example just uses Request as class to inherit. However laravel by default creates a FormRequest instead. What I need is a request to validate my json, but I currently do not know which one is the right one. Maybe you could add some more hints to this example?

URI naming convertion?

E.g.:
$router->get('/users/forgot_password', 'UserController@forgotPassword');
or
$router->get('/users/forgot-password', 'UserController@forgotPassword');
or
$router->get('/users/forgotPassword', 'UserController@forgotPassword');

there's no clue in Resource Controllers doc, but I guess forgot-password seems to be the way to go.

Traits and interfaces indistinguishable by name

Can't we make it more clear by name if the "class" is a trait or an interfaces as they both are adjectives now. I understand the reasoning but we also need a solution (I think). We might consider recommending creating an interface for every trait.

Date formatting

Is this really working?

// Model
protected $dates = ['ordered_at', 'created_at', 'updated_at']
public function getSomeDateAttribute($date)
{
    return $date->format('m-d');
}

// View
{{ $object->ordered_at->toDateString() }}
{{ $object->ordered_at->some_date }}

Is it really adding a property on the fly to the Carbon object?

$object->ordered_at->some_date doesn't really read fluent...

Test method naming convention

Currently:

Camel case prefixed with test. testGuestCannotSeeArticle()

Proposed:

Descriptive names delimited by underscore

Example:

<?php

    /** @test **/
   public function guests_cannot_see_article(){
       //Do Something.
   }

?>

Reasoning:

Laravel's own tutorials don't even follow the camel case standard.
https://laracasts.com/series/lets-build-a-forum-with-laravel/episodes/2
https://laracasts.com/series/phpunit-testing-in-laravel/episodes/2 (This one describes both but shows why underscored version is preferred in Laravel)

No mention of Blade components?

Hey, just came here to look for the best practices for Blade components.

ie.

php artisan make:component LongComponentName

avoid using request()->all()

request()->all() can be dangerous because when used may cause a security vulnerability.

for example:

# database
users:
   - id
  - username
  - password
  - email
  - superuser (bool)

# controller
public function store(Request $request) {
  User::create($request->all());
  return back()->with('alert', 'user created!');
}

if am i a hacker-boy and send a payload with input[name=superuser]=1 magically I will become a superadmin.


bad:

public function store(Request $request) {
  User::create($request->all());
  return back()->with('alert', 'user created!');
}

good:

public function store(Request $request) {
  User::create($request->only('username', 'password', 'email'));
  return back()->with('alert', 'user created!');
}

Is there a way to print this?

First, thank you to those who have made this possible, as a new developer I find this extremely helpful!

I was wondering if there's a way to print this out so I can have it available offline for when I'm not at my desk.

Views and assets dirnames with two words

How to name?

Views

  1. /resources/views/TwoWords/view.blade.php
  2. /resources/views/twoWords/view.blade.php
  3. /resources/views/twowords/view.blade.php
  4. /resources/views/two_words/view.blade.php

Assets

  1. /resources/assets/js/components/TwoWords/MyComponent.vue
  2. /resources/assets/js/components/twoWords/myComponent.vue
  3. /resources/assets/js/components/twowords/mycomponent.vue
  4. /resources/assets/js/components/two_words/my_component.vue

What about translation variables?

What is the best practice for the translation variables?

for example __('some variable')

do we do it as snake_case or kebab-case or camelCase?

What about laravel Resources?

like when we say php artisan make: resource SomeResouce

should we make them singular, or plural, or in which cAsEs?

Looking for the repo owner

...are you alive?

I suppose you have better things to do and I'm happy with it but couldn't you add other maintainers?

Ukrainian translation

Hey there, Alexey!

I want to translate these wonderful practices in Ukrainian language.
Which font and its size I need to use for the image of Laravel?
That info would be enough for me to start the translation.

Thank you!

Injection vs facades vs helpers?

I was just wondering what the best practices are or what the community's thoughts are on when to use:

a) Constructor injection
b) Method injection
c) Facades
d) Global helper functions

PSR-12

Should we update the linked PSR standard to PSR-12?

How can PHP framework propose a table naming convention in a database (SQL, NoSQL)?

Does it make sense to recommend database naming in context of PHP framework?
May be this is confusing for less experienced developers?
And implies violation of best practices, if database is already designed using singular naming style?

Are these practices of database naming possible, if database is already designed using singular naming style?
https://github.com/alexeymezenin/laravel-best-practices#follow-laravel-naming-conventions

Does it means that singular naming at database is not good for Laravel?

Korean translation

Hi, alexeymezenin!

I'm writing here because I don't know how to contact you.

First, thank you for a good article laravel best practices.

I want to spread this good article in Korea.

So I want to translate Korean. If you allow I'll fork your branch and then translate it.

Thanks :D

What are your thought on this?

Business logic should be in service class

  • I don't think it's best practice to pass a Laravel's Request object to the Service Layer.
  • Why?
    • Because, it's HTTP specific data object. If your Service Object depends on delivery mechanism, you can't reuse the service object in Console Command or Queue Job.
    • Furthermore the Request object is an object from the framework, and HEAVY.
      laravel_request
    • I know you may argue that not only the Request object is already on the memory and passing it is merely a memory reference in the runtime, also additional unnecessary memory usage due to Dto object. But in personal I'll choose maintenability and readibility.
  • Then what?
    • I'd like you to use a Boundary Object, namely Dto.
    • Make the Laravel Request object new up a Dto. And make the Service object use Dto.
Class CreateUserRequest
{
    public function rules()
    {
        return [
            // ...
        ];
    }

    public function getUserDto()
    {
        return new UserDto(
            $this->input('user_name', null),
            // ...
        );
    }
}

Class UserController
{
    public function createUser(CreateUserRequest $request, UserCreator $creator)
    {
        $dto = $request->getUserDto();
        DB::transaction(function () use ($creator, $dto) {
            $user = $creator->createUser($dto);
            $user->save();
        });

        // ...
    }
}

Class CreateUserCommand
{
    public function handle(UserCreator $creator)
    {
        $dto = new UserDto(
            $this->argument('user_name'),
            // ...
        );
        DB::transaction(function () use ($creator, $dto) {
            $user = $creator->createUser($dto);
            $user->save();
        });

        // ...
    }
}

Don't repeat yourself (DRY)

  • I don't like whereHas() example.
  • Because under the the hood, the query builder translate whereHas() to exists subquery.
  • And it leads you to a huage performance degradation, especially when you have a large volume of records.

Mass assignment

  • I don't think mass assignment is a good practice, when your service is NOT TRIVIAL.
  • As the document mentioned earlier, I would recommend to use a Sservice Object and mutate each property one by one.
  • For example:
class UserCreator
{
    public function createUser(UserDto $dto)
    {
        $user = new User();
        $user->name = $dto->getUserName();
        // You can hook into Model Validation(==Business Policy) logic here
        // With mass assignment, you will loose the model validation chance
        // ...
        return $user;
    }
}

class UserModifier
{
    public function modifyUser(User $user, UserDto $dto)
    {
        $name = $dto->getUserName();
        if ($name !== null) {
            // Again you can do the model validation here
            $user->name = $name;
        }
        // ...
        // Donot return the $user, because it was passed by reference.
    }
}

Use shorter and more readable syntax where possible

  • Maybe it's OK to use Laravel's global helper functions in a Controller but not in a Domain Logic.
  • I think the document is leading people being tightly coupled to the framework.

Accessing auth() and user() inside Models?

https://github.com/alexeymezenin/laravel-best-practices#single-responsibility-principle

That example, while probably contrived, as the first example in the document seems to signal to the reader that calling auth() inside a model (they are model methods after all, they have get*Attribute()) is a good thing or widely accepted thing to do. Is this the case? I have not seen this in the wild much (auth() calls probably best exist in the controller or view layers).

If it's purely serving to demonstrate single responsibility, is there a better contrived use case to use? Are you open to this change?

Following Mass assignment rule with array cuase column not found error

This is the rquest body:

{
	"arr": [
		{
			"a": 3,
			"b": 3
		},
		{
			"a": 3,
			"b": 3
		}
	]
}

and with this validations rules:

    public function rules()
    {
        return [
            // 'arr' => 'array',
            'arr.*.a' => 'required'
        ];
    }

The result of dd($request->validated()); is what I want, I don't need b to be included

"arr" => array:2 [
    0 => array:1 [
      "a" => 3
    ]
    1 => array:1 [
      "a" => 3
    ]
  ]

But when I want to validate the array itself like this:

    public function rules()
    {
        return [
            'arr' => 'array',
            'arr.*.a' => 'required'
        ];
    }

b will be added to the output

"arr" => array:2 [
    0 => array:1 [
      "a" => 3,
      "b" => 3
    ]
    1 => array:1 [
      "a" => 3,
      "b" => 3
    ]
  ]

There is no way to exclue b from the array and it will cause the following error:

Message
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'base_require' in 'field list' (SQL: insert into product_variation_unit (base, base_require, max, min, name, product_variation_id, unit_id) values (1000, ?, 10000, 1000, کیلو, 2036, 1))
Level
ERROR
Exception
{
   "class": "Illuminate\\Database\\QueryException",
   "message": "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'base_require' in 'field list' (SQL: insert into product_variation_unit (base, base_require, max, min, name, product_variation_id, unit_id) values (1000, ?, 10000, 1000, \u06a9\u06cc\u0644\u0648, 2036, 1))",
   "code": "42S22",

Discussion about it: https://stackoverflow.com/questions/58851288/using-validated-method-with-array-in-laravel

Wrong return type?

Under the single responsibility principle "good" example, should the return type for getFullNameAttribute() be "string" and not "bool"?

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

Pivot table naming convention

Hi @alexeymezenin

Thank you for your work and setting all this gems in one place.
Whenever I have chance I point people on SO to this.

Can you tell something about my doubt here:

Having products and product_attributes tables should pivot be product_product_attribute or product_attribute_product still following alphabetical convention?

Thanks, Goran

Naming convention for Request classes

Is there a particular convention that should be followed for Request classes? For example, if I need different Request class for store and update, instead of PostRequest, what should I name my Request classes?

NewPostRequest and UpdatePostRequest ?
PostNewRequest and PostUpdateRequest ?
StorePostRequest and UpdatePostRequest ?
PostStoreRequest and PostUpdateRequest ?

Something else entirely?

should laravel controllers/views sub-dir be singular or plural

Laravel UI build-in:

should controllers/views sub-dir be singular or plural?

for example: https://github.com/settings/profile

  • controllers path: Controllers/Settings/ProfileController.php or Controllers/Setting/
  • views path: views/settings/profile.blade.php or views/setting/
  • route name: settings.profile or setting.profile

image

pivotTables

the only issue i have is with pivot_tables.. most times you want to name them so when you look at your tables in database you know what they are.. user_article may not tell you but something like users_favourited_article etc will

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.