Describes PHP and Laravel guidelines provided by Spatie. These rules result in more maintainable, and readable code.
53
60%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./config/claude/skills/php-guidelines-from-spatie/SKILL.mdFollow Laravel conventions first. If Laravel has a documented way to do something, use it. Only deviate when you have a clear justification.
?string not string|nullvoid return types when methods return nothingvoid?Type not Type|null/** @return Collection<int, User> */
public function getUsers(): Collectionuse \Spatie\Url\Url;
/** @return Url *//** @var string *//** @var Collection|SomeWeirdVendor\Collection *//**
* @param array<int, MyObject> $myArray
* @param int $typedArgument
*/
function someFunction(array $myArray, int $typedArgument) {}/** @return array{
first: SomeClass,
second: SomeClass
} */if statements that use && into nested if statements for better readability// Happy path last
if (! $user) {
return null;
}
if (! $user->isActive()) {
return null;
}
// Process active user...
// Short ternary
$name = $isFoo ? 'foo' : 'bar';
// Multi-line ternary
$result = $object instanceof Model ?
$object->name :
'A default value';
// Ternary instead of else
$condition
? $this->doSomething()
: $this->doSomethingElse();
// Bad: compound condition with &&
if ($user->isActive() && $user->hasPermission('edit')) {
$user->edit();
}
// Good: nested ifs
if ($user->isActive()) {
if ($user->hasPermission('edit')) {
$user->edit();
}
}/open-source)->name('openSource')){userId})[Controller::class, 'method']PostsController)index, create, store, show, edit, update, destroy)pdf-generator.php)chrome_path)config/services.php, don't create new filesconfig() helper, avoid env() outside config filesdelete-old-records)$this->comment('All ok!'))$items->each(function(Item $item) {
$this->info("Processing item id `{$item->id}`...");
$this->processItem($item);
});
$this->comment("Processed {$items->count()} items.");Be very critical about adding comments as they often become outdated and can mislead over time. Code should be self-documenting through descriptive variable and function names.
Adding comments should never be the first tactic to make code readable.
Instead of this:
// Get the failed checks for this site
$checks = $site->checks()->where('status', 'failed')->get();Do this:
$failedChecks = $site->checks()->where('status', 'failed')->get();Guidelines:
{} bracketspublic function rules() {
return [
'email' => ['required', 'email'],
];
}Validator::extend('organisation_type', function ($attribute, $value) {
return OrganisationType::isValid($value);
});@if($condition)
Something
@endifGate::define('editPost', ...)view instead of show__() function over @lang:/errors/error-occurrences/error-occurrences/1
/errors/1/occurrencesit/test blocks (the tests should read first; helpers are support detail)UserController, OrderStatus)getUserName, $firstName)/open-source, /user-profile)pdf-generator.php)chrome_path)php artisan delete-old-records)Controller (PostsController)openSource.blade.php)CreateUser, SendEmailNotification)UserRegistering, UserRegistered)Listener suffix (SendInvitationMailListener)Command suffix (PublishScheduledPostsCommand)Mail suffix (AccountActivatedMail)Resource/Transformer (UsersResource)OrderStatus, BookingType)else statements when possibleif conditions using && into nested if statementsuse statements — never use inline fully qualified class names (e.g. \Exception, \Illuminate\Support\Facades\Http)$exception not $e, $request not $r)d0073bc
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.