Description
PHP Version
8.4
CodeIgniter4 Version
4.6.1
CodeIgniter4 Installation Method
Composer (using codeigniter4/appstarter
)
Which operating systems have you tested for this bug?
Windows
Which server did you use?
apache
Database
No response
What happened?
When validating an array with 5 or more items using a regex_match
rule containing curly braces (e.g., \d{4}
or \d{6}
), CodeIgniter throws a CodeIgniter\Exceptions\LogicException: No validation rules for the placeholder: "4". You must set the validation rules for the field. See <https://codeigniter4.github.io/userguide/libraries/validation.html#validation-placeholders>
My observations:
- The error only occurs when the data array has ≥5 items (index
4
triggers the bug). - The issue stems from CodeIgniter's parser misinterpreting numeric curly braces inside the regex pattern as validation placeholders (e.g.,
{4}
).
I might be misunderstanding how validation placeholders interact with regex patterns. If this is expected behavior, clarification in documentation would be appreciated.
Steps to Reproduce
<?php
namespace placeholders;
use CodeIgniter\Test\CIUnitTestCase;
use Config\Services;
final class RegexTest extends CIUnitTestCase {
private array $rules = [
'*.uid' => [
'label' => 'Order.uid',
'rules' => [
'if_exist',
'required',
'string',
'regex_match[/^(\d{4})\/(0[1-9]|1[0-2])\/\d{6}$/]' // Contains {4} and {6}
]
]
];
private array $data = [
['uid' => '2025/06/000001'],
['uid' => '2025/06/000002'],
['uid' => '2025/06/000003'],
['uid' => '2025/06/000004']
];
public function testLessThat5() {
$validation = Services::validation();
$validation->reset();
$validation->setRules($this->rules);
// Works with 4 items
self::assertTrue($validation->run($this->data));
}
public function testEqualTo5() {
$validation = Services::validation();
$validation->reset();
$validation->setRules($this->rules);
// Fails with 5 items (index 4 triggers the bug)
$largerData = array_merge($this->data, [['uid' => '2025/06/000005']]);
// Throws CodeIgniter\Exceptions\LogicException
self::assertTrue($validation->run($largerData));
}
}
Expected Output
Validation should ignore curly braces inside regex patterns and run successfully regardless of:
- The presence of
{n}
in regex patterns. - The size of the data array (including arrays with ≥5 items).
Anything else?
Root Cause:
The validation parser incorrectly scans regex patterns (delimited by /.../
) for placeholders like {4}
. When the data array has 5+ items, the index 4
is misinterpreted as a placeholder requiring validation rules.
Workaround:
As a temporary solution, you can use a custom validation rule to bypass the parser issue:
// Custom rule
public function valid_uid(string $uid): bool {
return (bool) preg_match('/^(\d{4})\/(0[1-9]|1[0-2])\/\d{6}$/', $uid);
}
// Rules definition
'rules' => [
'required',
'valid_uid' // No regex pattern in string -> no parsing issues
]
Although the above custom rule allows avoiding this problem, I think that using such a workaround shouldn't be necessary :/