Image generated with Dall-E 2

How I Optimize My PHP Code

Serghei Pogor
6 min readApr 21, 2024

--

As a senior PHP developer, I’ve seen my fair share of cluttered scripts, and I’m here to help you steer clear of them.

Let’s tackle one of the classic issues many newcomers face: handling arrays efficiently.

Arrays are fundamental in PHP, right?

They hold our data like little treasure chests. Imagine you’re working on an inventory system for a bookstore, where you need to filter out all books that are currently in stock from a larger list.

Here’s a sleek way to do it with PHP 8.3:

$books = [
['title' => 'The Great Gatsby', 'inStock' => true],
['title' => '1984', 'inStock' => false],
['title' => 'To Kill a Mockingbird', 'inStock' => true],
];

$inStockBooks = array_filter($books, fn($book) => $book['inStock']);
print_r($inStockBooks);

This snippet uses the arrow function (fn()) introduced in PHP 7.4, which we continue to love in PHP 8.3. It makes the code super concise and readable!

Now, let’s get a bit quirky with a real-world issue — avoiding NULL confusion.

It’s like expecting a text back but getting ghosted instead 😅. To handle potential NULL values in data you might receive from a database or user input, PHP 8.1 introduced a lifesaver: the null-safe operator.

Let’s say you need to get a user’s profile picture URL, but not all users have set one:

$user = [
'name' => 'Alice',
'profile' => [
'picture' => null
]
];

$pictureUrl = $user['profile']['picture'] ?? 'default-avatar.png';
echo $pictureUrl;

This ?? is the null coalesce operator, and it checks if something exists or not, providing a fallback if it doesn't. Clean, right?

Organizing Code with Single Responsibility Principles

A key principle in keeping your code clean is ensuring that each function or class has a single responsibility.

This means that every module or function should only have one reason to change. Here’s how you might apply this principle:

function createUser($userData) {
if (!validateUser($userData)) {
return false;
}
saveUser($userData);
return true;
}

function validateUser($userData) {
// Validate user data
return true; // Assume data is valid for simplicity
}
function saveUser($userData) {
// Logic to save user data to a database
}

Breaking down functions into smaller, purpose-focused units makes them easier to manage, test, and debug.

Refactoring Nested Conditionals

Nested conditionals can make your code hard to read and maintain. Refactoring these into clearer logic can dramatically clean up your code. Here’s an example:

function processDiscount($order) {
if ($order->customer->isVIP()) {
if ($order->amount > 1000) {
return 0.10; // 10% discount
}
return 0.05; // 5% discount
}
return 0; // no discount
}

This could be refactored to:

function processDiscount($order) {
if (!$order->customer->isVIP()) {
return 0; // no discount
}
return ($order->amount > 1000) ? 0.10 : 0.05;
}

This refactoring reduces the depth of nesting and improves the readability of your code.

Use Meaningful Variable Names

One of the simplest yet most impactful ways to clean up your PHP code is by using meaningful variable names.

Forget about short, cryptic names like $x or $data. Instead, name your variables descriptively:

$customerList = ['Alice', 'Bob', 'Charlie'];
$totalCustomers = count($customerList);
echo "Total customers: " . $totalCustomers;

In this example, $customerList and $totalCustomers clearly tell us what the variables represent, making the code self-explanatory.

Adopt Consistent Indentation and Spacing

Consistency is key in making your code readable. Adopt a style guide and stick to it. Whether you prefer 2 spaces or 4 spaces for indentation, use it consistently throughout your project. Also, add spaces around operators to make the code more readable:

for ($i = 0; $i < 10; $i++) {
echo $i;
}

This clean and consistent formatting helps differentiate between different blocks of code and improves readability.

Utilize PHPDoc for Documentation

Documenting your functions with PHPDoc can vastly improve understanding and maintenance of your code.

It provides a clear outline of what each function does, its parameters, and its return type:

/**
* Calculate the sum of two numbers.
*
* @param int $a First number
* @param int $b Second number
* @return int Sum of $a and $b
*/
function sum($a, $b) {
return $a + $b;
}

This documentation helps other developers understand the purpose and usage of your functions quickly and accurately.

