In PHP, what are the differences between echo and print, and why is neither of them a function?
answer
- both are language constructs
- echo takes several comma-separated arguments
- print takes one and returns 1
- parentheses belong to the expression
- no variable-function calls
basics
~10 sBoth output strings and are language constructs, not functions. echo accepts several comma-separated arguments and returns nothing; print accepts one argument and always returns 1, so it can appear inside an expression.
solid answer
~40 s`echo` and `print` are **language constructs**, so they need no parentheses and cannot be called as variable functions or with named arguments. `echo` takes **one or more** comma-separated expressions and has **no return value**, so it cannot be used inside an expression. `print` takes **exactly one** expression and **always returns 1**, which makes `$ok and print 'done'` or a ternary with `print` legal. Parentheses are allowed but are part of the expression, which surprises people: `print(1 + 2) * 3` prints `9`, and `echo('a', 'b')` is a parse error. Both coerce non-string values to strings even under `strict_types`. In practice teams use `echo` (and `<?=` in templates) everywhere; the performance difference is not worth discussing.
go deeper
Recall that both are language constructs, echo takes several arguments with no return value, and print takes one and returns 1.
Explain why parentheses are part of the expression, with print(1 + 2) * 3 printing 9 and echo('a', 'b') failing to parse.
Point out the precedence trap between concatenation and the ternary, and prefer comma-separated echo or explicit parentheses in output code.
Treat this as a style decision: one output construct in code and <?= in templates, enforced by a coding standard, with escaping handled by the template layer.
## Two constructs that output text PHP has two built-in ways to write a string to the output: `echo` and `print`. Neither is a function; both are **language constructs**, handled by the parser like `if` or `return`. That has practical consequences: - **No parentheses are needed**: `echo $name;` and `print $name;`. - **They cannot be used as callables**: you cannot call them through a variable (`$f = 'echo'; $f('x');` fails), pass them to `array_map()`, or use named arguments with them. - **Non-string values are coerced** to strings, even when `declare(strict_types=1)` is active; `strict_types` governs function parameters, and these are not functions. ## The differences | Aspect | `echo` | `print` | |---|---|---| | Arguments | one or more, separated by commas | exactly one | | Return value | none | always `1` | | Usable inside an expression | no | yes | | Short template form | `<?= $x ?>` | none | Because `print` returns `1`, it can appear where an expression is required: ```php <?php $dish = 'Soup'; $ok = true; $ok && print "Serving {$dish}\n"; // print as an expression ($ok) ? print "yes\n" : print "no\n"; // both branches are expressions ``` Writing `echo` in either position is a parse error, because `echo` is a statement with no value. ## The parentheses trap Parentheses after `echo` or `print` are **not** a call syntax. They are part of the expression being output: 1. `print("hello");` works because `("hello")` is a valid expression. 2. `print(1 + 2) * 3;` prints `9`: the whole `(1 + 2) * 3` is the argument. 3. `if (print("hello") && false)` prints an empty string and then runs the `if` body: the argument is `("hello") && false`, which is `false`, printed as `""`, and `print` returns `1`. 4. `echo("hello", " world");` is a **parse error**, because `("hello", " world")` is not an expression. `echo "hello", " world";` is the correct form. The manual documents each of these; they are the classic follow-up once a candidate has said "print returns 1". ## Commas versus concatenation `echo` with several arguments outputs each one in turn. That avoids precedence surprises with the `.` operator. Concatenation binds tighter than the ternary operator, so: ```php <?php echo 'Hello ' . isset($name) ? $name : 'guest'; // always evaluates to $name echo 'Hello ', isset($name) ? $name : 'guest'; // what was meant ``` In the first line PHP evaluates `'Hello ' . isset($name)`, which is a non-empty string and therefore true, so the ternary always picks `$name`, even when it is unset. ## What gets printed for non-strings Both constructs convert their argument to a string with the normal conversion rules: | Value | Printed as | |---|---| | `true` / `false` / `null` | `1` / empty / empty | | int | its digits | | float | formatted with the `precision` ini setting (default 14), so `0.1 + 0.2` prints `0.3` | | array | `Array`, with an `E_WARNING` "Array to string conversion" (a notice before PHP 8.0) | | object with `__toString()` | the method's result | | object without it | an `Error`: "Object of class ... could not be converted to string" | So `echo $order;` on an array is a bug that prints the word `Array`, and on a plain object it stops the request. ## Which one to use - **`echo`** is the everyday choice in code and, through `<?=`, in templates. Coding standards and most codebases use it. - **`print`** is rare; its one real advantage is being an expression, which is seldom clearer than an `if`. - Neither escapes anything. Echoing user data into HTML needs escaping first, which is a security topic of its own. The speed difference between them is negligible and not a reason to choose either. An interviewer asking this question wants the construct-not-function point, the argument and return-value difference, and ideally one of the parentheses traps.
- Why can't you pass echo to array_map() or call it through a variable?Because `echo` is a language construct, not a function. It has no entry in the function table, so it cannot be a callable, be called as a variable function, or take named arguments. Wrap it in a closure when you need a callable: `array_map(fn (string $s) => print $s, $items)` or a `foreach` with `echo`.
- What does `print(1 + 2) * 3;` output, and why?It prints `9`. `print` is not a function, so the parentheses do not delimit its argument; they only group `1 + 2`. The argument is the whole expression `(1 + 2) * 3`, which is `9`. The same applies to `echo(1 + 2) * 3;`.
saying these in an interview costs you the question
- echo and print are functions, so they need parentheses.
- print returns true or false depending on success.
- echo('a', 'b') is valid because echo accepts several arguments.
- strict_types makes echo throw a TypeError for an int.
- print is noticeably faster than echo in real applications.