Describes PHP and Laravel guidelines provided by Spatie. These rules result in more maintainable, and readable code.
59
Quality
49%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Optimize this skill with Tessl
npx tessl skill review --optimize ./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/occurrencesUserController, 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)355d067
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.