note 83779 added to function.sprintf
| From: | jaimthorn at yahoo dot com | Date: | Wed, 11 Jun 2008 14:01:19 +0000 |
| Subject: | note 83779 added to function.sprintf | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-140347@lists.php.net to get a copy of this message | ||
I needed a piece of code similar to the one Matt posted below, on the 10th of March, 2008. However,
I wasn't completely satisfied with Matt's code (sorry, Matt! No offense intended!),
because
1) I don't like to initialize variables when it's not really needed, and
2) it contains two bugs.
What are the bugs?
First, Matt's code tests for count($vars) > 0, but if $var == "Hello world!", then
count($var) == 1, but the foreach() will crash because $var has to be an array. So instead, my code
tests for is_array($var).
Second, if a key in $vars is a prefix of any of the later keys in the array (like 'object'
is the beginning of 'objective') then the str_replace messes things up. This is no big
deal if your keys are hard-coded and you can make sure the keys don't interfere, but in my code
the keys are variable. So I decided to first sort the array on a decreasing length of the key.
<?php
function cmp($a, $b)
{
return strlen($b) - strlen($a);
}
function sprintf2($str, $vars, $char = '%')
{
if(is_array($vars))
{
uksort($vars, "cmp");
foreach($vars as $k => $v)
{
$str = str_replace($char . $k, $v, $str);
}
}
return $str;
}
echo sprintf2( 'Hello %your_name, my name is %my_name! I am %my_age, how old are you? I like
%object and I want to %objective_in_life!'
, array( 'your_name' => 'Matt'
, 'my_name' => 'Jim'
, 'my_age' => 'old'
, 'object' => 'women'
, 'objective_in_life' => 'write code'
)
);
?>
If possible, and if you're willing, you can also embed the key fields in the text between
percent-signs, rather than prefixing the keys with one. Sorting is no longer necessary, and the
execution time is less than half of the code above:
<?php
function sprintf3($str, $vars, $char = '%')
{
$tmp = array();
foreach($vars as $k => $v)
{
$tmp[$char . $k . $char] = $v;
}
return str_replace(array_keys($tmp), array_values($tmp), $str);
}
echo sprintf3( 'Hello %your_name%, my name is %my_name%! I am %my_age%, how old are you? I like
%object% and I want to %objective_in_life%!'
, array( 'your_name' => 'Matt'
, 'my_name' => 'Jim'
, 'my_age' => 'old'
, 'object' => 'women'
, 'objective_in_life' => 'write code'
)
);
?>
If you're willing to embed the keys in the text, you may also be willing to embed the keys
themselves in percent signs, thus shaving off another 30% of the execution time:
<?php
function sprintf4($str, $vars)
{
return str_replace(array_keys($vars), array_values($vars), $str);
}
echo sprintf4( 'Hello %your_name%, my name is %my_name%! I am %my_age%, how old are you? I like
%object% and I want to %objective_in_life%!'
, array( '%your_name%' => 'Matt'
, '%my_name%' => 'Jim'
, '%my_age%' => 'old'
, '%object%' => 'women'
, '%objective_in_life%' => 'write code'
)
);
?>
Of course, by now the sprintf function is no longer something you'd want to write to mum and
dad about...
----
Server IP: 83.137.20.135
Probable Submitter: 24.132.252.217
----
Manual Page -- http://www.php.net/manual/en/function.sprintf.php
Edit -- https://master.php.net/note/edit/83779
Del: integrated -- https://master.php.net/note/delete/83779/integrated
Del: useless -- https://master.php.net/note/delete/83779/useless
Del: bad code -- https://master.php.net/note/delete/83779/bad+code
Del: spam -- https://master.php.net/note/delete/83779/spam
Del: non-english -- https://master.php.net/note/delete/83779/non-english
Del: in docs -- https://master.php.net/note/delete/83779/in+docs
Del: other reasons-- https://master.php.net/note/delete/83779
Reject -- https://master.php.net/note/reject/83779
Search -- https://master.php.net/manage/user-notes.php