Formatting Strings with PHP

Formatting Strings with PHP
Until now, we have simply printed any strings we want to display directly to the browser in their original state. PHP provides two functions that allow you first to apply formatting, whether to round doubles to a given number of decimal places, define alignment within a field, or display data according to different number systems. In this section, you will look at a few of the formatting options provided by printf() and sprintf().

آموزش طراحی سایت اختصاصی و برنامه نویسی PHP برای هموطنان ایرانی داخل و خارج از کشور

ارایه درگاه پرداخت ePayBank.ir برای سایتهای برنامه نویسی شده با زبان برنامه نویسی PHP

ارایه امکان تبلیغات اینترنتی خدمات و محصولات فیزیکی و مجازی با درج آگهی در MyCityAd.ir

Working with printf()
If you have any experience with a C-like programming language, you will be familiar with the concept of the printf() function. The printf() function requires a string argument, known as a format control string. It also accepts additional arguments of different types, which you’ll learn about in a moment. The format control string contains instructions regarding the display of these additional arguments. The following fragment, for example, uses printf() to output an integer as an octal (or base-8) number:

<?php
printf(“This is my number: %o”, 55);
// prints “This is my number: 67″
?>

Within the format control string (the first argument), we have included a special code, known as a conversion specification.

A conversion specification begins with a percent (%) symbol and defines how to treat the corresponding argument to printf(). You can include as many conversion specifications as you want within the format control string, as long as you send an equivalent number of arguments to printf().

The following fragment outputs two floating-point numbers using printf():

<?php
printf(“First number: %f<br/>Second number: %f<br/>”, 55, 66);
// Prints:
// First number: 55.000000
// Second number: 66.000000
?>

The first conversion specification corresponds to the first of the additional arguments to printf(), or 55. The second conversion specification corresponds to 66. The f following the percent symbol requires that the data be treated as a floating-point number. This part of the conversion specification is the type specifier.

printf() and Type Specifiers
You have already come across two type specifiers, o, which displays integers as octals, and f, which displays integers as floating-point numbers. Table 10.1 lists the other type specifiers available.

Table 10.1. Type Specifiers Specifier
Description

d
Display argument as a decimal number

b
Display an integer as a binary number

c
Display an integer as ASCII equivalent

f
Display an integer as a floating-point number (double)

o
Display an integer as an octal number (base 8)

s
Display argument as a string

x
Display an integer as a lowercase hexadecimal number (base 16)

X
Display an integer as an uppercase hexadecimal number (base 16)

Listing 10.1 uses printf() to display a single number according to some of the type specifiers listed in Table 10.1.

Notice that we do not only add conversion specifications to the format control string. Any additional text we include will also be printed.

Listing 10.1. Demonstrating Some Type Specifiers
1: <?php
2: $number = 543;
3: printf(“Decimal: %d<br/>”, $number);
4: printf(“Binary: %b<br/>”, $number);
5: printf(“Double: %f<br/>”, $number);
6: printf(“Octal: %o<br/>”, $number);
7: printf(“String: %s<br/>”, $number);
8: printf(“Hex (lower): %x<br/>”, $number);
9: printf(“Hex (upper): %X<br/>”, $number);
10: ?>

Put these lines into a text file called printftest.php and place this file in your web server document root. When you access this script through your web browser, it should look something like Figure 10.1. As you can see, printf() is a quick way of converting data from one number system to another and outputting the result.

Figure 10.1. Demonstrating conversion specifiers.

When specifying a color in HTML, you combine three hexadecimal numbers between 00 and FF, representing the values for red, green, and blue. You can use printf() to convert three decimal numbers between 0 and 255 to their hexadecimal equivalents:

