Code that Speaks
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
-- Martin Fowler, "Refactoring: Improving the Design of Existing Code"
90% of coding is debugging. The other 10% is writing bugs.
-- Anonymous
1. Avoid meaningless words
2. Strive for consistency
3. Don't make my brain hurt
4. Name according to scope
5. Don't make me look things up
1. Avoid meaningless words
words that put my brain sleep....
1. Avoid meaningless words
$data
1. Avoid meaningless words
$data
$data = ['id' => 1];
$client->get('/user', $data);
$payload = ['id' => 1];
$client->get('/user', $payload);
1. Avoid meaningless words
$items
$items = getNavLinks();
foreach($items as $item) {...}
$links = getNavLinks();
foreach($links as $link) {...}
1. Avoid meaningless words
Drop the type suffix
$namesArray = ['John', 'Doe'];
$names = ['John', 'Doe'];
$createdAtTimestamp = new DateTime;
$createdAt = new DateTime;
1. Avoid meaningless words
Hungarian Notation
$aNames = ['Corona', 'Budweiser'];
$sName = 'Heineken';
$iAge = 23;
$names = ['Corona', 'Budweiser'];
$name = 'Heineken';
$age = 23;
1. Avoid meaningless words
Service classes
$mailService = new MailService;
$mailService->send($message);
$mailer = new Mailer;
$mailer->send($message);
1. Avoid meaningless words
$things1, $things2
$user1 = factory(User::class);
$user2 = factory(User::class);
login($user1);
$this->assertTrue($user1->loggedIn());
$this->assertFalse($user2->loggedIn());
$user = factory(User::class);
$visitor = factory(User::class);
login($user);
$this->assertTrue($user->loggedIn());
$this->assertFalse($visitor->loggedIn());
1. Avoid meaningless words
2. Strive for consistency
2. Strive for consistency
echo $blog->body;
echo $comment->text;
echo $testimonial->content;
Pick a word and stick with it
echo $blog->body;
echo $comment->body;
echo $testimonial->body;
2. Strive for consistency
$post->image;
$user->photo;
$tag->thumbnail;
Pick a word and stick with it
$post->image;
$user->image;
$tag->image;
1. Avoid meaningless words
2. Strive for consistency
3. Don't make my brain hurt
3. Don't make my brain hurt
Abbreviations I'm OK with...👍
auth
admin
id
db
i
int, bool
e
authentication
administration
identifier
database
iteration
integer, boolean
exception
3. Don't make my brain hurt
Abbreviations I'm not OK with...👎
addr
attr
err
arr
opt
msg
img
address
attribute
error
array
option
message
image
3. Don't make my brain hurt
Dates
(new DateTime)
->setDate(date('Y'), date('m'), 1)
->setTime(12, 0 ,0);
new DateTime('first day of this month midnight');
3. Don't make my brain hurt
Ugh!😩 Regex
preg_replace('/\s\s+/', ' ', $title);
stripeOutExtraWhiteSpace($title);
3. Don't make my brain hurt
Negatives...👎
if (! $post->isExpired()) {...}
if ($post->isActive()) {...}
1. Avoid meaningless words
2. Strive for consistency
3. Don't make my brain hurt
4. Name according to scope
4. Name according to scope
Your names may be telling you that your code is ready for a refactoring.
4. Name according to scope
Compound variable names
$transactionId;
$transactionName;
$transactionAmount;
$transaction->id;
$transaction->name;
$transaction->amount;
1. Avoid meaningless words
2. Strive for consistency
3. Don't make my brain hurt
4. Name according to scope
5. Don't make me look things up
5. Don't make me look things up
Bare parameters
new HttpRequest(500);
new HttpRequest($timeOutInSeconds = 500);
json_decode($json, true);
json_decode($json, $returnArray = true);
5. Don't make me look things up
Bare integer
$response = $request->post('/users', $payload);
$this->assertEquals(201, $response->statusCode());
class HttpStatus {
const CREATED = 201;
}
$response = $request->post('/users', $payload);
$this->assertEquals(HttpStatus::CREATED, $response->statusCode());
Readability > Optimization
- Optimization is great.
- In databases and other places where it actually makes a difference to response times.
- Premature optimization: you don't know if it will actually make a difference.
- Skipping a more verbal series of steps for a few shortcuts might shave off some milliseconds, but it adds minutes to the next time you try to debug what you wrote.
Choosing words is fun and creative.
GIF break...
Laravel Tips & Tricks
Laravel Tips & Tricks
dd() a collection like a pro...😎
dd(Users::where('name', 'test')->get()->pluck('id'));
Users::where('name', 'test')
->get()
->dd()
->pluck('id')
->dd();
Laravel Tips & Tricks
dd() a collection like a pro...😎
// App\Providers\AppServiceProvider@register()
Collection::macro('dd', function () {
dd($this);
});
P.S. Added in L5.5 out of the box
Laravel Tips & Tricks
@push and @stack
// layouts/master.blade.php
@stack('javascript')
// blog/index.blade.php
@push('javascript')
<script>
// blog based javascript
</script>
@endpush
Laravel Tips & Tricks
Return null instead of ErrorException when trying to get property of non-object
$user->city->state->name;
$user->city->state ? $user->city->state->name : '';
$user->city ? ($user->city->state ? $user->city->state->name : '') : '';
array_get($user, 'city.state.name', '');
Laravel Tips & Tricks
Reshape an array...
$me = [
"user.name" => "Amit",
"user.email" => "aka@gmail.com",
"payment.id" => "9",
"payment.amount" => "786",
];
$me = [
"user" => [
"name" => "Amit",
"email" => "aka@gmail.com",
],
"payment" => [
"id" => "9",
"amount" => "786",
],
]
Laravel Tips & Tricks
Reshape an array...
function array_reshape($array)
{
$results = [];
foreach ($array as $key => $value) {
array_set($results, $key, $value);
}
return $results;
}
array_reshape($me)
Laravel Tips & Tricks
Get the latest relationship...
// returns collection
public function comments()
{
return $this->hasMany(Comment::class);
}
// returns object
public function latestComment()
{
return $this->hasOne(Comment::class)->latest();
}
Laravel Tips & Tricks
Define a model to use for a many-to-many relationship pivot table...
Class Paper extends Model
{
public function tests()
{
return $this->belongsToMany(Test::class, 'sets')
->using(Set::class);
}
}
Laravel Tips & Tricks
life-saver - request()->query()
request()->query() // Returns only GET (query string) params
// Extremely useful when trying to preserve query params across requests
// Suppose current URL is:
"/posts?sort_column=name&sort_order=asc&start_date=01-01-99"
// Example: export table (with sorts and filters)
route('export-posts' , request()->query());
// Example: display pagination links (with sorts and filters)
$posts->appends(request()->query())->links()
Laravel Tips & Tricks
Clean things when route has one parameter...
// Instead of this...
return redirect()->route('products.edit', ['id' => $product->id]);
// ...you can just pass the model, no array needed at all:
return redirect()->route('products.edit' ,$product);
Laravel Tips & Tricks
Dead simple redirects...🤠
// AppServiceProvider@boot
Route::macro('redirect', function ($from, $to) {
return Route:get($from, function () use($to) {
return redirect($to) ;
});
});
// redirect from the root to a dashboard
Route::get('/admin', function () {
return redirect('/admin/dashboard');
});
// Ideal
Route::redirect('/admin', '/admin/dashboard');
Laravel Tips & Tricks
DRY up your ".env" files with variable nesting
OTHER_VARIABLE="some_value"
SOME_VARIABLE=${OTHER_VARIABLE}
Laravel Tips & Tricks
Database design tip...
$order->shipped = true;
$order->shipped = '2017-07-28 00:00:00';
$subscription->cancelled = true;
$subscription->cancelled = '2017-07-28 00:00:00';
$user->admin = true;
$user->admin = '2017-07-28 00:00:00';
Consider using date fields instead of booleans. It works the same way, and now you know when the TRUE state happened.
Laravel Tips & Tricks
Javascript tiny tip...
In Chrome `console.log(element)` just prints the markup. `console.dir(element)` gives you an object to inspect.
console.dir(document.getElementsByName('email')[0])
Laravel Tips & Tricks
Javascript tiny tip...
You don't need to uglify your code if it's already ugly!
Laravel Tips & Tricks
GIF break...
Problems
Problems
Importers - Imports the data from excel file
- Import the file only if each row passes the validation.
- Stop processing if there are errors more than the threshold limit.
Problems
Slug
public function handle($value, $attribute = 'slug')
{
$slug = str_slug($value);
// Look for exisiting slugs
$existingSlugs = $this->query->whereRaw("{$attribute} REGEXP '^{$slug}(-[0-9]*)?$'");
// If no matching slugs were found, return early
if ($existingSlugs->count() === 0) {
return $slug;
} else {
// Get slugs in reversed order, and pick the first
$lastSlugNumber = intval(
str_replace(
$slug . '-',
'',
$existingSlugs->orderBy('slug', 'desc')->first()->slug
)
);
return $slug . '-' . ($lastSlugNumber + 1);
}
}
Questions?
Thank You
Code that Speaks
By Amit Gupta
Code that Speaks
- 939