PHP arrays are flexible and easy to use. They can store lists, key-value pairs, and complex data structures. However, some array operations become inefficient when working with large collections or processing data repeatedly.
A few unnecessary operations might not matter in a small script, but they can noticeably affect performance when handling thousands of records.
In this guide, you'll learn how to avoid inefficient array operations in PHP, reduce unnecessary processing, and write code that performs better without sacrificing readability.
1. Avoid Repeated array_merge() Calls
The array_merge() function combines arrays. It's useful when you need to merge collections, but repeatedly calling it inside a loop can create unnecessary overhead.
Consider this inefficient approach:
<?php
$numbers = [];
for ($i = 1; $i <= 1000; $i++) {
$numbers = array_merge($numbers, [$i]);
}
Each iteration creates a new merged array, repeatedly processing elements already collected.
When you simply want to add an element, use [] instead:
<?php
$numbers = [];
for ($i = 1; $i <= 1000; $i++) {
$numbers[] = $i;
}
This approach appends each value directly to the array without rebuilding the entire collection.
Recommendation: Use [] for appending individual elements. Reserve array_merge() for situations where you actually need to combine arrays.
2. Avoid Searching the Same Array Repeatedly
Functions such as in_array() and array_search() examine array values to find a match.
They're perfectly suitable for many tasks, especially with small arrays.
However, repeatedly searching a large array can become expensive because each search may need to examine many elements.
For frequent membership checks, consider building an associative array that uses the values as keys.
<?php
$allowedActions = [
"create",
"edit",
"delete"
];
// Build a lookup array once.
$allowedLookup = array_fill_keys(
$allowedActions,
true
);
// Check whether an action is allowed.
if (isset($allowedLookup["edit"])) {
echo "Action allowed.";
}
Output:
Action allowed.
Associative array key lookups are typically very efficient, making this approach useful when checking many values against the same collection.
Remember that isset() returns false when a key contains null. Use array_key_exists() when you need to distinguish a missing key from one containing null.
3. Avoid Expensive Array Modifications Inside Loops
Some array functions need to reorganize existing elements.
For example, array_shift() removes the first element of an array and reindexes its numeric keys.
Repeatedly removing the first element from a large array can therefore be inefficient.
If you're processing a list from beginning to end without needing to remove elements, a simple foreach loop is usually clearer:
<?php
$tasks = [
"Backup files",
"Check updates",
"Review logs"
];
foreach ($tasks as $task) {
echo $task . PHP_EOL;
}
If your application frequently adds and removes items from a queue, consider PHP's SplQueue class, which is designed for queue operations.
Similarly, avoid repeatedly sorting an array or calling array_unique() inside a loop when the operation can be performed once after collecting the data.
4. Avoid Creating Unnecessary Intermediate Arrays
Functions such as array_map() and array_filter() are useful and can make code easier to read.
However, chaining several array transformations may create additional arrays that consume memory.
For example, if you need to filter and transform a large collection only once, combining both operations into a single loop may reduce temporary allocations.
<?php
$prices = [10, 25, 5, 40];
$discounted = [];
foreach ($prices as $price) {
if ($price >= 20) {
$discounted[] = $price * 0.9;
}
}
print_r($discounted);
Output:
Array
(
[0] => 22.5
[1] => 36
)
This example filters the prices and calculates discounts in one pass.
That doesn't mean array_map() or array_filter() should be avoided. Use them when they make your code clearer, and consider alternatives when profiling reveals excessive memory usage or processing overhead.
5. Practical Example: Processing Orders Efficiently
Imagine an online store that needs to calculate order totals using product information.
A common inefficient approach is to loop through the entire product catalog for every order item until the matching product is found.
A better solution is to create a lookup array indexed by product ID.
Create a file named orders.php:
<?php
declare(strict_types=1);
// Product catalog.
$products = [
[
"id" => 101,
"name" => "Keyboard",
"price_cents" => 4500
],
[
"id" => 102,
"name" => "Mouse",
"price_cents" => 2000
]
];
// Items in the order.
$orders = [
["product_id" => 102, "quantity" => 2],
["product_id" => 101, "quantity" => 1]
];
// Create a product lookup once.
$productsById = [];
foreach ($products as $product) {
$productsById[$product["id"]] = $product;
}
// Process the order.
$totalCents = 0;
foreach ($orders as $order) {
$productId = $order["product_id"];
if (!isset($productsById[$productId])) {
throw new RuntimeException(
"Unknown product ID."
);
}
$product = $productsById[$productId];
$subtotalCents =
$product["price_cents"] * $order["quantity"];
$totalCents += $subtotalCents;
$label = $product["name"]
. " x "
. $order["quantity"]
. ": $"
. number_format($subtotalCents / 100, 2);
echo "<p>" . htmlspecialchars(
$label,
ENT_QUOTES,
"UTF-8"
) . "</p>";
}
echo "<p>Total: $"
. number_format($totalCents / 100, 2)
. "</p>";
Browser output:
Mouse x 2: $40.00
Keyboard x 1: $45.00
Total: $85.00
Instead of searching the entire product array for every order item, the code builds $productsById once and retrieves products directly by their IDs.
This changes the typical lookup work from repeatedly scanning the catalog to using efficient associative key access.
The example also stores prices as integer cents to avoid common floating-point precision issues in monetary calculations.
For simplicity, the order data is predefined. A real application should validate product IDs and quantities before calculating totals.
Common PHP Array Performance Mistakes
| Inefficient Approach | Better Alternative |
|---|---|
Calling array_merge() for every appended element |
Use $array[] = $value. |
| Repeatedly searching a large array | Build an associative lookup array. |
| Repeatedly removing the first array element | Use foreach or SplQueue, depending on the task. |
| Sorting the same data on every iteration | Sort once when appropriate. |
| Creating many unnecessary temporary arrays | Consider combining operations into one loop. |
Performance tip: Don't assume every shorter expression is faster. For example, count($array) is a constant-time operation for normal PHP arrays, so moving it outside a loop generally isn't a meaningful optimization by itself.
Measure real bottlenecks before making performance changes. Tools such as microtime(true) and memory_get_peak_usage() can help with basic measurements, while profilers provide more detailed information.
Key Takeaways
- Use
[]to append elements instead of repeatedly merging arrays. - Use associative arrays for frequent lookups by a known key.
- Avoid repeated operations that reorganize large arrays unnecessarily.
- Reduce temporary arrays when memory usage becomes significant.
- Choose the simplest data structure that fits the task.
- Profile performance before introducing optimizations that make code harder to maintain.
Efficient PHP array handling is mainly about avoiding unnecessary work. By choosing appropriate lookup structures, reducing repeated operations, and keeping loops straightforward, you can improve performance while maintaining readable, reliable code.