In PHP, the sprintf function is a powerful string formatting tool that enables inserting variables into strings in a specified format. For example:
$name = "Alice";
$age = 30;
echo sprintf("My name is %s,This year %d age。", $name, $age);
The output is:
My name is Alice,This year 30 age。
Although sprintf is already very practical, sometimes we may want to have more flexibility in controlling the formatting method, or implement a "lightweight" or "customizable" formatting function in some frameworks or environments. This article will introduce how to customize a formatting function similar to sprintf using PHP.
We want to implement a function my_sprintf($template, $args) which supports the following functions:
Replace placeholders such as %s and %d ;
Supports sequential parameters or array parameters;
Maintain good readability and maintainability.
We start with a simple implementation that supports only %s and %d :
function my_sprintf($template, ...$args) {
$argIndex = 0;
$result = preg_replace_callback('/%[sd]/', function($matches) use (&$args, &$argIndex) {
$placeholder = $matches[0];
$value = $args[$argIndex++] ?? '';
if ($placeholder === '%d') {
return intval($value);
} elseif ($placeholder === '%s') {
return strval($value);
} else {
return $placeholder;
}
}, $template);
return $result;
}
echo my_sprintf("welcome %s,You have %d New news。", "Alice", 5);
Output:
welcome Alice,You have 5 New news。
If we want this function to also support passing parameters in arrays, we can modify it slightly:
function my_sprintf_array($template, array $args) {
$argIndex = 0;
$result = preg_replace_callback('/%[sd]/', function($matches) use (&$args, &$argIndex) {
$placeholder = $matches[0];
$value = $args[$argIndex++] ?? '';
return match ($placeholder) {
'%d' => intval($value),
'%s' => strval($value),
default => $placeholder,
};
}, $template);
return $result;
}
echo my_sprintf_array("Please visit https://gitbox.net/user/%s,integral:%d", ["alice", 100]);
Output:
Please visit https://gitbox.net/user/alice,integral:100
We can further support formats such as %05d (width is 5, and zero is added to the left):
function my_sprintf_extended($template, ...$args) {
$argIndex = 0;
$result = preg_replace_callback('/%0?(\d*)([sd])/', function($matches) use (&$args, &$argIndex) {
$width = (int)($matches[1] ?? 0);
$type = $matches[2];
$value = $args[$argIndex++] ?? '';
if ($type === 'd') {
$formatted = str_pad(intval($value), $width, '0', STR_PAD_LEFT);
} else {
$formatted = strval($value);
}
return $formatted;
}, $template);
return $result;
}
echo my_sprintf_extended("Order number:%05d,user:%s", 42, "bob");
Output:
Order number:00042,user:bob
Through the implementation of the above versions, we can see:
Custom formatting functions allow us to control flexibly according to business needs;
Using regular expressions combined with callback functions is the key to implementing sprintf -like;
If you need more complex formats (such as floating point, binary, placeholding order, etc.), you can continue to expand the parsing rules of regular expressions.
In actual projects, such functions are also often used in custom template engines, logging systems or DSL (domain-specific language) development, bringing more convenience and control to development.
You can encapsulate this function into your own tool library and use it in projects like https://gitbox.net to improve development efficiency.