Echo vs. Print

Christopher Pitt
3 min readAug 14, 2014

--

There’s much mystery and misinformation about this fundamental area of PHP. Every PHP developer learns how to make text appear on a page. Usually it’s with the help of echo. Later they have to figure out what’s actually inside a variable, and they are taught/discover either print_r() or var_dump().

Tonight I attended a workshop, where some aspects of PHP were taught to people new to the language. These kinds of workshops are hard to give, because people will ask questions which only new people would, and often they are about areas of the language long since forgotten or ignored by experienced PHP developers.

One of the attendees asked what the difference was between echo and print, and immediately I though quite certain of their function. Then I thought about the subtle differences between all the variable printing functions, and how they are never really explained in detail. Let’s change that!

echo

echo is a language construct which looks like a function, but isn’t. According to the documentation; it outputs multiple (string) parameters, yet when I attempt this it generates a syntax error:

php > echo("foo", "bar", "baz");

PHP Parse error: syntax error, unexpected ',' in php shell code on line 1

Be that as it may, the brackets are optional:

php > echo "foo"; echo("bar");

foobar

echo does not return a value. It’s only job is to output a string.

Seems I should have tried multiple strings without the brackets. Thanks to those who have pointed this out. ☺

print

Unlike echo; the documentation for print correctly states that it will output a single string. It is also not strictly a function, but bizarrely will always return 1. As a result, the following things happen:

php > print "foo"; print("bar"); print print print "baz";

foobarbaz11

Strange. Definitely strange.

print_r

Following these practically similar constructs, print_r starts to develop the idea of outputting a variable. The idea behind print_r is to output/return a human-readable representation of a single variable:

php > print_r("foo"); print_r(2); print_r(true);

foo21

The second (boolean) parameter of print_r tells PHP whether to return the value or output it. true means return, false means output. The default is false.

php > echo print_r(["foo" => "bar"], true);

Array
(
[foo] => bar
)

print_r will return a lot of information for deeply-nested objects. When it spots recursive references, it will omit them, and display *RECURSION*. You may also have noticed that there is whitespace surrounding parts of the output, which make the output easier to read.

var_dump

Similarly, var_dump() outputs a representation of one or more variables. Like echo, the documentation for var_dump() says it will handle multiple variables. Unlike echo this appears to be true:

php > var_dump("foo", "bar");

string(3) "foo"
string(3) "bar"
php > var_dump(new StdClass);

class stdClass#1 (0) {
}

var_dump() also shows nested data, but installing the XDebug extension will limit this to three levels deep, and require a configuration change to show more again.

This XDebug configuration change you will need to make is xdebug.var_display_max_depth=n.

var_dump() does not output extra whitespace, so this makes it difficult to read the output. Additionally, the XDebug extension will wrap everything in HTML elements (for syntax highlighting), so reading var_dump() output is a nightmare on the command line.

var_export

var_export() is similar to print_r(), in that it can output directly, or return a string. However, the output/return is valid PHP syntax:

php > var_export(["foo" => "bar"]);

array (
'foo' => 'bar',
)

You’ll not often find a good use for this method, and when you do you’ll probably return (rather than output) the representation. When you pass an instance to it, you get quite a strange representation:

php > $instance = new Thing();
php > $instance->foo = "bar";
php > var_export($instance);

Thing::__set_state(array(
'foo' => 'bar',
))

If that code was parsed; the __set_state() method would be called on the Thing class. Here’s an example of what you might do then:

class Thing
{
public $foo;

public static function __set_state($state)
{
$thing = new Thing();
$thing->foo = $state["foo"];
return $thing;
}
}

You should also note that resource variables can’t be exported:

php > var_export(fopen("http://google.com", "r"));

NULL

This is great for solving a very specific problem; reading, updating and writing PHP configuration files:

return [
"foo" => "bar
];

This is from config.php

$config = file_get_contents("config.php");

$config["hello"] = "world";

file_put_contents(
"config.php",
"return " . var_export($config, true) . ";"
);

This is from update.php

return array (
'foo' => 'bar',
'hello' => 'world',
);

This is from config.php

Though the formatting has changed slightly, this simple script has done a powerful thing. The alternatives (which maintain formatting, indentation and comments) are staggeringly complicated.

--

--