PHP81 Compatibility - sebiboga/testlink-upgraded GitHub Wiki
PHP 8.1+ Compatibility
Issue #140
Modernized TestLink for PHP 8.1+ support with zero breaking changes.
What Changed
1. strftime() Deprecation
Problem: PHP 8.1 deprecated strftime(). Many TestLink functions used this for date formatting.
Solution: Created tlStrftime() wrapper function that:
- Uses IntlDateFormatter for locale-aware formatting (PHP 8.1+)
- Falls back to date() conversion
- Maintains backward compatibility with PHP 7.4+
Usage:
// Old (deprecated)
$date = @strftime("%Y-%m-%d", time());
// New (recommended)
$date = tlStrftime("%Y-%m-%d", time());
2. Count Type Safety
Problem: PHP 8.1 enforces strict typing. count() on non-countable values throws TypeError.
Solution: Created type-safe helpers:
// tlCount() - returns 0 for non-countable
$count = tlCount($items); // Safe even if $items is null
// tlEnsureCountable() - converts to array
$items = tlEnsureCountable($query_result);
$count = count($items);
3. Variable Syntax
Status: Already fixed. All ${var} replaced with {$var} in strings.
Compatibility Layer
New File: lib/functions/php81_compat.php
Three helper functions:
tlStrftime($format, $timestamp)
- Modern date formatting
- Locale-aware (PHP 8.1+)
- Format strings: %Y, %m, %d, %H, %M, %S, %A, %B, %c, %x, %X
tlCount($value, $mode)
- Safe count for any type
- Returns 0 for null/non-countable
- Supports COUNT_NORMAL and COUNT_RECURSIVE
tlEnsureCountable($value)
- Converts values to countable
- Returns empty array if null
- Safe for subsequent count()
Affected Files
- date_api.php
- lang_api.php
- testcase.class.php
- print.inc.php
- logger.class.php
- resultsMoreBuildsGUI.php
- tcCreatedPerUserOnTestProject.php
- reqOverview.php
- stashrestInterface.class.php
- jiraCommons.class.php
- gforgesoapInterface.class.php
- TestlinkXMLRPCServerTest.php
Testing
Check PHP Version
php -v
Run with Strict Error Reporting
error_reporting(E_ALL);
ini_set('display_errors', '1');
Test Date Formatting
$date = tlStrftime("%Y-%m-%d", time());
echo $date; // 2026-08-16
Test Safe Counting
$items = null;
$count = tlCount($items);
echo $count; // 0 (no error)
Compatibility Matrix
| PHP Version | Status | Notes |
|---|---|---|
| 7.4 LTS | ✅ Full | Tested |
| 8.0 | ✅ Full | Tested |
| 8.1 | ✅ Full | Recommended |
| 8.2 | ✅ Full | Tested |
| 8.3 | ✅ Full | Tested |
Performance
- IntlDateFormatter: Minimal overhead, proper locale support
- Fallback date(): Near-native performance
- tlCount(): Negligible overhead (type check + count)
Format String Reference
Common strftime format strings supported by tlStrftime():
| Code | Meaning | Example |
|---|---|---|
| %Y | 4-digit year | 2026 |
| %y | 2-digit year | 26 |
| %m | Month (01-12) | 08 |
| %d | Day (01-31) | 16 |
| %H | Hour (00-23) | 14 |
| %M | Minute (00-59) | 30 |
| %S | Second (00-59) | 45 |
| %A | Full weekday | Saturday |
| %a | Abbreviated day | Sat |
| %B | Full month | August |
| %b | Abbreviated month | Aug |
| %c | Locale date/time | Sat Aug 16 14:30:45 2026 |
Migration Guide
For Developers
When adding new date formatting:
// ✅ DO: Use tlStrftime()
$date = tlStrftime("%Y-%m-%d", $timestamp);
// ❌ DON'T: Use strftime() directly
$date = strftime("%Y-%m-%d", $timestamp);
When working with counts:
// ✅ DO: Use tlCount()
if (tlCount($results) > 0) { ... }
// ❌ DON'T: Call count() on potentially null values
if (count($results) > 0) { ... } // May throw TypeError
Documentation
See docs/PHP81_COMPATIBILITY.md for detailed technical documentation.
Related Links
- Developer-Guide - Development setup
- PHP 8.1 Migration
- IntlDateFormatter Docs
Status: ✅ Completed
Issue: #140
Commits: 628457552, 1f85af2c7
Min PHP: 7.4
Recommended: 8.1+