DEV Community

Cover image for How to write a different PHP?
Adnan Babakan (he/him)
Adnan Babakan (he/him)

Posted on • Updated on

How to write a different PHP?

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
function greet_user(User $user, int $age): void {
    echo "Hello" . $user->first_name . " " . $user->last_name;
    echo "\nYou are " . $age . " years old";
}
Enter fullscreen mode Exit fullscreen mode

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
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,
        ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

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
$age = 17;
if($age >= 18) {
    $type = 'adult';
} else {
    $type = 'not adult';
}
Enter fullscreen mode Exit fullscreen mode

This code can be shortened to the code below using a ternary operator:

<?php
$age = 17;
$type = $age >= 18 ? 'adult' : 'not adult';
Enter fullscreen mode Exit fullscreen mode

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
$url = 'http://example.com/api';
$base_url = $url ? $url : 'http://localhost';
Enter fullscreen mode Exit fullscreen mode

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
$url = 'http://example.com/api';
$base_url = $url ?: 'http://localhost';
Enter fullscreen mode Exit fullscreen mode

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
$base_url = $url ?? 'http://localhost';
Enter fullscreen mode Exit fullscreen mode

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
$url = false;
$base_url = $url ?? 'http://localhost';
Enter fullscreen mode Exit fullscreen mode

Using this operator you can check if a variable is defined previously and if not assign it a value:

<?php
$base_url = 'http://example.com';
$base_url = $base_url ?? 'http://localhost';
Enter fullscreen mode Exit fullscreen mode

You can shorten this code using null coalescing assignment operator

<?php
$base_url = 'http://example.com';
$base_url ??= 'http://localhost';
Enter fullscreen mode Exit fullscreen mode

All these nall coalescing techniques can be implemented on array values as well.

<?php
$my_array = [
    'first_name' => 'Adnan',
    'last_name' => 'Babakan'
];

$my_array['first_name'] ??= 'John';
$my_array['age'] ??= 20;
Enter fullscreen mode Exit fullscreen mode

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
echo 5 <=> 3; // result: 1
echo -7 <=> -7; // result: 0
echo 9 <=> 15; // result: -1
Enter fullscreen mode Exit fullscreen mode

Pretty simple but very useful.

This gets more interesting when you realize that the spaceship operator can compare other things as well:

<?php
// String
echo 'c' <=> 'b'; // result: -1

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

// Array
echo [5, 6] <=> [2, 7]; // result: 1
Enter fullscreen mode Exit fullscreen mode

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
$pi = 3.14;
$sphere_volume = function($r) {
    return 4 / 3 * $pi * ($r ** 3);
};

echo $sphere_volume(5);
Enter fullscreen mode Exit fullscreen mode

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
$pi = 3.14;
$sphere_volume = function($r) use ($pi) {
    return 4 / 3 * $pi * ($r ** 3);
};

echo $sphere_volume(5);
Enter fullscreen mode Exit fullscreen mode

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
$pi = 3.14;
$sphere_volume = fn($r) => 4 / 3 * $pi * ($r ** 3);

echo $sphere_volume(5);
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (21)

Collapse
erhankilic profile image
Erhan Kılıç • Edited on

I never use arrow function. If I wanted to use javascript, I would use it not php. Arrow function destoys the readabilty of the code.
I don't like using everything if it's new, you need to think about it if it's worth or not.

Collapse
adnanbabakan profile image
Adnan Babakan (he/him) Author

Hi Erhan
PHP and JavaScript are different and I don't think only just because you want to use arrow functions you would switch to JavaScript.
On the opposite hand, I think arrow functions increase the readability.

Collapse
erhankilic profile image
Erhan Kılıç

Well, If you work on your own project alone it can be ok but real world isn't like that. You can work with a team on a big project and it can be really really messy with arrow function.
I know it because I worked on a big javascript project with a big team and arrow function makes it really mess in my opinion.
Right now my php team doesn't allow using arrow function and I'm happy about it.

Thread Thread
adnanbabakan profile image
Adnan Babakan (he/him) Author

I respect your opinion but really disagree about being messy since arrow functions are made to make code more clear if your function is not that much complicated. If you wanted to use a global variable in PHP you should GLOBAL or $_GLOBAL which is not needed in arrow functions.

Collapse
patabah profile image
PatAbah

For functions that perform simple operations, I'll rather a bunch of arrow functions instead.
IMO, It makes such functions more readable 😁

Collapse
rehmatfalcon profile image
Kushal Niroula

It would have been much more useful if the arrow syntax could be used for multiline function.

I actually like that it closes over the value of the enclosing scope. It would have been much more useful when creating an anonymous function that uses data from the enclosing scope.

<?php
function create($name,$age) {
    $this->em->transactional(fn() {
        $person = new Person($name,$age);
        $this->em->persist($person);
        $this->em->flush();
    });
}
Collapse
adnanbabakan profile image
Adnan Babakan (he/him) Author • Edited on

Yes, it would have been awesome. Maybe in the later version, they will add such a feature.

Collapse
jinoantony profile image
Jino Antony

It would be helpful if you can add the PHP version from which each feature is available. I think most features you mentioned only available in PHP 7.4

Collapse
dwilmer profile image
Daan Wilmer

New in 7.4 are the arrow functions and the $foo ??= 'bar; assignment. 7.2 brought class-based type hinting and return types, and everything else was included in 7.0 - including $too = $foo ?? 'bar'; and scalar type hinting.

Collapse
easrng profile image
easrng

I love that a

✨Spaceship operator 🚀

exists.

Collapse
biros profile image
Boris Jamot ✊ /

Nice post, thanks!

Collapse
davidfrafael profile image
David Fernández

Doesn't Laravel automatically trim the values of the request?

Collapse
adnanbabakan profile image
Adnan Babakan (he/him) Author

For some reason sometimes there is an inconsistency. That's why I added another layer or triming. LOL

Collapse
zahedomid profile image
OmidZahed

so cool

Collapse
chuckych profile image
Norberto CH

Muy Bueno... Gracias.

Collapse
adnanbabakan profile image
Adnan Babakan (he/him) Author

Gracias para leer mi articulo. xD

Collapse
karimboudjema profile image
Karim Boudjema

Don't forget you can also assign values in the assignment part:
$type = ($age >= 18) ? 'adult' : 'no adult';
is the same as
($age >= 18) ? $type = 'adult' : $type = 'no adult';

Collapse
detzam profile image
webstuff • Edited on

The single question that i have, cuz i m lazy at the moment, is this a 7.x feature? Or is it possible on 5.6.x , too?

Collapse
adnanbabakan profile image
Adnan Babakan (he/him) Author

Hi
I believe they are 7.x features.

Collapse
xenialdan profile image
Dan

$base_url = $url ? $url : 'localhost';

shouldn't that be

$base_url === $url ? $url : 'localhost';

otherwise the condition will always be true because you assign a variable..

Collapse
adnanbabakan profile image
Adnan Babakan (he/him) Author

Hi Dan
Not it is not a condition, it is an assignment statement.