Refactor Repeated Code into Functions

If you find yourself writing the same code multiple times, it’s a good candidate for refactoring into a function.

This not only cleans up your code by reducing repetition but also makes it easier to manage:

function greetUser($name) {
return "Hello, $name!";
}

echo greetUser('Alice');
echo greetUser('Bob');

This function greetUser can be reused throughout your application, keeping your code DRY (Don't Repeat Yourself).

Embrace Modern PHP Features

Modern PHP versions (7.x and above) offer many features that can help you write cleaner and more efficient code. For instance, using type declarations makes your code more predictable and robust:

function addNumbers(float $a, float $b): float {
return $a + $b;
}

Type declarations prevent incorrect data types from being passed to functions, reducing bugs and making the codebase more reliable.

Decompose Large Functions

Large functions that try to do too much can be hard to understand and maintain. A cleaner approach is to break them into smaller, more focused functions.

This not only makes them easier to manage but also promotes reusability.

Before:

function processUserData($data) {
if ($data['age'] < 18) {
return 'Error: User is underaged.';
}
saveToDatabase($data);
sendWelcomeEmail($data['email']);
return 'User registered successfully.';
}

After:

function checkAge($age) {
return $age >= 18;
}

function registerUser($data) {
if (!checkAge($data['age'])) {
return 'Error: User is underaged.';
}
saveToDatabase($data);
sendWelcomeEmail($data['email']);
return 'User registered successfully.';
}

Breaking down the processUserData function into checkAge and registerUser not only clarifies the workflow but also isolates each function’s responsibilities.

Refine Logic with Early Returns

Using early returns in your functions can simplify their structure by reducing nesting and making the flow easier to follow.

Before:

function calculateDiscount($customer) {
$discount = 0;
if ($customer['type'] == 'VIP') {
if ($customer['years'] > 5) {
$discount = 20;
} else {
$discount = 10;
}
}
return $discount;
}

After:

function calculateDiscount($customer) {
if ($customer['type'] != 'VIP') {
return 0;
}
return ($customer['years'] > 5) ? 20 : 10;
}

The revised function uses early returns and a ternary operator, which simplifies the decision-making process.

Utilize Object-Oriented Programming

Adopting an object-oriented programming (OOP) approach can significantly clean up your PHP code.

OOP allows you to encapsulate and organize your code in a way that is both manageable and scalable.

class User {
private $name;
private $email;

public function __construct($name, $email) {
$this->name = $name;
$this->email = $email;
}

public function sendWelcomeEmail() {
echo "Sending welcome email to " . $this->email;
// Email sending logic
}
}

$user = new User("John Doe", "john@example.com");
$user->sendWelcomeEmail();

Using classes and objects helps you manage related data and functionalities, keeping your code modular and clean.

Implement Design Patterns

Design patterns are templates for solving common design problems. They can help standardize and simplify your approach to certain coding challenges, ensuring that your code is cleaner and easier to understand.

Singleton Pattern:

class Database {
private static $instance;

private function __construct() {}
public static function getInstance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
}
$db = Database::getInstance();

Singleton ensures that a class has only one instance and provides a global point of access to it, which is particularly useful for managing database connections.

Writing clean code isn’t just a technical requirement; it’s a foundational aspect of professional software development that affects collaboration, maintainability, and the overall quality of software.

Tools and methodologies will change, but the principles of clarity, simplicity, and efficiency remain constant.

By committing to these principles, you ensure that your codebase is not just a collection of scripts but a well-crafted software that stands the test of time.

Remember, clean code is not achieved in a day. It results from continuous learning, meticulous practice, and a proactive approach to adapting best practices.

Keep exploring, keep refining, and let every line of code you write be a step towards mastery.

Happy coding!

🔔 Click Subscribe to catch more coding fun.
👏🏻 Love it? Give a big clap.
💬 Got a cool idea or funny coding joke? Drop it in the comments.

Share these tips with your fellow developers to help each other succeed together.

Thanks for hanging out and reading. You rock! 🚀

Hold on a sec!!! Want more of my fun stuff in your inbox? Sign up here! 📩

--

--