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

  • 953