What is the purpose of the printf() function in PHP? - php

This may seem like a really daft question, but what is the reason for the existence of the printf() function in PHP?
It seems to me that that using echo will achieve the exact same results, with the added bonus that you don't get confused if you have several variables being output on one line (true, you can use %1$s as opposed to just %s, but it can still get messey with a few variables all being declared).
I know you can also define the type of the variable, without the need to amend it before outputting the string, but to me that doesn't seem like enough to warrent creating a function.
Maybe I'm wrong, maybe I'm missing something obvious, but if someone can help me to understand why it exists (so that I know whether or not I should really be using it!) I'd appriciate it. Thanks.

echo is language construct, printf is a function. It means that so you won't be able to use echo in the same way as printf.
IT'S NOT JUST PERSONAL TASTE
Take a look to the manual pages for both functions:
echo: http://php.net/manual/en/function.echo.php
printf: http://php.net/manual/en/function.printf.php
This topic is discussed there, for example, you cannot call echo with variable functions. Moreover the way they get and manage the input is different. If you do not need the parameters FORMATTING provided by printf you should use echo (it's slightly faster).
Examples
I insist again on some keywords: formatting and function.
The use of printf isn't to concatenate strings or to build a string from placeholders but to do it with custom formatting (possibly from configuration, user inputs or whatever else).
I write some code to explain what I mean (original source in the links I posted).
This code is not valid, echo is not a function so it won't return the printed value (you may use print or sprintf for this but print does not provide string concatenation).
($some_var) ? echo 'true' : echo 'false';
Following code prints a formatted string, in this case the format comes from a literal variable but it may comes from (for example) a GET request or whatever else. Can you rewrite it with echo and the formatting string taken from the configuration?
%format = "%'.-15.15s%'.6.6s\n";
printf($format, $heading1, $value1);

printf() is a port of C's printf() function, so people who got a background writing C code are more familiar with the syntax and will prefer it.
However, most people who start with PHP find it rather confusing.
For comparison:
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
(I used sprintf(), which is the same as printf but it won't actually print the string, it just returns it)
$query = "SELECT * FROM users WHERE user='" . mysql_real_escape_string($user) . "' AND password='" . mysql_real_escape_string($password) . "'";
It's just a matter of preference!

This is about separating static string and formatting, and data.
This separation is encouraged in every programming language that I know of because:
intent of programmer is clearer and enforced
intent is clear: When you read this you know what type is awaited for each field:
printf("a: %.2f, b: %s, c: %d", $a, $b, $c)
intent is enforced: silly type errors are limited (as for the security concerns).
it's more secure
Because it limits silly injection of unexpected meta-strings:
$avg = 3.1415;
// $avg = '3</td>pawned!';
printf("average: %.2f", $avg);
It's much worse in SQL...
usually much easier to read
Appart than you have more clues to the intent of the writer, the string
is clearly in one unique clear block. Data are cleanly listed one by one
after. You don't overuse things like ", . all over the place.
it's very powerfull
I'm curious to see how you would do the following without printf:
printf("%.2f %5d", $v1, $v2);
it's some sort of standard of programming
A lot of other programming languages (C, C++, Java, Python, Bash...) will have
similar printf format and way to treat strings.
So its good for you to know it, and for those who already know, it's easier.
And as a consequence there are plenty of docs and tutorials everywhere on the
subject, and a wikipedia page for it: print format string
The strings can be separated from your data automatically
And this means it's available for translation or syntax correction.
You'll find similar concerns with:
prepared statements in mysql that are now enforced with mysql_query being
deprecated in php 5.5 in favor for prepared statements.
All templating language: where you have the template usually in a different langage,
and the data the other side to render the template.
The more general topic is covered on wikipedia: string interpolation
A last precision:
echo does nothing more than outputing a string. And printf does string interpolation, and outputs a string.
So to be fair, we are here comparing building string via string concatenation vs string interpolation. As there's nothing wrong to output a string with echo. So this is not about echo but how you make your string. You are doing string interpolation even when using echo like this:
echo sprintf("avg: %.3f", $avg);
But then, well there are no more difference between this last form and:
printf("avg: %.3f", $avg);

printf probably exists because PHP was created in C, and printf is traditionally used to output formatted strings in C. printf can actually do a lot more than echo because it can output variables in a variety of formats including decimals to certain places and probably a lot more.
That being said, you can do anything that printf can do with some combination of PHP functions, and it may make more sense depending upon your background.

I'll just explain what I did so you get a clear difference, I'm not a PHP Pro, so maybe I'm wrong and there is a better or easier approach, and also my example may be not so useful to you as well.
I pass each string I want to translate to a function, and it returns the translated string, based on source string and current language, this way it would translate:
"The cat has %d kittens." (english) <=> "Katua %d kume ditu." (euskera)
The fact is that the splitted string for the echo couldn't be translated, as the part previous to the number is not the same for every language, so it must be translated as a "single entity".

It's legacy from C inherited by the PHP language
function http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

printf takes input differently: you can provide a format string and then list all the required input (just like in C/C++).
'echo' and 'print' only take strings and are easier to use.
Your wish, Your style :)
NOT THAT:
as Others have said echo is a language construct and printf is a real function,
You can do lot with printf.
People coming from C/C++ background know a lot of format strings like %f, %d, %.2f and what not !!!!!
They would prefer printf to echo for this scenario as these floating point precison format and others will be at their finger-tips.
They wd prefer these over PHP's inbuilt format functions.

Related

PHP - evaluating param

I have following code:
<?php
$param = $_GET['param'];
echo $param;
?>
when I use it like:
mysite.com/test.php?param=2+2
or
mysite.com/test.php?param="2+2"
it prints
2 2
not
4
I tried also eval - neither worked
+ is encoded as a space in query strings. To have an actual addition sign in your string, you should use %2B.
However, it should be noted this will not perform the actual addition. I do not believe it is possible to perform actual addition inside the query string.
Now. I would like to stress to avoid using eval as if it's your answer, you're asking the wrong question. It's a very dangerous piece of work. It can create more problems than it's worth, as per the manual specifications on this function:
The eval() language construct is very dangerous because it allows
execution of arbitrary PHP code. Its use thus is discouraged. If you
have carefully verified that there is no other option than to use this
construct, pay special attention not to pass any user provided data
into it without properly validating it beforehand.
So, everything that you wish to pass into eval should be screened against a very.. Very strict criteria, stripping out other function calls and other possible malicious calls & ensure that 100% that what you are passing into eval is exactly as you need it. No more, no less.
A very basic scenario for your problem would be:
if (!isset($_GET['Param'])){
$Append = urlencode("2+2");
header("Location: index.php?Param=".$Append);
}
$Code_To_Eval = '$Result = '.$_GET['Param'].';';
eval($Code_To_Eval);
echo $Result;
The first lines 1 through to 4 are only showing how to correctly pass a character such a plus symbol, the other lines of code are working with the data string. & as #andreiP stated:
Unless I'm not mistaking the "+" is used for URL encoding, so it would
be translated to a %, which further translates to a white space.
That's why you're getting 2 2
This is correct. It explains why you are getting your current output & please note using:
echo urldecode($_GET['Param']);
after encoding it will bring you back to your original output to which you want to avoid.
I would highly suggest looking into an alternative before using what i've posted

Best way to debug an array using PHP

What is the best way to debug an array so that you can see what values are being stored and in what keys in the array they are being stored at? Also how do you make it so that it's easier to look at visually so that you don't have to keep looking through the array for the key and it's value in the one line print_r() function?
EDIT:
I now realize that print_r() is not the only solution to debugging arrays. So if you have alternate solutions that would be lovely as well to learn more about debugging.
EDIT2:
Ayesh K, ITroubs and Robert Rozas have mentioned both Krumo and Kint this far, if you have others feel free to post them. Also thanks to Raveren for writing Kint!
Every PHP developer should have a function for this. My function is below:
function r($var){
echo '<pre>';
print_r($var);
echo '</pre>';
}
To nicely print data, just call r($data);. If you want more detail, you could use this function:
function d($var){
echo '<pre>';
var_dump($var);
echo '</pre>';
}
here's mine...
demo: http://o-0.me/dump_r/
repo: https://github.com/leeoniya/dump_r.php
composer: https://packagist.org/packages/leeoniya/dump-r
you can restyle it via css if needed.
Everyone suggests print_r which is in core and works really well.
But when it comes to view a large array, print_r() drives me nuts narrowing down the output.
Give a try to krumo.
It nicely prints the array with visual formatting, click-expand and it also gives you the exact array key call that you can simply copy and paste.
<?php
krumo($my_array);
?>
Itroubs mentioned Kint as a better alternative to Krumo. (Thanks ITroubs!)
I use var_dump....now if you want some more, check out this site:
http://raveren.github.io/kint/
and
http://krumo.sourceforge.net/
The best practice to visually see the values/keys in an array is the following:
echo "<pre>".print_r($array,TRUE)."</pre>";
The true is required as it changes it into a string, the output will be:
array(
key1 => value,
key2 => value,
...
)
Quick solution: Open the source code of the page, and you'll see print_r's output in several lines and perfectly indented.
print_r is not one lined (it uses \n as new line, not <br>). Add a <pre>...</pre> around it to show the multiple lines.
print_r() uses \n as its line delimiter. Use <pre> tags or view the page's source code to make it look right. (on Windows, Linux works with \n)
You can either look source code or use var_dump() or print_r() with <pre>...</pre>
I personally, never liked all this fancy stuff, i use print_r() because it's not overwhelming and it gives enough information.
Here is mine:
if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] == 'Debug')
{
echo '<strong><i>FILE : </i></strong>'.__FILE__.'<strong> <i>LINE : </i></strong>'.__LINE__.'<pre>';
print_r($var);
echo '</pre>';
die;
}
This if statement is to ensure that other people don't see what you've printed.
There is a good add-on for Mozila-Firefox and Google Chrome called "user agent switcher", where you can create your custom user agents. So I create a user agent called "Debug", and when I'm working, I change the user agent.
If I use default user agent nothing will happen and the page wont die;, only you and people who also change the user agent to "Debug" will see the printed variable. This is helpful if you want to debug a problem in a production environment, and you don't want the page to die; and it is also good if other people are also working on the project and you don't want to interrupt them by killing the page.
Then I echo out the current File and Line, this is helpful when you work in a framework or CMS or any other big project with thousands of files and folders, and while debugging, if you might forget where you've typed die; or exit; and you need to remember where you've been and which variables you have printed.
I use the NetBeans IDE for PHP development, I have a macro set up so when you select a variable and use it, it will paste this debugging tool to the text editor and put the selection inside a print_r(); function. If you also use NetBeans, you can use this macro:
cut-to-clipboard
"if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] == 'Debug')"
insert-break
"{"
insert-break
"echo '<strong><i>FILE : </i></strong>'.__FILE__.'<strong> <i>LINE :</i></strong>'.__LINE__.'<pre>';"
insert-break
"print_r("
paste-from-clipboard
remove-line-begin
");"
insert-break
"echo '</pre>';"
insert-break
"die;"
You just need to select the $variable and use the macro.
To be honest, I'm surprised that print_r() (print human-readable). There are three native functions which each have their advantages and disadvantages in printing data to a document. As mentioned elsewhere on the page, wrapping your output in <pre> ... </pre> tags will be very beneficial in respecting newlines and tabbing when printing to an html document.
The truth is that ALL php developers, from newbie to hobbyist to professional to grand wizard level 999, need to have the following techniques in their toolbox.
Here is a non-exhaustive demo which exposes some of the differences.
var_export() is the format that I use most often. This function wraps strings in single quotes. This is important in identifying trailing whitespace characters and differentiating numeric types versus string types. To maintain the integrity of the output data and permit instant portability of the data into a runnable context, single quotes and backslashes are escaped -- don't let this trip you up.
print_r() is probably my least-used and the least-informative function when data needs to be inspect. It does not wrap strings in any kind of delimiting character so you will not be able to eyeball invisible characters. It will not escape backslashes, single quotes, or double quotes. It wraps keys in square braces which may cause confusion if your keys contain square braces originally.
var_dump() is uniquely powerful in that it expresses data types AND the byte count for strings. This is hands-down the best tool when there is a risk that you might have unexpected multibyte characters interfering with the success/stability of your script.
Depending on your php version and which function you use, you may see differing values with same input data. Pay careful attention to float values.
debug_zval_dump() very much resembles the output of var_dump(), but also includes a refcount. This native function is not likely to provide any additional benefit relating to "debugging an array".
There are also non-native tools which may be of interest (most of which I've never bothered to use). If you are using a framework, Laravel for instance, offers dd() (dump and die) as a diagnostic helper method. Some devs love the collapsed/expandable styling of this tool, but other devs loudly voice their annoyance at the tedious clicking that is necessary to expose nested levels of data.
As a sideways approach to printing iterable data, you could entertain the idea of echoing a json-encoded string with the JSON_PRETTY_PRINT. This may reveal some things that could cause trouble like multibyte and whitespace characters, but don't forget that this is literally "encoding" the data. In other words, it is converting data from one form to another and it will mutate certain occurrences in the process. Like var_export(), a json encoded string is an excellent form to maintain data integrity when it needs to be tranferred from one place to another (like from your project to your Stack Overflow question!).

PHP Query String Variable Parameters

I've noticed a lot of PHP functions accept variables like this in any order.
<?php function_name('var8=hi, var2=hello'); ?>
Edit:
Like charles mentioned the string will actually look like this:
<?php function_name('var8=hi&var2=hello'); ?>
If I wanted to write a function like that, how would I do that?
You are just passing that function a string. For it to make any sense of that, it would have to parse the string to split up the key/value pairs. I'm not saying it's the best approach, but if you want to do that, you should use parse_str().
Note that this is not by any means a language feature of PHP, but I am just providing a means to handle what you've shown.
I am confused to as why you have your parameters in quotations.
When you create a function in php you are able to set default values by setting the variable, like so:
<?php
function foo($bar = 'pie')
{
return $bar;
}
echo foo(); // will echo pie
echo foo('bar'); //will output bar
?>
That's not quite a common idiom, but if there is a strong use case and makes your API more usable, why not. Short of using parse_str and the URL-encoded format, you could of course write a mini parser for that.
Pretty simple would also be abusing parse_ini_string for that:
function function_name($paramstr) {
extract(parse_ini_string(strtr($paramstr, ",", "\n")));
You'd probably still want default values; then also needs an array_merge etc.
(The reason this is not widely used is that you end up with only string scalars, and it prohibits the delimiters in the values as well. And not often are an arbitrary number of parameters really useful.)

i18n on a variable

I would like to know if I can use a gt function on a variable with php?
eg. : echo _($var);
Feel free to. But you need to make sure the possible contents of the variable makes it into .po/.mo files. (one of the ways to do assure it is to create a dummy file never processed except for by xgettext, containing _("translate me"); expressions).
I don't think gettext will recognize a variable since it scans the source code. If you want to include variables in a string, it's better to use
sprintf()
For example
echo sprintf(_("There are %d results!"), $numResults);
In gettext, the translator will see
There are %d results!
so therefore it can easily be translated as long as he/she knows that %d is a variable. When the script gets executed, gettext will first replace the translation, and then sprintf will insert the variable $numResults. Good luck! I just got done internationalizing my site.

echoing multiple arguments when output_buffering is on

One of Googles Let's make the internet faster talks included something about using echo with multiple arguments in PHP instead of using print or string concatenation.
echo 'The ball is ', $color;
Rather than either of these
echo "The ball is $color";
echo 'The ball is ' . $color;
What if output buffering is in play ?
What would be the difference between using echo with multiple arguments along with output buffering, vs using the alternate methods without output buffering ?
Be sure to read the PHP team's rebuttal of Google's performance tips.
Specifically, he (Gwynne Raskind) says:
4) "Don't use concatenation with echo."
This is exactly the opposite of correct advice. The engine handles
multiple arguments to echo() in such a way that concatenation (or
double-quoted string interpolation) is actually much faster. See the
benchmark posted at http://pastie.org/523020.
the first version should be a bit faster because it doesn't have to parse the string for variable expansion (single quotes) and it doesn't have to spend time concatenating the two strings before writing them. i don't think that buffering will affect this

Categories