TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   Tips & Tricks (http://www.talkphp.com/tips-tricks/)
-   -   Don't repeat yourself when using printf! (http://www.talkphp.com/tips-tricks/1129-dont-repeat-yourself-when-using-printf.html)

Salathe 09-16-2007 06:15 PM

Don't repeat yourself when using printf!
 
Hi folks,

We all use printf (or sprintf) to help ourselves when mingling together output strings with our variables, right? This is a tip that I use often, but I continually see people writing code where this technique would be useful but isn't used. What am I on about? Well, how many times have you seen people write something similar to this:
PHP Code:

echo '<ul>';
foreach (
$aItems as $aItem)
{
    
// E.g., <li><a href="link.html" title="Link 2">Link 2</a> (link.html)</li>
    
printf('<li><a href="%s" title="%s">%s</a> (%s)</li>',
           
$aItem['link'],
           
$aItem['title'],
           
$aItem['title'],
           
$aItem['link']);
}
echo 
'</ul>'

Notice that in the printf call, there are a number of repeated arguments (2 x $aItem['link'], and 2 x $aItem['title']). Wouldn't it be great if we could satisfy the lazy side within all of us and not repeat ourselves? Well, it's possible! Take a look at the amended example below:
PHP Code:

printf('<li><a href="%1$s" title="%2$s">%2$s</a> (%1$s)</li>',
       
$aItem['link'],
       
$aItem['title']); 

Ok, I admit for those of you not well versed in using this (or those who didn't look at the code very hard) might well be a little lost right now. What's with the extra stuff messing up our nice, normal "%s" placeholders?

Well, the extra stuff is what helps us to be lazy! The "1$" and "2$" allow us to point to the argument number which will fill in that particular placeholder. In the code above, 1$ refers to $aItem['link'] and 2$ refers to $aItem['title']. The numbers preceding the dollar sign simply reference the order of the arguments fed into the function call. What makes things useful for us, in this instance, is that the numbered replacements can be repeated any number of times within the template string without the need to add more (of the same) arguments as we did in the original example up above!

Finally, here is another example which hopefully should help to cement things into your own mind about using numbered placeholders in your (s)printf function calls:
PHP Code:

$szAdjective 'fluffy';
$szNoun 'cat';

// Both methods will output the following:
//     Yesterday, I saw a cat. It was a fluffy cat! 
//     I have never seen a cat quite so fluffy.

// Old-school method
printf('Yesterday, I saw a %s. '.
       
'It was a %s %s! I have '.
       
'never seen a %s quite so %s.',
       
$szNoun,
       
$szAdjective,
       
$szNoun,
       
$szNoun,
       
$szAdjective);

// Sexy, lazy method
printf('Yesterday, I saw a %1$s. '.
       
'It was a %2$s %1$s! I have '.
       
'never seen a %1$s quite so %2$s.',
       
$szNoun,
       
$szAdjective); 

Be lazy, use numbered placeholders! :)

Wildhoney 09-25-2007 09:50 PM

Be lazy indeed! I've seen this on my travels, but in admission, I've never actually really taken the time to learn it. I have now!

Salathe 09-25-2007 10:23 PM

Just wait until you start using placeholders like %1$'x-10.20s, then it gets really interesting! Yes, that is a single placeholder like %s.

Wildhoney 09-25-2007 10:26 PM

You know what your next article is then :) !

Salathe 09-25-2007 10:30 PM

I think I may have scared people away with this article (judging by the huge list of comments), never mind getting into the relative complexities of the optional parameters within the placeholders! Though if someone asks, it might be good to write up a quick lesson. :)

ReSpawN 11-23-2007 09:23 PM

Ooh hell no. I've tested in the program I call sandbox (part of my CMS for testing wild idea's of mine) and I must say, wow.

Tripping down the code here (nubstyle).

PHP Code:

# First we define the replacements right? Ok here we go.
$firstReplacement 'dang';
$secondReplacement 'it';

# Same way, the lazy way.
printf('Oh man, today I saw this chick and may I say %1$s %2$s!'$firstReplacement$secondReplacement); 

Which displayed:
Quote:

Oh man, today I saw this chick and may I say dang it!
Only tell me one thing, how could I make this practical?

Andrew 11-23-2007 10:03 PM

Very nice article, and good to know. I've never gotten to the point where I've repeated myself in a sprintf() or printf() statement, but now I never will have to.


All times are GMT. The time now is 02:36 AM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0