Flat pair arrays: three pitfalls from the Related articles block

Содержание
The flat pair array
Count entries, not articles
Cap the array you loop over
array_search and index 0
Prove it with a test
When to retire the flat array

The flat pair array

The Related articles block of this site is fed by a flat array: url, title, url, title and so on. The renderer walks it two steps at a time:

<?php $i = 0; while ($i < $limit) { $url = $items[$i]; $name = $items[$i + 1]; $i += 2; }

Three small mistakes hide in this loop. All three shipped on this very site, so here they are with fixes.

Count entries, not articles

Twelve articles are twenty-four array entries. Capping the loop at 12 shows six articles; capping at 24 shows twelve. And the cap must stay even, otherwise the last iteration reads one past the end of the array:

<?php // BAD: six articles, not twelve $limit = 12; // GOOD: twelve articles, even cap $limit = min(12 * 2, count($items)); $limit -= $limit % 2;

An odd-length array (a trailing url with no title after a bad edit) would otherwise end in an undefined-index warning or a broken link.

Cap the array you loop over

Do not take the limit from a stale length property when the loop runs over a filtered copy. Removing the current page shrinks the working array by two, so a limit computed before the filter can run past its end:

<?php // BAD: limit from the unfiltered array $limit = $this->related_urls_length; $shown = array_values($filtered); // GOOD: limit from the array in the loop $shown = array_values($filtered); $limit = min(12 * 2, count($shown)); $limit -= $limit % 2;

array_search and index 0

Filtering out the current page usually starts with array_search(). It returns the index, and the first element lives at index 0, which is falsy. A loose comparison silently skips the removal exactly when the current page is first in the list:

<?php $at = array_search($current, $items); // BAD: misses index 0, because 0 != false is false if ($at != false) { unset($items[$at], $items[$at + 1]); } // GOOD: strict comparison, then reindex the pair list if ($at !== false) { unset($items[$at], $items[$at + 1]); $items = array_values($items); }

The reindex matters too: after unset() the pair loop expects consecutive numeric keys, so array_values() restores them.

Prove it with a test

All three fixes fit in one script you can run before every deploy. Feed the renderer a list with the current page first (catches the array_search bug), an odd-length list (catches the cap bug), and a filtered list shorter than the original (catches the stale-limit bug):

<?php $items = ['/here', 'Here', '/a', 'A']; remove_current($items, '/here'); assert($items === ['/a', 'A']); render(array_slice($items, 0, 24)); // even cap, no warnings

If any assertion or a single warning appears, the block is broken — no manual clicking through pages required.

When to retire the flat array

The flat array survives while the list is small, unordered and edited by hand. Retire it when you need any of: per-item metadata (dates, weights), sorting that is not file order, or more than one consumer with different limits. The replacement is an array of small arrays (url, title, extra), where count() finally means articles and every limit bug in this article disappears by construction.

Похожие статьи
Development with PHP
Arrays in PHP
Date and Time in PHP - basics
How to display time of multiple timezones in PHP
How to add variable to url in PHP
json_decode
How to get screen size with PHP
Call function from another file
Premature end of chunk coded message body: closing chunk expected
Generate unique random numbers with PHP
Check your HTTP_USER_AGENT
Compare two dates
OOP
Namespaces in PHP
Comments in PHP
Cookies
PHP sessions
Authentication and Authorization in PHP 8
PHP linters we use
PHP errors: case studies
card_from_db(): banner card from a DB row
PHP versions: history in brief
Creating rules in .htaccess
require, require_once, include, include_once
Flat pair arrays: three pitfalls from the Related articles block
Deduplication in PHP
PHP course: zero to hero in 50 lessons

Search this site

Subscribe to Telegram channel @aofeed to follow new articles and updates to old ones

Go to channel

@aofeed

Ask a question in the Telegram group

@aofeedchat

Contacts and cooperation:
I recommend our hosting beget.ru
Write to info@urn.su, info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: