Solar_Locale and named placeholders (was Re: [Solar-talk] Pager helper changes)

Paul M Jones pmjones at ciaweb.net
Mon Jul 2 10:58:56 CDT 2007


On Jul 1, 2007, at 9:07 AM, Rodrigo Moraes wrote:

> 2007/7/1, Rodrigo Moraes
>> a preg_match_all would be something like
>> 5x slower than vsprintf, but is this something to worry about?
>
> I made a benchmark using Solar_Text_Bench, but sometimes the results
> are strange :P:
>
> name              : diff : total
> __start           : 0.000000 : 0.000000
> benchVSprintF     : 0.006196 : 0.006196
> benchPregMatchAll : -0.341567 : -0.335371
> __stop            : 0.000000 : -0.335371
>
> I don't understand the negative value, but it only happens sometimes.

Very strange; I don't know what to say to that -- maybe preg_match_all 
() uses the "tachyon" stream wrapper?  ;-)


> Here's the comparison class:
>
> class Tipos_Bench_Placeholder extends Solar_Test_Bench
> {
>    public function benchVSprintF()
>    {
>        $string = '%1$d-%2$d de %3$d';
>        $replace = array(101, 150, 2010);
>
>        return vsprintf($string, (array) $replace);
>    }
>
>    public function benchPregMatchAll()
>    {
>        $string = ':item_x-:item_y of :count';
>        $replace = array(
>            'item_x' => 101,
>            'item_y' => 150,
>            'count'  => 2010,
>        );
>
>        preg_match_all(
>            "/:([a-zA-Z_][a-zA-Z0-9_]*)/m",
>            $string . "\n",
>            $matches
>        );
>
>        return str_replace($matches[0], $replace, $string);
>    }
> }

Normally I don't like str_replace(), because if you have ":page" and  
":pages", the ":page" part of ":pages" gets matched and replaced  
(leaving you with just the "s").

However, if we change the syntax a bit to "{:page}" then we can use  
only str_replace() and a foreach() in Solar_Locale::_trans().   
There's no preg*() call, and we don't have the mismatch problem  
because the braces delimit the placeholder.

         // do replacements?
         if ($replace) {
             // by vsprintf(), or by preg_match_all() ?
             $key = key($replace);
             if (is_int($key)) {
                 // sequential array, use vsprintf()
                 $string = vsprintf($string, (array) $replace);
             } else {
                 // assoc array, use str_replace()
                 foreach ($replace as $key => $val) {
                     $string = str_replace("{:$key}", $val, $string);
                 }
             }
         }

Surely not as fast as vsprintf(), but I think it suits our purposes  
(clarity and order-independence) -- especially since I don't see us  
using lots of named replacements in any given locale string, or lots  
of locale strings that need replacements.

Don't know if this makes sense, happy to hear arguments for/against  
here.



--

Paul M. Jones  <http://paul-m-jones.com>

Solar: Simple Object Library and Application Repository
for PHP5.  <http://solarphp.com>

Join the Solar community wiki!  <http://solarphp.org>

Savant: The simple, elegant, and powerful solution for
templates in PHP.  <http://phpsavant.com>




More information about the Solar-talk mailing list