<?php
$red = 204;
$green = 204;
$blue = 204;
printf(“#%X%X%X”, $red, $green, $blue);
// prints “#CCCCCC”
?>

Although you can use the type specifier to convert from decimal to hexadecimal numbers, you can’t use it to determine how many characters the output for each argument should occupy. Within an HTML color code, each hexadecimal number should be padded to two characters, which would become a problem if we changed our $red, $green, and $blue variables in the previous fragment to contain 1, for example. We would end up with the output #111. You can force the output of leading zeroes by using a padding specifier.

Padding Output with the Padding Specifier
You can require that output be padded by leading characters. The padding specifier should directly follow the percent sign that begins a conversion specification. To pad output with leading zeroes, the padding specifier should consist of a zero followed by the number of characters you want the output to take up. If the output occupies fewer characters than this total, the difference will be filled with zeroes:

<?php
printf(“%04d”, 36);
// prints “0036″
?>

To pad output with leading spaces, the padding specifier should consist of a space character followed by the number of characters that the output should occupy:

<?php
printf(“% 4d”, 36)
// prints ” 36″
?>

By the Way

A browser will not display multiple spaces in an HTML document. You can force the display of spaces and new lines by placing <pre> tags around your output:

<pre>
<?php echo “The spaces will be visible”;
?>
</pre>

If you want to format an entire document as text, you can use the header() function to change the Content-Type header:

header(“Content-Type: text/plain”);

Remember that your script must not have sent any output to the browser for the header() function to work as desired.

You can specify any character other than a space or a zero in your padding specifier with a single quotation mark followed by the character you want to use:

<?php
printf (“%’x4d”, 36);
// prints “xx36″
?>

We now have the tools we need to complete our HTML code example. Until now, we could convert three numbers to hexadecimal, but we could not pad the hexadecimal values with leading zeroes:

<?php
$red = 1;
$green = 1;
$blue = 1;
printf(“#%02X%02X%02X”, $red, $green, $blue);
// prints “#010101″
?>

Each variable is output as a hexadecimal number. If the output occupies fewer than two spaces, leading zeroes will be added.

Specifying a Field Width
You can specify the number of spaces within which your output should sit. The field width specifier is an integer that should be placed after the percent sign that begins a conversion specification (assuming that no padding specifier is defined). The following fragment outputs a list of four items, all of which sit within a field of 20 spaces. To make the spaces visible on the browser, we place all our output within a pre element:

<?php
echo “<pre>”;
printf(“%20s\n”, “Books”);
printf(“%20s\n”, “CDs”);
printf(“%20s\n”, “DVDs”);
printf(“%20s\n”, “Games”);
printf(“%20s\n”, “Magazines”);
echo “</pre>”;
?>

Figure 10.2 shows the output of this fragment.

Figure 10.2. Aligning with field width specifiers.

By default, output is right-aligned within the field you specify. You can make it left-aligned by prepending a minus () symbol to the field width specifier:

printf(“%-20s\n”, “Left aligned”);

Note that alignment applies to the decimal portion of any number that you output. In other words, only the portion before the decimal point of a double will sit flush to the end of the field width when right aligned.

Specifying Precision
If you want to output data in floating-point format, you can specify the precision to which you want to round your data. This is particularly useful when dealing with currency. The precision identifier should be placed directly before the type specifier. It consists of a dot followed by the number of decimal places to which you want to round. This specifier only has an effect on data that is output with the f type specifier:

<?php
printf(“%.2f”, 5.333333);
// prints “5.33″
?>

By the Way

In the C language, it is possible to use a precision specifier with printf() to specify padding for decimal output. The precision specifier will have no effect on decimal output in PHP. Use the padding specifier to add leading zeroes to integers.

Conversion Specifications: A Recap
Table 10.2 lists the specifiers that can make up a conversion specification in the order that they would be included. Note that it is difficult to use both a padding specifier and a field width specifier. You should choose to use one or the other, but not both.

Table 10.2. Components of Conversion Specification Name
Description
Example

Padding specifier
Determines the number of characters that output should occupy, and the characters to add otherwise
‘.4′

Field width specifier
Determines the space within which output should be formatted
’20′

Precision specifier
Determines the number of decimal places to which a double should be rounded
‘.4′

Type specifier
Determines the data type that should be output
‘d’

Listing 10.2 uses printf() to output a list of products and prices.

Listing 10.2. Using printf() to Format a List of Product Prices
1: <?php
2: $products = array(“Green armchair” => “222.4″,
3: “Candlestick”=> “4″,
4: “Coffee table”=> “80.6″);
5: echo “<pre>”;
6: printf(“%-20s%20s\n”, “Name”, “Price”);
7: printf(“%’-40s\n”, “”);
8: foreach ($products as $key=>$val) {
9: printf( “%-20s%20.2f\n”, $key, $val );
10: }
11: echo “</pre>”;
12: ?>

We first define an associative array containing product names and prices in lines 2 through 4. We print the opening tag of the pre element in line 5, so that the browser will recognize our spaces and newlines. Our first printf() call on line 6 uses the following format control string:

“%-20s%20s\n”

The first conversion specification in the format control string (“%-20s”) defines a width specifier of 20 characters, with the output to be left-justified. The string type specifier is also used. The second conversion specification (“%20s”) sets up a right-aligned field width. This printf() call will output our field headers.

Our second printf() function call on line 7 draws a line containing characters, 40 characters wide. We achieve this with a padding specifier, which adds padding to an empty string.

The final printf() call on line 9 is part of a foreach statement that loops through the product array. We use two conversion specifications herethe first (“%-20s”) prints the product name as a string left-justified within a 20-character field, and the second (“%20.2f”) uses a field width specifier to ensure that output will be right-aligned within a 20-character field. We also use a precision specifier to ensure that the output is rounded to two decimal places.

Put these lines into a text file called printftest2.php and place this file in your web server document root. When you access this script through your web browser, it should look like Figure 10.3.

Figure 10.3. Products and prices formatted with printf().

[View full size image]

Argument Swapping
Imagine that you are printing dates to the browser. You have the dates in a multidimensional array and you are using printf() to format the output.

<?php
$dates = array(
array(‘mon’=> 12, ‘mday’=>25, ‘year’=>2005),
array(‘mon’=> 5, ‘mday’=>23, ‘year’=>2006),
array(‘mon’=> 10, ‘mday’=>29, ‘year’=>2005)
);
$format = include(“local_format.php”);
foreach($dates as $date) {
printf(“$format”, $date['mon'], $date['mday'], $date['year']);
}
?>

In the preceding snippet, the format control string comes from an include file called local_format.php. Assuming that this file contains only

<?php
return “%02d/%02d/%d<br/>”;
?>

our output will be in the format mm/dd/yyyy:

12/25/2005
05/23/2006
10/29/2005

Imagine now that we are installing our script for a European site, where dates are commonly presented with days before months (dd/mm/yyyy). Assume that the core code is written in stone and cannot be changed. What should you do? Luckily we can now alter the order in which the arguments are presented from within the format control code by changing the return statement to

return “%2\$02d/%1\$02d/%3\$d<br/>”;

We can insert the argument number we are interested in after the initial percentage character that marks each conversion specification, followed by an escaped dollar ($) character. So, in our fragment, we are demanding that the second argument be presented:

%2\$02d

followed by the first argument:

%1\$02d

and concluded with the third argument:

%3\$d

The result of the new code is a list of dates in British format:

25/12/2005
23/05/2006
29/10/2005

Storing a Formatted String
The printf() function outputs data to the browser, which means that the results are not available to your scripts. You can, however, use the function sprintf(), which is used just like printf() except that it returns a string that can be stored in a variable for later use. The following fragment uses sprintf() to round a double to two decimal places, storing the result in $cash:

<?php
$cash = sprintf(“%.2f”, 21.334454);
echo “You have \$$cash to spend.”;
// Prints “You have $21.33 to spend.”
?>

One particular use of sprintf() is to write formatted data to a file you can call sprintf() and assign its return value to a variable that can then be printed to a file with fputs().