reverse() on querybuilder get() changes the collection results
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Deciphering Collection Flow: Why reverse() on a QueryBuilder Result Behaves Unexpectedly
As senior developers, we often deal with the nuances of how data flows between the database layer and the application layer. When working with Eloquent or the Query Builder in Laravel, understanding the precise sequence of operations—sorting, limiting, and reversing—is crucial. The scenario you've presented highlights a common point of confusion: the interaction between database-level ordering and PHP collection manipulation methods like reverse().
Let’s dive deep into why applying reverse() after using orderBy() and take() changes your results, and how we can ensure our data retrieval logic is always explicit and predictable.
The Mechanics Behind the Confusion
The difference you are observing stems from the separation between two distinct operations: Database Sorting and Application Collection Reversal.
1. Database Ordering (orderBy)
When you execute $query->orderBy('data_ora', 'desc')->take(10)->get();, you are instructing the database (SQL) to perform the heavy lifting first. The database sorts the entire result set based on data_ora descending and then only returns the top 10 rows. This resulting collection is already ordered according to the database’s logic (oldest items first, or newest items first, depending on how you frame the sort).
2. Application Reversal (reverse())
The subsequent call to ->reverse() operates purely on the PHP array or collection that was returned from the database. It reverses the order of the already retrieved elements in memory.
Why the results look different:
In your initial example, you ordered by desc. If you take the top 10 records ordered descendingly (newest first), and then reverse it, you effectively turn the newest record into the first item, and the oldest record into the last item. This is a perfectly valid operation, but it’s important to understand that the initial ordering context has been inverted by the application layer.
The key takeaway here is that orderBy() dictates the order of retrieval from the database, while reverse() dictates the final sequence presented to your application. They operate on different layers of abstraction.
Practical Example and Best Practices
Let's re-examine the logic using a clearer approach. If your goal is to retrieve the last 10 records (i.e., the 10 most recent ones) and present them in chronological order (oldest first), you should rely solely on the database for sorting, eliminating the need for an extra reversal step if possible.
Scenario A: Getting the Last N Records in Reverse Chronological Order (The Original Goal)
If you want the most recent 10 records and present them from newest to oldest within your application code, your original approach was mathematically correct for that specific outcome:
$eventi = \App\Model::with('relation_1', 'relation_2')
->orderBy('data_ora', 'desc') // Orders the DB result: Newest first
->take(10) // Takes the 10 newest records
->get() // Result set is ordered: [Newest, ..., Oldest]
->reverse(); // Reverses it to: [Oldest, ..., Newest] (Chronological order)
Scenario B: Achieving Chronological Order Directly (The Cleaner Approach)
If your ultimate goal is simply to retrieve the 10 most recent records and have them naturally ordered from oldest to newest (which is often preferred for displaying a history), you can simplify the query by adjusting the sorting direction.
To get the last 10 records when ordered descendingly, you are already getting the latest ones. To make them appear chronologically ascending in your final collection, you simply need to reverse the result of the initial sort:
// Goal: Get the 10 most recent records, ordered from oldest to newest.
$eventi = \App\Model::with('relation_1', 'relation_2')
->orderBy('data_ora', 'desc') // Sort by date descending (Newest first)
->take(10) // Select the 10 newest
->get() // Collection is: [Newest, ..., Oldest]
->reverse(); // Collection is now: [Oldest, ..., Newest] (Chronological order)
While this works, a more idiomatic and potentially more performant way, especially when dealing with complex sorting requirements in Laravel, is to leverage database functions directly if the requirement is purely about retrieving the "last" items. However, for simple ordering as you demonstrated, keeping the orderBy followed by reverse on the collection is perfectly valid, provided you fully understand the sequence of operations within your application logic. As we explore more complex data interactions in Laravel, understanding this layer-by-layer execution is key to writing robust code, much like adhering to best practices outlined on sites like laravelcompany.com.
Conclusion
The confusion arises not from an error, but from the difference between instruction sets: the database dictates the physical order, and PHP collection methods dictate the presentation order. Always map out the flow of data—from SQL sorting to PHP array manipulation—to ensure your results are exactly what you expect. For complex queries involving limiting and ordering, mastering this separation between persistence and presentation is fundamental to effective development in Laravel.