The Ultimate Guide to PHP Arrays (PHP 8.4+) - Every Function Explained
Thursday, July 9, 2026
Learn everything about PHP arrays: indexed, associative, multidimensional arrays, array_map(), array_filter(), array_reduce(), performance, best practices and real-world examples.
Table of Contents
- Introduction
- 1. What is an Array?
- 2. How PHP Arrays Work Internally
- 3. Indexed Arrays
- 4. Associative Arrays
- 5. Multidimensional Arrays
- 6. Iterating Arrays
- 7. Transforming Arrays
- 8. Combining Arrays
- 9. Sorting Arrays
- 10. Searching Arrays
- 11. Array Destructuring
- 12. Spread Operator
- 13. Performance
- 14. Common Mistakes
- 15. Best Practices
- 16. Real Production Examples
- 17. Frequently Asked Questions (FAQ)
- Are PHP arrays ordered?
- Are PHP arrays hash tables?
- What's the difference between indexed and associative arrays?
- Is array_map() faster than foreach?
- When should I use array_reduce()?
- Why does array_filter() remove 0 and empty strings?
- What's the difference between isset() and array_key_exists()?
- Does assigning an array create a copy?
- Why are PHP arrays so memory intensive?
- Should I use arrays or objects?
- Conclusion
Introduction
Every PHP developer uses arrays.
Whether you're reading data from a database, consuming a REST API, processing JSON, handling HTTP requests, or simply storing a list of values, arrays are everywhere. In fact, many of PHP's built-in features—including superglobals like $_GET, $_POST, and $_SERVER—are nothing more than arrays.
Yet, despite being one of the most frequently used data structures in the language, arrays are also one of the most misunderstood.
Many developers learn how to create an array and iterate over it with foreach, but stop there. They rarely explore the dozens of built-in array functions available in PHP, don't fully understand how arrays behave internally, and often write code that is slower, harder to read, or unnecessarily complex.
Understanding arrays at a deeper level changes the way you write PHP. Instead of thinking of them as simple containers of values, you'll start seeing them as one of the language's most powerful tools for transforming, organizing, and processing data efficiently.
In this guide, we'll cover everything you need to know about PHP arrays, including:
- Indexed, associative, and multidimensional arrays
- How arrays work internally
- Essential array functions
- Functional programming helpers such as
array_map(),array_filter(), andarray_reduce() - Performance considerations
- Common pitfalls
- Best practices used in production applications
All examples are written for PHP 8.4+, but most concepts also apply to earlier PHP versions.
Whether you're just getting started with PHP or you've been writing it for years, this article will help you write cleaner, more expressive, and more efficient code.
1. What is an Array?
If you come from languages like C, Java, or C#, you probably think of an array as a fixed-size sequence of elements stored in contiguous memory.
PHP arrays are fundamentally different.
According to the official PHP documentation, an array is an ordered map. While this definition may sound abstract at first, it perfectly describes why PHP arrays are so flexible.
An ordered map is a collection of key-value pairs where the insertion order is preserved.
Each element consists of:
- a key, used to identify the value;
- a value, which can be almost any PHP type.
For example:
$colors = [
"red",
"green",
"blue",
];
Although no keys were explicitly defined, PHP automatically assigns integer keys starting at zero.
Internally, the array actually looks like this:
[
0 => "red",
1 => "green",
2 => "blue",
]
Keys don't have to be integers.
They can also be strings, allowing arrays to represent dictionaries, configuration objects, database records, JSON documents, HTTP headers, and many other kinds of structured data.
$user = [
"name" => "John Doe",
"email" => "john@example.com",
"age" => 32,
];
One of PHP's greatest strengths is that both indexed arrays and associative arrays use exactly the same data structure internally. You don't need different collection types depending on your use case.
Arrays can even contain other arrays, making it possible to represent hierarchical or nested data structures.
$company = [
"name" => "Acme Inc.",
"employees" => [
[
"name" => "Alice",
"role" => "Developer",
],
[
"name" => "Bob",
"role" => "Designer",
],
],
];
Another important characteristic is that PHP arrays are heterogeneous, meaning they can store different data types together.
$data = [
42,
"Hello",
true,
3.14,
null,
];
While this flexibility is convenient, it's generally considered good practice to keep arrays as homogeneous as possible. Arrays containing mixed types tend to become harder to understand, validate, and maintain over time.
As you'll see throughout this guide, PHP arrays are much more than simple lists—they're the foundation upon which much of the language is built.
2. How PHP Arrays Work Internally
Most developers use arrays every day without ever wondering what happens behind the scenes.
You don't need to understand PHP's internals to write good code, but having a basic understanding of how arrays work helps explain many behaviors that otherwise seem surprising.
Unlike arrays in languages such as C, PHP arrays are not contiguous blocks of memory.
Instead, they are implemented as ordered hash tables.
This design allows PHP arrays to support all of these features simultaneously:
- integer keys;
- string keys;
- automatic key generation;
- fast key lookups;
- insertion order preservation;
- dynamic resizing.
That's a remarkable amount of flexibility for a single data structure.
A simplified view looks like this:
Hash Function
│
▼
┌────────────┐
"name" ─▶│ Bucket │──▶ "John"
└────────────┘
"age" ──▶│ Bucket │──▶ 32
"city" ─▶│ Bucket │──▶ "London"
When you access:
echo $user["name"];
PHP doesn't scan the entire array searching for "name".
Instead, it computes a hash of the key, jumps directly to the corresponding bucket, and retrieves the value. This is why key-based lookups are typically very fast.
Another important characteristic is that PHP preserves the order in which elements were inserted.
$data = [];
$data["c"] = 1;
$data["a"] = 2;
$data["b"] = 3;
Iterating over this array produces:
c
a
b
—not alphabetical order.
This behavior makes arrays predictable when generating JSON, rendering HTML, processing configuration files, or working with APIs.
PHP also uses an optimization called Copy-on-Write (CoW).
Consider this example:
$a = [1, 2, 3];
$b = $a;
At first glance, it appears that the array has been duplicated.
It hasn't.
Initially, both variables point to the same underlying data structure.
A real copy is created only when one of them is modified.
$b[] = 4;
Only at this moment does PHP allocate new memory for $b.
Without Copy-on-Write, passing arrays between functions or assigning them to other variables would be significantly more expensive.
This optimization is one of the reasons why PHP code can remain surprisingly efficient, even when working extensively with arrays.
Although PHP arrays are incredibly versatile, this flexibility comes with a trade-off: they consume considerably more memory than low-level arrays in languages like C or Rust. That's because every element stores additional metadata beyond just its value.
For most web applications, however, this trade-off is well worth it. The expressive syntax, fast lookups, and rich standard library make arrays one of the most productive features of the language.
3. Indexed Arrays
Indexed arrays are the simplest and most common type of array in PHP.
They store values using integer keys, making them ideal whenever the position of each element is more important than assigning it a descriptive name.
Creating an indexed array is straightforward.
$languages = [
"PHP",
"JavaScript",
"Python",
"Go",
];
PHP automatically assigns sequential numeric keys starting at zero.
Internally, this array is equivalent to:
$languages = [
0 => "PHP",
1 => "JavaScript",
2 => "Python",
3 => "Go",
];
You can access individual elements using their index.
echo $languages[0]; // PHP
echo $languages[2]; // Python
Adding new elements is equally simple.
$languages[] = "Rust";
PHP automatically chooses the next available numeric index.
You can also define indexes explicitly.
$numbers = [
10 => "ten",
20 => "twenty",
];
Appending another element results in:
$numbers[] = "thirty";
The new element receives index 21, not 2.
This behavior surprises many beginners.
PHP always continues from the highest existing integer key.
Updating values works exactly as expected.
$languages[1] = "TypeScript";
Removing elements is done with unset().
unset($languages[2]);
However, there's an important detail: removing an element does not automatically reindex the array.
After executing the previous code, the array becomes:
[
0 => "PHP",
1 => "TypeScript",
3 => "Go",
4 => "Rust",
]
Notice that index 2 no longer exists.
If you need consecutive indexes again, use array_values().
$languages = array_values($languages);
Result:
[
0 => "PHP",
1 => "TypeScript",
2 => "Go",
3 => "Rust",
]
In most cases, you shouldn't rely on numeric indexes having no gaps. Many PHP functions preserve keys intentionally, and reindexing large arrays unnecessarily may introduce extra processing without any practical benefit.
The most common way to iterate over indexed arrays is with foreach.
foreach ($languages as $language) {
echo $language . PHP_EOL;
}
If you also need the index:
foreach ($languages as $index => $language) {
echo "{$index}: {$language}" . PHP_EOL;
}
Although indexed arrays are often used as simple lists, they're also the foundation for many operations you'll see later in this article, including mapping, filtering, sorting, grouping, and reducing data. Mastering these fundamentals will make the more advanced array functions feel much more natural.
Os próximos capítulos começam a sair do básico e entram na parte que realmente diferencia um desenvolvedor iniciante de alguém que escreve código idiomático em PHP. A ideia aqui é preparar o terreno para, nas próximas seções do artigo, explicar funções como array_map(), array_filter() e array_reduce() sem parecer uma simples lista da documentação.
4. Associative Arrays
While indexed arrays organize data by numeric positions, associative arrays organize data by named keys.
Instead of asking "What is the third element?", you ask "What is the user's email?" or "What is the product price?". This makes associative arrays much more expressive and is one of the reasons they are so heavily used in PHP applications.
Creating an associative array is simple:
$user = [
"name" => "John Doe",
"email" => "john@example.com",
"age" => 32,
];
Values are accessed using their keys:
echo $user["name"];
echo $user["email"];
Updating an existing value works exactly as you'd expect:
$user["age"] = 33;
Adding new entries is equally straightforward:
$user["country"] = "Canada";
Removing a key uses unset():
unset($user["age"]);
Unlike many programming languages, PHP doesn't have a dedicated dictionary or map type. Associative arrays fulfill that role while using exactly the same underlying data structure as indexed arrays.
This flexibility makes associative arrays ideal for representing structured information.
A configuration object:
$config = [
"host" => "localhost",
"port" => 3306,
"database" => "blog",
];
HTTP headers:
$headers = [
"Content-Type" => "application/json",
"Accept" => "application/json",
];
A database record:
$product = [
"id" => 15,
"name" => "Mechanical Keyboard",
"price" => 129.90,
];
Or the result of decoding a JSON response:
$response = json_decode($json, true);
The second argument (true) tells json_decode() to return associative arrays instead of objects, a pattern you'll encounter frequently in modern PHP applications.
Because keys have semantic meaning, associative arrays generally produce code that is easier to read than relying on numeric indexes.
Compare these two examples:
$user[0];
$user[1];
$user[2];
versus
$user["name"];
$user["email"];
$user["age"];
The second version is immediately understandable without additional comments or documentation.
One thing worth remembering is that array keys are unique. Assigning a value to an existing key replaces the previous value.
$user["name"] = "Alice";
$user["name"] = "Bob";
The resulting array contains only "Bob".
Although associative arrays are incredibly convenient, they are sometimes overused. If an array starts containing dozens of fields, nested structures, validation rules, and business logic, it may be a sign that a dedicated class or Data Transfer Object (DTO) would provide a cleaner and more maintainable design.
5. Multidimensional Arrays
Arrays can contain any PHP value—including other arrays.
When an array contains one or more nested arrays, it is called a multidimensional array.
These structures are extremely common because real-world data is rarely flat.
Imagine an e-commerce application.
A single order contains customer information, shipping details, and a list of purchased products.
Representing this using multidimensional arrays feels natural:
$order = [
"id" => 1001,
"customer" => [
"name" => "John Doe",
"email" => "john@example.com",
],
"items" => [
[
"product" => "Keyboard",
"quantity" => 2,
"price" => 129.90,
],
[
"product" => "Mouse",
"quantity" => 1,
"price" => 49.90,
],
],
];
Accessing nested values simply means chaining indexes:
echo $order["customer"]["name"];
echo $order["items"][0]["product"];
Likewise, updating deeply nested values is straightforward:
$order["items"][1]["quantity"] = 3;
One of the biggest sources of multidimensional arrays in PHP is JSON.
Consider the following API response:
{
"name": "John",
"roles": ["admin", "editor"],
"address": {
"city": "London",
"country": "UK"
}
}
After decoding it:
$data = json_decode($json, true);
The resulting structure is simply a multidimensional associative array.
Understanding nested arrays is therefore essential for working with REST APIs, configuration files, databases, queues, and virtually every modern web application.
As nesting levels increase, however, readability tends to decrease.
Compare:
$data["users"][4]["orders"][8]["products"][2]["price"];
with a well-designed object model.
While multidimensional arrays are excellent for transporting and transforming data, they are usually not the best choice for representing complex domain models. As your application grows, deeply nested arrays often become difficult to validate, document, and maintain.
A practical rule of thumb is this:
- Use arrays for data.
- Use objects for behavior.
Keeping that distinction in mind leads to code that scales much better over time.
6. Iterating Arrays
Creating arrays is only half the story.
Most applications spend considerably more time reading, processing, and transforming arrays than simply creating them.
PHP provides several ways to iterate over arrays, each suited to different situations.
foreach
The foreach statement is by far the most common and expressive way to iterate over arrays.
foreach ($languages as $language) {
echo $language;
}
If you also need the keys:
foreach ($user as $key => $value) {
echo "{$key}: {$value}" . PHP_EOL;
}
Because foreach was designed specifically for arrays and traversable objects, it should almost always be your first choice.
It is readable, concise, and avoids common indexing mistakes.
for
The traditional for loop also works with indexed arrays.
for ($i = 0; $i < count($languages); $i++) {
echo $languages[$i];
}
However, repeatedly calling count() inside the loop condition performs the function on every iteration.
A small improvement is storing the size beforehand.
$count = count($languages);
for ($i = 0; $i < $count; $i++) {
echo $languages[$i];
}
Even then, foreach is generally preferred because it is simpler and less error-prone.
Iterating by Reference
Sometimes you need to modify each element while iterating.
PHP allows iteration by reference.
foreach ($numbers as &$number) {
$number *= 2;
}
This updates the original array in place.
However, references should be used carefully.
One common mistake is forgetting to unset the reference afterward.
unset($number);
Otherwise, $number continues referencing the last array element, potentially causing subtle bugs later in the script.
This is one of those PHP behaviors that surprises even experienced developers.
array_walk_recursive()
Unlike array_walk(), which processes only the first level of an array, array_walk_recursive() traverses every nested array, visiting all leaf values regardless of how deeply they are nested.
Consider the following structure:
$data = [
"user" => [
"name" => "John Doe",
"email" => "john@example.com",
],
"address" => [
"city" => "London",
"country" => "United Kingdom",
],
"roles" => [
"admin",
"editor",
],
];
Using array_walk_recursive():
array_walk_recursive(
$data,
function ($value, $key) {
echo "{$key}: {$value}" . PHP_EOL;
}
);
Produces:
name: John Doe
email: john@example.com
city: London
country: United Kingdom
0: admin
1: editor
Notice that the callback is executed only for the leaf values.
It does not visit intermediate arrays such as "user" or "address" themselves.
This distinction is important because many developers initially expect recursive traversal to behave like a recursive foreach, which is not the case.
One practical use case is sanitizing or normalizing data received from external sources.
For example, trimming every string in a nested array:
array_walk_recursive(
$data,
function (&$value) {
if (is_string($value)) {
$value = trim($value);
}
}
);
Another common scenario is recursively escaping user input before generating HTML or exporting data.
Although array_walk_recursive() is convenient, it is not the best solution for every recursive operation.
Because it only exposes leaf values, it cannot be used when you need to:
- remove entire branches;
- rename array keys;
- change the array structure;
- keep track of parent elements.
For those cases, writing a recursive function is usually the better approach.
Fortunately, these situations are relatively uncommon. Most day-to-day PHP applications can be handled comfortably with ordinary foreach loops or one of the transformation functions introduced in the next section.
7. Transforming Arrays
Creating arrays is easy.
The real challenge is what comes next.
Imagine an application that loads 10,000 products from a database. Rarely will you display that data exactly as it was retrieved. Instead, you'll probably need to:
- convert prices;
- remove inactive products;
- calculate totals;
- group records;
- extract specific fields;
- prepare data for an API response.
In other words, you'll spend far more time transforming arrays than creating them.
PHP embraces this idea by providing dozens of built-in functions dedicated to manipulating arrays. Learning these functions is one of the biggest productivity improvements a PHP developer can make.
Consider this simple list:
$numbers = [1, 2, 3, 4, 5];
Depending on your goal, there are three fundamentally different kinds of transformations you might perform.
Transform every element
Suppose you want to square every number.
The desired result is:
[
1,
4,
9,
16,
25,
]
Nothing was removed.
Nothing was combined.
Each input value simply produced a new output value.
Conceptually, this is a mapping operation.
Keep only selected elements
Now imagine you only care about even numbers.
The result becomes:
[
2,
4,
]
The original array wasn't modified.
Some elements were discarded according to a condition.
This is known as filtering.
Produce a single value
Sometimes the array itself isn't the final goal.
Instead, you want a summary.
For example:
[
15
]
where 15 is the sum of all numbers.
Or perhaps:
- the average;
- the largest value;
- the total order price;
- a report;
- a new associative array indexed by ID.
This operation is called reducing, because multiple values are combined into a single result.
These three ideas are so common that PHP provides dedicated functions for each of them.
| Goal | Function |
| ----------------------- | ---------------- |
| Transform every element | array_map() |
| Keep selected elements | array_filter() |
| Combine values into one | array_reduce() |
Once you recognize these patterns, you'll start seeing them everywhere—not only in PHP, but also in JavaScript, Python, Java Streams, C#, Kotlin, Rust, and many other modern programming languages.
Although the names may differ, the concepts remain exactly the same.
This is one reason why mastering array transformations improves your programming skills beyond PHP itself.
Why not just use foreach?
At this point, you may wonder why these functions exist at all.
After all, everything shown so far can be implemented using a foreach loop.
For example, squaring every number manually:
$result = [];
foreach ($numbers as $number) {
$result[] = $number * $number;
}
This code is perfectly valid.
In fact, there are situations where it is the clearest possible solution.
However, once you're familiar with PHP's array functions, the intent of your code becomes much more explicit.
Instead of describing how to perform the operation step by step, you describe what you want to achieve.
That shift often results in code that is easier to read, easier to review, and less prone to implementation mistakes.
This programming style is commonly referred to as declarative programming, as opposed to the more imperative style represented by explicit loops.
Neither approach is universally better.
Good developers know both.
The important skill is recognizing which one communicates the intent of the code more clearly.
Choosing the right tool
One mistake frequently made by developers who discover functional programming is trying to replace every foreach with array_map() or array_reduce().
That's usually a bad idea.
A good rule of thumb is:
- Use
foreachwhen the operation has side effects, such as writing files, sending emails, logging messages, or updating objects. - Use
array_map()when every element should become another element. - Use
array_filter()when some elements should disappear. - Use
array_reduce()when many elements should become one result.
Trying to force a transformation function into the wrong problem often produces code that is clever but difficult to understand.
Readability should always be the primary goal.
In the following sections, we'll explore each of these functions in depth, understand how they work internally, compare them with traditional loops, discuss their performance characteristics, and examine real-world examples taken from production code.
8. Combining Arrays
Combining arrays is one of the most common operations in PHP.
Whether you're merging configuration files, aggregating API responses, building query parameters, or composing application settings, you'll eventually need to join multiple arrays into a single structure.
Although PHP offers several ways to accomplish this, they are not interchangeable. Choosing the wrong approach can lead to unexpected results, especially when associative arrays or numeric keys are involved.
The three techniques you'll encounter most often are:
array_merge()- the array union operator (
+) - the spread operator (
...)
Understanding the differences between them is essential.
array_merge()
array_merge() appends the elements of one or more arrays into a new array.
$backend = [
"PHP",
"MySQL",
];
$frontend = [
"JavaScript",
"CSS",
];
$result = array_merge($backend, $frontend);
print_r($result);
Output:
Array
(
[0] => PHP
[1] => MySQL
[2] => JavaScript
[3] => CSS
)
When associative arrays contain the same key, the last value wins.
$config = [
"host" => "localhost",
"port" => 3306,
];
$override = [
"port" => 3307,
];
$result = array_merge($config, $override);
Result:
[
"host" => "localhost",
"port" => 3307,
]
For indexed arrays, however, array_merge() always reindexes numeric keys.
$a = [
5 => "PHP",
];
$b = [
8 => "JavaScript",
];
$result = array_merge($a, $b);
Result:
[
0 => "PHP",
1 => "JavaScript",
]
This behavior surprises many developers who expect the original indexes to be preserved.
Array Union (+)
The + operator performs an array union, not a merge.
$a = [
"name" => "John",
"email" => "john@example.com",
];
$b = [
"email" => "john.doe@example.com",
"country" => "Canada",
];
$result = $a + $b;
Result:
[
"name" => "John",
"email" => "john@example.com",
"country" => "Canada",
]
Notice what happened:
- existing keys from the left-hand array were preserved;
- conflicting values from the right-hand array were ignored.
Think of the union operator as saying:
"Keep everything from the first array, and only add keys that don't already exist."
Unlike array_merge(), numeric keys are also preserved.
$a = [
5 => "PHP",
];
$b = [
8 => "JavaScript",
];
$result = $a + $b;
Produces:
[
5 => "PHP",
8 => "JavaScript",
]
Spread Operator (...)
Introduced for arrays in PHP 7.4 and improved in later versions, the spread operator offers a concise syntax for combining arrays.
$backend = ["PHP", "MySQL"];
$frontend = ["JavaScript", "CSS"];
$languages = [
...$backend,
...$frontend,
];
Result:
[
"PHP",
"MySQL",
"JavaScript",
"CSS",
]
It can also be mixed with new values.
$languages = [
"HTML",
...$frontend,
"TypeScript",
];
For associative arrays, modern PHP versions behave similarly to array_merge().
$config = [
...$defaults,
...$environment,
];
This syntax has become increasingly popular because it is concise and easy to read, especially when constructing arrays inline.
Which One Should You Use?
Although these approaches look similar, their intent is different.
| Operation | Existing Keys | Numeric Keys |
| --------------- | ---------------------------- | ------------ |
| array_merge() | overwritten by later arrays | reindexed |
| + | preserved from left array | preserved |
| ... | behaves like array_merge() | reindexed |
As a general rule:
- Use
array_merge()when you want to combine arrays and later values should replace earlier ones. - Use
+when you're providing defaults that should never overwrite existing values. - Use the spread operator when readability is more important than using an explicit function call.
Later in this article we'll also discuss the performance implications of these approaches, particularly when combining arrays inside loops.
9. Sorting Arrays
Sorting is one of the most common data manipulation tasks in any application.
Whether you're displaying products by price, users by name, blog posts by publication date, or reports by revenue, sooner or later you'll need to sort an array.
PHP provides a surprisingly rich collection of sorting functions, each designed for a specific use case.
Although they may seem confusing at first, they follow a consistent naming convention.
The two most important questions are:
- Are you sorting by values or by keys?
- Do you need to preserve the original keys?
Once you know the answers, choosing the correct function becomes much easier.
Sorting by Values
The simplest function is sort().
$numbers = [8, 3, 5, 1];
sort($numbers);
print_r($numbers);
Result:
[
1,
3,
5,
8,
]
sort() always sorts in ascending order.
To sort in descending order, use rsort().
rsort($numbers);
One important detail is that both functions discard the original keys.
Preserving Keys
When working with associative arrays, losing the keys is usually undesirable.
For those situations, PHP provides asort().
$scores = [
"Alice" => 90,
"Bob" => 75,
"Carol" => 95,
];
asort($scores);
Result:
[
"Bob" => 75,
"Alice" => 90,
"Carol" => 95,
]
The values were sorted while the keys remained attached to them.
The descending equivalent is arsort().
Sorting by Keys
Sometimes the values are already correct—you simply want the keys in alphabetical order.
$user = [
"email" => "...",
"age" => 30,
"country" => "...",
];
Using ksort():
ksort($user);
Produces:
[
"age" => 30,
"country" => "...",
"email" => "...",
]
The reverse order is available through krsort().
Custom Sorting
Real-world applications often require more sophisticated rules.
Imagine sorting people by age.
$users = [
["name" => "John", "age" => 32],
["name" => "Alice", "age" => 25],
["name" => "Bob", "age" => 41],
];
This is where usort() becomes useful.
usort(
$users,
fn ($a, $b) => $a["age"] <=> $b["age"]
);
The spaceship operator (<=>) returns:
-1if the left value is smaller;0if both values are equal;1if the left value is greater.
Because of its simplicity, it has become the preferred way of implementing comparison callbacks in modern PHP.
You can just as easily sort by name.
usort(
$users,
fn ($a, $b) => strcmp($a["name"], $b["name"])
);
Which Sorting Function Should You Use?
The number of available sorting functions may initially seem overwhelming, but most applications rely on only a handful of them.
| Function | Sort By | Preserve Keys |
| ---------- | ------------------- | ------------- |
| sort() | values | ❌ |
| rsort() | values (descending) | ❌ |
| asort() | values | ✅ |
| arsort() | values (descending) | ✅ |
| ksort() | keys | ✅ |
| krsort() | keys (descending) | ✅ |
| usort() | custom comparison | ❌ |
Later in this article we'll revisit sorting when discussing performance and common pitfalls, including locale-aware sorting, natural ordering, and the cost of repeatedly sorting large datasets.
10. Searching Arrays
Finding information inside an array is another task you'll perform almost every day.
PHP offers several search functions, each optimized for a different purpose.
Understanding which one to use—and when—is important not only for correctness but also for performance.
The four functions you'll encounter most often are:
in_array()array_search()isset()array_key_exists()
Although they appear similar, they answer completely different questions.
in_array()
Use in_array() when you want to know whether a value exists in an array.
$languages = [
"PHP",
"JavaScript",
"Go",
];
if (in_array("PHP", $languages)) {
echo "Found!";
}
By default, comparisons are not strict.
in_array("5", [5]);
This returns true.
To avoid unexpected type juggling, enable strict comparisons.
in_array("5", [5], true);
Now the result is false.
As a general rule, prefer the third parameter set to true unless you intentionally want loose comparisons.
array_search()
Sometimes you need more than a yes-or-no answer.
You need to know where the value was found.
$index = array_search("Go", $languages, true);
Result:
2
If the value is not found, the function returns false.
Because 0 is a valid array index, always compare using the identity operator.
if ($index !== false) {
// Found
}
Never write:
if ($index) {
...
}
Otherwise, an element located at index 0 will incorrectly appear as "not found".
This is one of the oldest and most common PHP bugs.
isset()
isset() checks whether a key exists and its value is not null.
$user = [
"name" => "John",
"email" => null,
];
isset($user["name"]);
Returns:
true
But:
isset($user["email"]);
Returns:
false
Even though the key exists.
array_key_exists()
If your goal is to determine whether the key itself exists, regardless of its value, use array_key_exists().
array_key_exists("email", $user);
Returns:
true
This subtle distinction causes a surprising number of bugs in production systems.
Consider the following table.
| Situation | isset() | array_key_exists() |
| ----------------------------- | --------- | -------------------- |
| Key exists with value "PHP" | ✅ | ✅ |
| Key exists with value 0 | ✅ | ✅ |
| Key exists with value false | ✅ | ✅ |
| Key exists with value null | ❌ | ✅ |
| Key does not exist | ❌ | ❌ |
A good way to remember the difference is:
isset()asks "Can I safely use this value?"array_key_exists()asks "Does this key exist at all?"
Performance Considerations
Searching by key is generally much faster than searching by value.
Functions like isset() and array_key_exists() can take advantage of PHP's internal hash table to locate keys efficiently.
By contrast, in_array() and array_search() must inspect values until they find a match (or reach the end of the array), making them inherently more expensive for large datasets.
This distinction rarely matters for small arrays, but it can become significant when processing thousands of elements inside performance-critical code.
We'll revisit this topic later when discussing benchmarks and optimization techniques.
11. Array Destructuring
One of the nicest additions to modern PHP is array destructuring.
Instead of accessing individual elements one by one, destructuring lets you extract multiple values from an array in a single, expressive statement.
Consider the following indexed array:
$coordinates = [150, 75];
Without destructuring, you would write:
$x = $coordinates[0];
$y = $coordinates[1];
With destructuring:
[$x, $y] = $coordinates;
The result is exactly the same, but the intent is immediately clear.
echo "X: {$x}, Y: {$y}";
This syntax becomes especially useful when functions return multiple values.
Imagine a function that returns a start and end date:
function getPeriod(): array
{
return [
'2025-01-01',
'2025-12-31',
];
}
[$start, $end] = getPeriod();
Instead of manually accessing indexes, the returned values are unpacked directly into variables.
Skipping Values
You don't have to assign every element.
Suppose you're only interested in the first and third values.
$data = [
"John",
32,
"Canada",
];
You can simply skip the second one.
[$name, , $country] = $data;
Result:
$name => John
$country => Canada
This keeps the code concise while avoiding unnecessary temporary variables.
Destructuring Associative Arrays
Since PHP 7.1, destructuring also supports associative arrays.
$user = [
"id" => 15,
"name" => "John",
"email" => "john@example.com",
];
Instead of writing:
$id = $user["id"];
$name = $user["name"];
$email = $user["email"];
You can write:
[
"id" => $id,
"name" => $name,
"email" => $email,
] = $user;
Notice that, unlike indexed arrays, the order doesn't matter.
The keys determine which value is assigned to each variable.
This is particularly useful when working with API responses, configuration arrays, or database records where only a subset of fields is needed.
Destructuring Inside foreach
One of the most elegant uses of destructuring is inside loops.
Suppose each employee is represented as a simple indexed array.
$employees = [
["Alice", "Developer"],
["Bob", "Designer"],
["Carol", "Manager"],
];
Instead of indexing each value manually:
foreach ($employees as $employee) {
echo $employee[0];
echo $employee[1];
}
You can destructure each row automatically.
foreach ($employees as [$name, $role]) {
echo "{$name} - {$role}" . PHP_EOL;
}
Associative arrays work as well.
$users = [
[
"name" => "John",
"email" => "john@example.com",
],
[
"name" => "Alice",
"email" => "alice@example.com",
],
];
foreach ($users as [
"name" => $name,
"email" => $email,
]) {
echo "{$name}: {$email}" . PHP_EOL;
}
This style removes repetitive indexing and makes loops significantly easier to read.
When Should You Use Destructuring?
Array destructuring shines whenever an array has a well-known structure.
Typical examples include:
- function return values;
- CSV rows;
- database records;
- API responses;
- coordinate pairs;
- date ranges.
On the other hand, destructuring becomes less attractive when arrays contain dozens of fields or optional keys. In those situations, assigning only the values you actually need often results in cleaner code.
Like many modern PHP features, destructuring isn't something you'll use everywhere—but when it fits the problem, it makes code noticeably more expressive.
12. Spread Operator
The spread operator (...) has become one of the most widely used features in modern PHP.
Originally introduced for function arguments, it was later extended to support arrays, providing a concise and expressive way to build new collections.
Conceptually, the spread operator expands an iterable into its individual elements.
For arrays, you can think of it as saying:
"Take everything inside this array and place it here."
Creating New Arrays
Suppose you have two arrays.
$backend = [
"PHP",
"MySQL",
];
$frontend = [
"JavaScript",
"CSS",
];
Instead of calling array_merge(), you can write:
$languages = [
...$backend,
...$frontend,
];
Result:
[
"PHP",
"MySQL",
"JavaScript",
"CSS",
]
Many developers find this syntax easier to read because it visually resembles the resulting array.
Mixing Existing and New Values
One advantage of the spread operator is that new values can be inserted naturally.
$languages = [
"HTML",
...$backend,
...$frontend,
"TypeScript",
];
This style is often cleaner than multiple nested array_merge() calls.
Spreading Associative Arrays
Modern PHP also supports unpacking associative arrays.
$defaults = [
"host" => "localhost",
"port" => 3306,
];
$environment = [
"port" => 3307,
];
$config = [
...$defaults,
...$environment,
];
Result:
[
"host" => "localhost",
"port" => 3307,
]
Just like array_merge(), later values overwrite earlier ones.
This behavior makes the spread operator particularly useful for configuration overrides.
Conditional Array Construction
One elegant pattern is conditionally adding elements while constructing an array.
$user = [
"name" => "John",
...($isAdmin
? ["role" => "admin"]
: []),
];
Without the spread operator, this would typically require multiple statements.
This pattern appears frequently in frameworks, API serializers, and DTO builders.
Copying Arrays
The spread operator can also create a shallow copy of an array.
$copy = [...$original];
This is equivalent to:
$copy = array_merge([], $original);
Although PHP's Copy-on-Write optimization means explicit copying is often unnecessary, there are situations where creating an independent array improves readability or avoids accidental modifications.
Spread Operator vs array_merge()
Many developers ask whether the spread operator replaces array_merge().
The answer is: not entirely.
For most day-to-day code, they produce equivalent results.
$result = [
...$a,
...$b,
];
and
$result = array_merge($a, $b);
are usually interchangeable.
The choice often comes down to readability and coding style.
That said, array_merge() still has advantages when combining an unknown number of arrays dynamically.
$result = array_merge(...$arrays);
Likewise, some developers prefer the explicitness of a function call over language syntax.
Neither approach is inherently better. The important point is understanding that both perform essentially the same operation and choosing the one that makes the surrounding code easiest to understand.
13. Performance
Performance is one of the most misunderstood aspects of PHP arrays.
It's easy to spend hours micro-optimizing loops while overlooking operations that have a much greater impact on execution time and memory consumption.
Before discussing specific functions, it's important to establish a general principle:
Write readable code first. Optimize only after measuring.
PHP is highly optimized internally, and many assumptions about performance turn out to be incorrect when benchmarked.
That said, understanding how arrays behave allows you to avoid several common performance pitfalls.
Arrays Are Powerful—But Not Cheap
As discussed earlier, PHP arrays are ordered hash tables.
This makes them extremely flexible, but flexibility comes at a cost.
Each element stores considerably more information than just its value, including metadata used by the Zend Engine.
For small and medium-sized datasets, this overhead is negligible.
However, applications processing hundreds of thousands of records should be aware that arrays consume significantly more memory than low-level arrays in languages such as C or Rust.
Fortunately, most web applications never approach these limits.
foreach vs array_map()
One of the oldest debates in the PHP community is whether array_map() is faster than foreach.
The honest answer is:
Usually, it doesn't matter.
Both are implemented in C and highly optimized.
More importantly, they solve slightly different problems.
$result = [];
foreach ($numbers as $number) {
$result[] = $number * 2;
}
versus
$result = array_map(
fn ($number) => $number * 2,
$numbers
);
In practice, readability should be the deciding factor.
If the operation is naturally expressed as a transformation, array_map() often communicates the intent better.
If the logic is complex, a foreach loop may be clearer.
isset() vs in_array()
Another common misconception concerns lookup speed.
Checking whether a key exists:
isset($users[$id]);
is fundamentally different from searching whether a value exists:
in_array($id, $users, true);
The first operation leverages PHP's internal hash table for fast key lookups.
The second must inspect values until a match is found.
If you frequently search by identifier, restructuring your data into an associative array indexed by ID can dramatically improve lookup performance.
Instead of:
$users = [
[
"id" => 15,
"name" => "John",
],
[
"id" => 42,
"name" => "Alice",
],
];
Consider:
$users = [
15 => [
"name" => "John",
],
42 => [
"name" => "Alice",
],
];
Now retrieving a user becomes trivial.
$user = $users[42] ?? null;
This is a common optimization in production systems processing large datasets.
Avoid array_merge() Inside Loops
One of the most expensive mistakes beginners make is repeatedly merging arrays inside a loop.
$result = [];
foreach ($chunks as $chunk) {
$result = array_merge($result, $chunk);
}
Every iteration creates a brand-new array containing all previous elements plus the new ones.
As the result grows, more and more data needs to be copied.
This can quickly become expensive in both CPU time and memory allocation.
Whenever possible, accumulate values directly.
$result = [];
foreach ($chunks as $chunk) {
foreach ($chunk as $item) {
$result[] = $item;
}
}
For large datasets, this approach often performs substantially better because it avoids repeatedly copying the growing array.
Avoid Unnecessary Copies
Because of Copy-on-Write, many developers mistakenly believe every assignment duplicates an array.
It doesn't.
$a = $largeArray;
does not immediately allocate another copy.
Only when either variable is modified does PHP create a separate array.
This optimization means passing arrays to functions is generally much cheaper than many newcomers expect.
Understanding this behavior helps avoid premature optimization based on incorrect assumptions.
The Biggest Performance Win
Ironically, the largest performance improvement rarely comes from replacing one array function with another.
It comes from choosing the right data structure.
Searching thousands of elements repeatedly with in_array() is often far slower than organizing the data into an associative array and performing direct key lookups.
Likewise, eliminating unnecessary loops usually produces larger gains than replacing foreach with a more "clever" function.
In other words, algorithmic improvements almost always outweigh micro-optimizations.
That's a principle worth remembering not only in PHP, but in software engineering as a whole.
14. Common Mistakes
PHP arrays are incredibly flexible, but that flexibility also makes them easy to misuse.
Most production bugs involving arrays are not caused by obscure language features—they stem from a handful of common mistakes that are surprisingly easy to make.
Understanding these pitfalls will help you write code that is more predictable, maintainable, and less prone to subtle bugs.
Mixing Indexed and Associative Arrays
PHP allows numeric and string keys to coexist in the same array.
$data = [
"name" => "John",
0 => "PHP",
"country" => "Canada",
1 => "JavaScript",
];
Although this is perfectly valid, it usually indicates that the array is trying to represent two different concepts at once.
Ask yourself:
- Is this supposed to be a list?
- Or is it a structured object?
Trying to make it both generally hurts readability.
A good rule is simple:
- Lists should contain sequential numeric keys.
- Objects and records should use descriptive string keys.
Keeping these two concepts separate makes the code much easier to understand.
Assuming Numeric Keys Are Always Sequential
Many developers expect indexed arrays to always contain consecutive indexes.
That assumption breaks as soon as an element is removed.
$languages = [
"PHP",
"JavaScript",
"Go",
];
unset($languages[1]);
print_r($languages);
Result:
[
0 => "PHP",
2 => "Go",
]
Notice that index 1 no longer exists.
If your code later assumes that every integer between 0 and count($array) - 1 exists, you'll eventually run into unexpected behavior.
If consecutive indexes are required, explicitly reindex the array.
$languages = array_values($languages);
Otherwise, let the original keys remain untouched.
Forgetting Strict Comparisons
Functions such as in_array() and array_search() perform loose comparisons by default.
in_array("5", [5]);
This returns true.
Likewise:
in_array(false, [0]);
also returns true.
These implicit type conversions have been responsible for countless production bugs.
Whenever possible, enable strict comparisons.
in_array("5", [5], true);
Likewise:
array_search($value, $array, true);
The extra argument costs nothing in readability and makes the intent explicit.
Misusing array_search()
A classic mistake is writing:
if ($index = array_search("PHP", $languages)) {
...
}
Why is this wrong?
Because if "PHP" is found at index 0, the condition evaluates to false.
The correct approach is:
if (($index = array_search("PHP", $languages, true)) !== false) {
...
}
Using the identity operator (!==) avoids one of the oldest PHP pitfalls.
Modifying an Array While Iterating
Changing an array during iteration can produce confusing behavior.
For example:
foreach ($numbers as $number) {
$numbers[] = $number;
}
Depending on the situation, this may produce unexpected results or even create an infinite loop.
Similarly, removing elements while iterating often deserves extra care.
Instead of modifying the array in place, consider building a new array or using array_filter() when appropriate.
Forgetting to unset() References
References are powerful but easy to misuse.
foreach ($numbers as &$number) {
$number *= 2;
}
After the loop, $number still references the last element.
If you later write:
$number = 100;
you unintentionally modify the original array.
Always break the reference explicitly.
unset($number);
This tiny statement prevents an entire class of subtle bugs.
Overusing Arrays
Arrays are so convenient that many applications use them for everything.
Soon, a simple associative array evolves into something like this:
$user = [
"id" => 15,
"name" => "John",
"email" => "...",
"permissions" => [...],
"orders" => [...],
"settings" => [...],
"preferences" => [...],
...
];
If an array starts representing a rich business entity with behavior, validation, and invariants, it's usually time to introduce a dedicated class or Data Transfer Object (DTO).
Arrays excel at transporting data.
Objects excel at modeling behavior.
Knowing where that boundary lies is an important architectural skill.
15. Best Practices
Over the years, the PHP community has converged on a number of practices that consistently lead to cleaner, safer, and more maintainable code.
They're not language rules, but they are habits worth adopting.
Choose the Right Data Structure
One of the most important decisions happens before writing any code.
Ask yourself:
Is this data a list or an object?
If the order matters and every element is conceptually the same, use an indexed array.
$languages = [
"PHP",
"JavaScript",
"Go",
];
If each value has a specific meaning, use an associative array.
$user = [
"name" => "John",
"email" => "john@example.com",
];
Making this distinction early improves readability throughout the application.
Prefer Meaningful Keys
Compare:
$user[0];
$user[1];
$user[2];
with:
$user["name"];
$user["email"];
$user["country"];
The second version documents itself.
Descriptive keys reduce the need for comments and make the codebase much easier to navigate.
Keep Arrays Homogeneous
Although PHP allows mixing different data types freely, consistency pays off.
Prefer:
$prices = [
10.5,
19.9,
49.0,
];
over:
$data = [
10,
"John",
true,
null,
5.3,
];
Homogeneous collections are easier to validate, transform, and reason about.
Enable Strict Comparisons
Whenever a function offers a strict comparison mode, use it unless you have a very specific reason not to.
in_array($id, $ids, true);
array_search($name, $names, true);
Avoid relying on PHP's automatic type juggling.
Being explicit almost always results in fewer bugs.
Write for Humans First
Many array functions produce beautifully concise code.
Others can quickly become cryptic.
Consider this:
$result = array_reduce(
array_filter(
array_map(...),
),
...
);
Technically impressive?
Perhaps.
Easy to understand six months later?
Probably not.
Sometimes two simple foreach loops communicate the intent much more clearly.
Readability should always outweigh cleverness.
Index Data for Fast Lookups
If your application frequently searches records by ID, don't repeatedly scan the entire array.
Instead of:
foreach ($users as $user) {
if ($user["id"] === $id) {
...
}
}
Build an associative array keyed by ID.
$usersById[$user["id"]] = $user;
Now retrieval becomes immediate.
$user = $usersById[$id] ?? null;
This simple pattern appears everywhere in high-performance PHP applications.
Don't Fear Built-in Functions
PHP's standard library contains decades of accumulated knowledge.
Functions like:
array_map()array_filter()array_reduce()array_column()array_count_values()array_flip()
often replace dozens of lines of custom code.
Learning them pays dividends throughout your entire career.
16. Real Production Examples
Everything we've discussed so far becomes much more valuable when applied to real applications.
The following examples illustrate common patterns you'll encounter in production code.
Transforming Database Results
Imagine a query returning all users.
$users = [
[
"id" => 1,
"name" => "John",
],
[
"id" => 2,
"name" => "Alice",
],
];
A REST API may require only the user names.
$names = array_column($users, "name");
Result:
[
"John",
"Alice",
]
No manual loops required.
Indexing Records by ID
A common optimization is converting a list into a lookup table.
Instead of repeatedly searching the array:
foreach ($users as $user) {
if ($user["id"] === $id) {
...
}
}
Create an index once.
$usersById = [];
foreach ($users as $user) {
$usersById[$user["id"]] = $user;
}
Now every lookup becomes:
$user = $usersById[$id] ?? null;
This pattern appears in ORMs, caches, authentication systems, and API gateways.
Filtering API Responses
Imagine an external service returning hundreds of products.
Only active products should be displayed.
$activeProducts = array_filter(
$products,
fn ($product) => $product["active"]
);
The resulting code communicates the business rule directly.
Preparing JSON Responses
Suppose your database contains sensitive information.
$user = [
"id" => 15,
"name" => "John",
"email" => "...",
"password" => "...",
];
Before returning the response:
unset($user["password"]);
echo json_encode($user);
Arrays make it straightforward to reshape data before exposing it through an API.
Grouping Records
Suppose you need to group employees by department.
$result = [];
foreach ($employees as $employee) {
$result[$employee["department"]][] = $employee;
}
Result:
Engineering
Alice
Bob
Sales
Carol
David
This pattern is extremely common in reporting systems and dashboards.
Building Configuration Objects
Modern PHP frameworks often compose configuration from multiple sources.
$config = [
...$defaults,
...$environment,
...$userOverrides,
];
Each layer overrides the previous one while preserving values that remain unchanged.
This pattern can be found in Laravel, Symfony, WordPress, Composer, and countless other projects.
Processing CSV Files
CSV processing is another area where arrays naturally shine.
while (($row = fgetcsv($file)) !== false) {
[$id, $name, $email] = $row;
// Process the record...
}
Using destructuring makes the code significantly easier to read than repeatedly accessing numeric indexes.
Working with JSON APIs
Most REST APIs ultimately become associative arrays after decoding.
$response = json_decode($json, true);
From that point on, nearly every technique covered in this article becomes useful:
array_map()to transform data;array_filter()to remove unwanted records;array_column()to extract fields;array_reduce()to calculate aggregates;array_merge()to combine responses;- destructuring to simplify access to well-known structures.
This is perhaps the biggest takeaway from this guide.
Arrays are not just another language feature—they are the backbone of modern PHP development.
Whether you're building APIs, processing files, consuming external services, generating reports, or implementing business logic, mastering PHP arrays will improve the quality, readability, and performance of almost every application you write.
17. Frequently Asked Questions (FAQ)
Are PHP arrays ordered?
Yes.
Unlike hash maps in many programming languages, PHP arrays preserve the order in which elements are inserted.
$data = [];
$data["c"] = 1;
$data["a"] = 2;
$data["b"] = 3;
foreach ($data as $key => $value) {
echo $key . PHP_EOL;
}
Output:
c
a
b
This predictable iteration order is one of the reasons arrays work so well for JSON serialization, configuration files, API responses, and templating.
Are PHP arrays hash tables?
Yes.
Internally, PHP implements arrays as ordered hash tables.
This implementation combines several desirable characteristics:
- fast key lookups;
- automatic resizing;
- support for integer and string keys;
- insertion order preservation.
The downside is that PHP arrays consume significantly more memory than low-level arrays found in languages like C.
Fortunately, that trade-off is well suited to web applications, where developer productivity is usually more important than squeezing every byte of memory.
What's the difference between indexed and associative arrays?
Technically, none.
Both use exactly the same internal data structure.
The only difference is the type of keys being used.
Indexed arrays primarily use integer keys.
$languages = [
"PHP",
"JavaScript",
];
Associative arrays use descriptive string keys.
$user = [
"name" => "John",
"email" => "john@example.com",
];
Conceptually, indexed arrays represent lists, while associative arrays represent records or objects.
Is array_map() faster than foreach?
Usually, this is the wrong question.
Both are highly optimized.
The real question should be:
Which one makes the code easier to understand?
Use array_map() when you're transforming every element into another value.
Use foreach when the operation is more procedural, involves side effects, or requires more complex logic.
The readability difference is almost always more important than the performance difference.
When should I use array_reduce()?
array_reduce() is appropriate whenever multiple elements should produce a single result.
Examples include:
- calculating totals;
- computing averages;
- building associative indexes;
- grouping records;
- generating reports;
- accumulating statistics.
If the reduction logic is difficult to follow, don't hesitate to replace it with a well-written foreach.
Clarity always wins.
Why does array_filter() remove 0 and empty strings?
When no callback is provided, array_filter() removes every value considered falsy by PHP.
For example:
$data = [
0,
false,
"",
null,
"PHP",
];
$result = array_filter($data);
Result:
[
"PHP",
]
If you only want to remove null values—or apply any other custom rule—provide an explicit callback.
$result = array_filter(
$data,
fn ($value) => $value !== null
);
Being explicit avoids many subtle bugs.
What's the difference between isset() and array_key_exists()?
This is one of the most frequently asked PHP questions.
isset() checks whether the key exists and its value is not null.
isset($user["email"]);
array_key_exists() checks only whether the key exists.
array_key_exists("email", $user);
If null is a valid value in your application, array_key_exists() is usually the correct choice.
Does assigning an array create a copy?
Not immediately.
PHP uses Copy-on-Write (CoW).
$a = [1, 2, 3];
$b = $a;
At this point, both variables reference the same internal structure.
A real copy is created only after one of them is modified.
$b[] = 4;
This optimization makes passing arrays between functions much cheaper than many developers expect.
Why are PHP arrays so memory intensive?
Each array element stores considerably more than just its value.
Internally, PHP maintains metadata used for:
- hashing;
- reference counting;
- type information;
- insertion order;
- memory management.
This additional information enables the flexibility developers enjoy every day, but it also means PHP arrays are considerably heavier than primitive arrays in lower-level languages.
Should I use arrays or objects?
It depends on what you're modeling.
As a rule of thumb:
Use arrays when you're dealing with data.
Examples include:
- JSON responses;
- configuration files;
- CSV rows;
- API payloads;
- temporary transformations.
Use objects when you're modeling behavior.
If an array starts requiring validation rules, business logic, invariants, or dozens of fields, introducing a dedicated class usually leads to cleaner and more maintainable code.
Conclusion
Arrays are, without question, one of the most important features of PHP.
They appear everywhere: in HTTP requests, database results, JSON documents, configuration files, framework internals, third-party libraries, and countless everyday programming tasks. Whether you realize it or not, nearly every PHP application relies heavily on arrays.
However, mastering arrays goes far beyond knowing how to write [] or iterate with foreach.
As you've seen throughout this guide, understanding how arrays work internally helps explain why certain operations are fast, why others are expensive, and why seemingly small implementation details—such as preserving keys or using strict comparisons—can have a significant impact on correctness and maintainability.
You've also explored the rich ecosystem of array functions provided by PHP. Functions like array_map(), array_filter(), array_reduce(), array_column(), array_merge(), and many others allow you to express complex data transformations with code that is often shorter, more readable, and less error-prone than manually manipulating arrays with nested loops.
Equally important, we've discussed the situations where these functions shouldn't be used. Clean code isn't about replacing every foreach with a clever one-liner; it's about choosing the construct that communicates your intent most clearly.
If there's one idea to take away from this article, it's this:
Great PHP developers don't just know array functions—they know when, why, and when not to use them.
That judgment comes from understanding the underlying concepts rather than memorizing the standard library.
The good news is that the concepts you've learned here extend well beyond PHP. Mapping, filtering, reducing, sorting, grouping, indexing, and transforming collections are universal programming techniques found in virtually every modern language. Mastering them in PHP will make you a better developer regardless of the technology stack you work with.
This guide intentionally focused on building a strong foundation. Many of the topics introduced here deserve their own in-depth discussion, and several of them will be explored in dedicated articles, including:
- A complete guide to
array_map() - Mastering
array_filter() - Understanding
array_reduce() - Sorting arrays efficiently in PHP
- Searching arrays like a pro
- PHP array performance and benchmarks
- Copy-on-Write explained
- Associative arrays vs objects
- Advanced array manipulation techniques
If you found this guide useful, consider bookmarking it and sharing it with other PHP developers. Arrays are one of those topics that everyone uses, but very few developers fully understand—and that knowledge can make a noticeable difference in the quality, readability, and performance of the code you write every day.