How to write a different PHP?
Tags: php
Published: 2020-05-10 11:59:57

Hey there DEV.to community.

PHP is one of the most discussed programming languages out in the development world. Some people call it a dead programming language, some call it a disgusting programming language which has no convention or architecture, which I agree with some of them because they've got fair points. But here I'm going to share some of my experience with PHP that I got all these years programming in PHP. Some of these tips are only available in most recent PHP versions so they might not work in older versions.

# Type hinting and return types

PHP isn't a perfect language when it comes to data types but you can improve your code quality and prevent further type conflicts by using type hinting and return types. Not many people use these features of PHP and not all PHP programmers know that it is possible.
```php
<?php
function greet_user(User $user, int $age): void {
    echo "Hello" . $user->first_name . " " . $user->last_name;
    echo "\nYou are " . $age . " years old";
}
```

A type hinting can be declared using a type's name or a class before the argument variable and a return type can be declared after the function's signature following a colon sign.

A more advanced use of this can be when you are designing your controllers in a framework like Laravel:
```php
<?php
class UserController extends Controller
{
    // User sign up controller
    public function signUp(Request $request): JsonResponse
    {
        // Validate data
        $request->validate([
            'plateNumber' => 'required|alpha_num|min:3|max:20|unique:users,plate_number',
            'email' => 'required|email|unique:users',
            'firstName' => 'required|alpha',
            'lastName' => 'required|alpha',
            'password' => 'required|min:8',
            'phone' => 'required|numeric|unique:users'
        ]);

        // Create user
        $new_user = new User;

        $new_user->plate_number = trim(strtoupper($request->input('plateNumber')));
        $new_user->email = trim($request->input('email'));
        $new_user->first_name = trim($request->input('firstName'));
        $new_user->last_name = trim($request->input('lastName'));
        $new_user->password = Hash::make($request->input('password'));
        $new_user->phone = trim($request->input('phone'));

        $new_user->save();

        return response()->json([
            'success' => true,
        ]);
    }
}
```

# Ternary operator and a shorter way

Ternary operator is a thing that almost 70% of programmers know about and use it widely but in case you don't know what a ternary operator is see the example below:
```php
<?php
$age = 17;
if($age >= 18) {
    $type = 'adult';
} else {
    $type = 'not adult';
}
```

This code can be shortened to the code below using a ternary operator:
```php
<?php
$age = 17;
$type = $age >= 18 ? 'adult' : 'not adult';
```

If the condition is met the first string will be assigned to the variable if not the second part will be.

There is also a shorter way if you want to use the value of your condition if it is evaluated to a truly value.
```php
<?php
$url = 'http://example.com/api';
$base_url = $url ? $url : 'http://localhost';
```

As you can see `$url` is used both as the condition and as the result of the condition being true. In that case, you can escape the left-hand operand:
```php
<?php
$url = 'http://example.com/api';
$base_url = $url ?: 'http://localhost';
```

# Null coalescing operator

Just like a ternary operator you can use a null coalescing operator to see if a value exists, note that existing is different than a falsely value since false is a value itself.
```php
<?php
$base_url = $url ?? 'http://localhost';
```

Now `$base_url` is equal to `http://localhost` but if we define `$url` even as false the `$base_url` variable will be equal to false.
```php
<?php
$url = false;
$base_url = $url ?? 'http://localhost';
```

Using this operator you can check if a variable is defined previously and if not assign it a value:
```php
<?php
$base_url = 'http://example.com';
$base_url = $base_url ?? 'http://localhost';
```

You can shorten this code using null coalescing assignment operator
```php
<?php
$base_url = 'http://example.com';
$base_url ??= 'http://localhost';
```
All these nall coalescing techniques can be implemented on array values as well.
```php
<?php
$my_array = [
    'first_name' => 'Adnan',
    'last_name' => 'Babakan'
];

$my_array['first_name'] ??= 'John';
$my_array['age'] ??= 20;
```
The array above will have the `first_name` as `Adnan` since it is already defined but will define a new key named `age` and assign the number `20` to it since it doesn't exist.

# Spaceship operator

Spaceship operator is a pretty useful operator when it comes to comparison when you want to know which operand is larger rather than only knowing if one side is larger.

A spaceship operator will return one of the `1`, `0` or `-1` values when the left-hand operand is larger, when both operands are equal and when the right-hand operand is larger respectively.
```php
<?php
echo 5 <=> 3; // result: 1
echo -7 <=> -7; // result: 0
echo 9 <=> 15; // result: -1
```

Pretty simple but very useful.

This gets more interesting when you realize that the spaceship operator can compare other things as well:
```php
<?php
// String
echo 'c' <=> 'b'; // result: -1

// String case
echo 'A' <=> 'a'; // result: 1

// Array
echo [5, 6] <=> [2, 7]; // result: 1
```

# Arrow functions
If you have ever programmed a JavaScript application especially using recent versions of it you should be familiar with arrow functions. An arrow function is a shorter way of defining functions that they have no scope.
```php
<?php
$pi = 3.14;
$sphere_volume = function($r) {
    return 4 / 3 * $pi * ($r ** 3);
};

echo $sphere_volume(5);
```

The code above will throw an error since the `$pi` variable is not defined in this particular function's scope. If we wanted to use it we should change our function a bit:
```php
<?php
$pi = 3.14;
$sphere_volume = function($r) use ($pi) {
    return 4 / 3 * $pi * ($r ** 3);
};

echo $sphere_volume(5);
```

So now our function can use the `$pi` variable defined in the global scope.
But a shorter way of doing all this stuff is by using the arrow functions.
```php
<?php
$pi = 3.14;
$sphere_volume = fn($r) => 4 / 3 * $pi * ($r ** 3);

echo $sphere_volume(5);
```

As you can see it is pretty simple and neat and has access to global scope by default.

---
I hope you enjoyed this article, and I'm also planning on continuing this article and make it a series.

Tell me if I missed something or any other idea you have in the comments section below.