I keep coming across statements like:
echo is a language construct but
print is a function and hence has a
return value
and
die is a language construct
My question is what are these language constructs and more importantly why do we need them?
Language constructs are hard coded into the PHP language. They do not play by normal rules.
For example, whenever you try to access a variable that doesn't exist, you'd get an error. To test whether a variable exists before you access it, you need to consult isset or empty:
if (isset($foo))
If isset was a normal function, you'd get a warning there as well, since you're accessing $foo to pass it into the function isset. Since isset is a language construct though, this works without throwing a warning. That's why the documentation makes a clear distinction between normal functions and language constructs.
Language constructs are what makes up the language: things like "if" "for" "while" "function" and so on.
The mentions in the PHP manual of things like "echo", "die" or "return" are there to make it clear that these are NOT functions and that they do not always behave like functions.
You could call "echo" as "echo()" so it may confuse beginners. That's why they put the clear disinction in the manual. To make it absolutely clear to everyone.
Other examples for language constructs that could be mistaken for functions are "array()", "list()" and "each()".
To understand the answer for this question you must understand how parsers work. A language is defined by syntax and the syntax is defined through keywords.
The language constructs are pieces of code that make the base of PHP language. The parser deals with them directly instead of functions.
Not all of a language can be functions. There must be some base, somewhere, on which you implement those first functions. The elements of this base are the language constructs (alternately, built-ins). They don't always behave like "normal" functions do.
For the sake of completeness, a language construct is any instruction which is built into the language itself, while a function is an additional block of code.
In some cases, a language may choose to build in a particular feature or to rely on a separate function.
For example, PHP has the print language construct, which outputs a string. Many other languages, such as C don’t build it in, but implement it as a function. There might be technical reasons for taking one or other approach, but sometimes it is more philosophical — whether the feature should be regarded as core or additional.
For practical purposes, while functions follow a rigid set of logistic rules, language constructs don’t. Sometimes, that’s because they may be doing something which would otherwise traumatise a regular function. For example, isset(…), by its very purpose, may be referencing something which doesn’t exist. Functions don’t handle that at all well.
Here are some of the characteristics of language constructs:
Many don’t require parentheses; some do sometimes.
Language Constructs are processed in a different stage; functions are processed later
Some Language Constructs, such as isset do things which would be impossible as functions; some others, such as Array(…) could have gone either way.
Some Language Constructs certainly don’t look like functions. For example, the Array(…) construct can be written as […].
As the documentation keeps reminding us, language constructs cannot be referenced as variable variables. So $a='print_r'; $a(…); is OK, but $a='print'; $a(…); isn’t.
Some things are just not possible using normal functions, consider this snippet:
list($el1, $el2) = array('el1', 'el2');
What it does is it takes the elements from a non-associative array and assigns the values to the variables defined in the list() construct.
Simply cannot be done with functions :)
A more subtle example is issetand empty. Though they look like functions, they one thing that's not possible with functions alone – they do not generate "variable is undefined" or "undefined index" notices.
language constructs can be formed in more than one way and has a return-value
print("asdf"); is as possible as print "asdf"; and will return 1.
echo("asdf"); is equal to echo "asdf;" but has no return-value.
die("asdf"); is equal to exit("asdf"); and hasn't a return-value too.
Related
why codacy(code review tool) showing "echo language construct is discouraged."
how to solve this issue.
1:
You can either:
Replace echo with print_r:
print_r( $StateList->state_name )
Return the value instead:
return $StateList->state_name
As for why your linter discourages the use of echo, this depends on your coding standard and context.
For example, if you wish to follow the PSR-1 Basic Coding Standard, section 2.3 states that:
A file SHOULD declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it SHOULD execute logic with side effects, but SHOULD NOT do both.
Since echo produces a side effect, it would be discouraged in the context of a file that was declaring a new class, for instance. In this context, you'd return the value instead.
Codacy detects linting problems on your code base. Linting problems may be security bugs, code style issues, etc.
In your case, it's bad practice to use php "echo". Just like you shouldn't use println in other languages. If you need to print something, you should use loggers
Is there a possible way to combine the if function and the isset function (Or other functions) into one function.
For example:
if(isset($_GET['test'])){
echo "It exists";
}
into
exitsts($_GET['test']){
echo "It exists";
}
I searched on google and stackoverflow and used multiple ways to describe it.
But no solution.
So is there a solution for it?
Thanks in advance!
Bram Hammer
No, this is not possible. If is not a function, but a syntax element. Usually in most programming languages you have functions, which take values and return values (and maybe do something behind the back in the process) and syntax elements, which can be used to structure the code and have it behave in certain ways, for example branching (if-then-else), looping (for,while etc). The distinction in most languages is simple: If it has a block of code behind it, then it is a syntactic element, if it is somehow called, it is a function. However this may not be true for all languages.
It is usually not possible to add your own syntax elements, unless the language explicitly allows it through some meta-programming facilities, like macros or other powerful tools used to extend the language. As far as I know PHP does not offer any such tools. One way to get them for languages which do not offer them out of the box is to use an additional preprocessor, such as M4. However this is rarely useful.
Some languages also allow treating blocks of code as values, so in that case you can use functions in a similar way as syntactic elements, passing them code which has not yet been evaluated. If blocks of code cannot be directly used, maybe the language offers anonymous functions or anonymous classes, which can be used to simulate this. However usually these simulated control-structures are not nearly as nice looking as the built in control structures. I am not sure whether PHP allows anonymous functions, or classes, you may be able to build something like the structure you want, but it will look very ugly.
create custom function:
function exitsts($var){
if(isset($var)){
return "It exists";
}
else{
return "doesn't exsits";
}
}
then do your check:
echo exitsts($_GET['test']);
There is, use empty
if(!empty($_GET['test'])){
/* matches
"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)
*/
}
I was reading up on Paul Bigger's http://blog.paulbiggar.com/archive/a-rant-about-php-compilers-in-general-and-hiphop-in-particular/ and he mentions that HPHP doesn't fully support dynamic constructs. He then states, "Still, a naive approach is to just stick a switch statement in, and compile everything that makes sense." Is he saying that instead of a dynamic include, you could use switch statements to include the proper file? If so, why would this work and why is it "easier" for a compiler to compile? As always, thx for your time!
from my understanding, if you've got this
include "$foo.php";
the compiler would have no clue what you're going to include. On the other side, with this
switch($foo) {
case 'bar' : include "bar.php";
case 'quux' : include "quux.php";
}
they can simply compile "bar" and "quux" and wrap them in an if statement which checks $foo and executes whatever is appropriate.
A compiler expects to be able to identify all of the source and binary files that might be used by the program being compiled.
include($random_file);
If the file named in $random_file declares constants, classes, variables, the compiler will have no way knowing because the value of $random_file is not known at compile time. Your code using those constants, classes and variables will fail in difficult-to-debug ways. The switch statement would make known the list of possible files so the compiler can discover any relevant declarations.
Languages designed to be compiled have dynamic linkers and foreign function interfaces that combine to provide similar functionality to include($random_file) without needing the explicit switch.
I'm just curious. In PHP, why wasn't echo implemented as a function? Why didn't PHP just give us printf and never tell about echo? Please note that:
This is not a question about echo vs. printf.
I already knew that echo is a language construct.
UPDATE: By the way, was printf implemented using echo?
Echo is not a function and it doesn't return a value like print. Print is a language construct too - does not require parenthesis.
Manual:
echo - No value is returned.
print - Returns 1, always.
The fact remains that returning a value degrades system performance.
So.. now since printf IS a function (which returns the length of the outputted string) the answer I believe is obvious.
Echo is a language construct. Function use language construct to do their job. Explaining is not exactly my specialty, but a google action brought me to this topic:
What is the difference between a language construct and a "built-in" function in PHP?
Some important content:
...
This is the root of why you can't redefine language constructs like echo or print:
they're effectively hardcoded into the parser, whereas functions are mapped to a
set of language constructs and the parser allows you to change that mapping at
compile- or runtime to substitute your own set of language constructs or expressions.
...
Just a wild guess, but perhaps it's because PHP used to exist as CGI binaries. So it would be for making porting shell scripts easier, since you could use the echo binary in those.
I know that include, isset, require, print, echo, and some others are not functions but language constructs.
Some of these language constructs need parentheses, others don't.
require 'file.php';
isset($x);
Some have a return value, others do not.
print 'foo'; //1
echo 'foo'; //no return value
So what is the internal difference between a language construct and a built-in function?
(This is longer than I intended; please bear with me.)
Most languages are made up of something called a "syntax": the language is comprised of several well-defined keywords, and the complete range of expressions that you can construct in that language is built up from that syntax.
For example, let's say you have a simple four-function arithmetic "language" that only takes single-digit integers as input and completely ignores order of operations (I told you it was a simple language). That language could be defined by the syntax:
// The | means "or" and the := represents definition
$expression := $number | $expression $operator $expression
$number := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
$operator := + | - | * | /
From these three rules, you can build any number of single-digit-input arithmetic expressions. You can then write a parser for this syntax that breaks down any valid input into its component types ($expression, $number, or $operator) and deals with the result. For example, the expression 3 + 4 * 5 can be broken down as follows:
// Parentheses used for ease of explanation; they have no true syntactical meaning
$expression = 3 + 4 * 5
= $expression $operator (4 * 5) // Expand into $exp $op $exp
= $number $operator $expression // Rewrite: $exp -> $num
= $number $operator $expression $operator $expression // Expand again
= $number $operator $number $operator $number // Rewrite again
Now we have a fully parsed syntax, in our defined language, for the original expression. Once we have this, we can go through and write a parser to find the results of all the combinations of $number $operator $number, and spit out a result when we only have one $number left.
Take note that there are no $expression constructs left in the final parsed version of our original expression. That's because $expression can always be reduced to a combination of other things in our language.
PHP is much the same: language constructs are recognized as the equivalent of our $number or $operator. They cannot be reduced into other language constructs; instead, they're the base units from which the language is built up. The key difference between functions and language constructs is this: the parser deals directly with language constructs. It simplifies functions into language constructs.
The reason that language constructs may or may not require parentheses and the reason some have return values while others don't depends entirely on the specific technical details of the PHP parser implementation. I'm not that well-versed in how the parser works, so I can't address these questions specifically, but imagine for a second a language that starts with this:
$expression := ($expression) | ...
Effectively, this language is free to take any expressions it finds and get rid of the surrounding parentheses. PHP (and here I'm employing pure guesswork) may employ something similar for its language constructs: print("Hello") might get reduced down to print "Hello" before it's parsed, or vice-versa (language definitions can add parentheses as well as get rid of them).
This is the root of why you can't redefine language constructs like echo or print: they're effectively hardcoded into the parser, whereas functions are mapped to a set of language constructs and the parser allows you to change that mapping at compile- or runtime to substitute your own set of language constructs or expressions.
At the end of the day, the internal difference between constructs and expressions is this: language constructs are understood and dealt with by the parser. Built-in functions, while provided by the language, are mapped and simplified to a set of language constructs before parsing.
More info:
Backus-Naur form, the syntax used to define formal languages (yacc uses this form)
Edit: Reading through some of the other answers, people make good points. Among them:
A language builtin is faster to call than a function. This is true, if only marginally, because the PHP interpreter doesn't need to map that function to its language-builtin equivalents before parsing. On a modern machine, though, the difference is fairly negligible.
A language builtin bypasses error-checking. This may or may not be true, depending on the PHP internal implementation for each builtin. It is certainly true that more often than not, functions will have more advanced error-checking and other functionality that builtins don't.
Language constructs can't be used as function callbacks. This is true, because a construct is not a function. They're separate entities. When you code a builtin, you're not coding a function that takes arguments - the syntax of the builtin is handled directly by the parser, and is recognized as a builtin, rather than a function. (This may be easier to understand if you consider languages with first-class functions: effectively, you can pass functions around as objects. You can't do that with builtins.)
Language constructs are provided by the language itself (like instructions like "if", "while", ...) ; hence their name.
One consequence of that is they are faster to be invoked than pre-defined or user-defined functions (or so I've heard/read several times)
I have no idea how it's done, but one thing they can do (because of being integrated directly into the langage) is "bypass" some kind of error handling mechanism. For instance, isset() can be used with non-existing variables without causing any notice, warning or error.
function test($param) {}
if (test($a)) {
// Notice: Undefined variable: a
}
if (isset($b)) {
// No notice
}
*Note it's not the case for the constructs of all languages.
Another difference between functions and language constructs is that some of those can be called without parenthesis, like a keyword.
For instance :
echo 'test'; // language construct => OK
function my_function($param) {}
my_function 'test'; // function => Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING
Here too, it's not the case for all language constructs.
I suppose there is absolutely no way to "disable" a language construct because it is part of the language itself. On the other hand, lots of "built-in" PHP functions are not really built-in because they are provided by extensions such that they are always active (but not all of them)
Another difference is that language constructs can't be used as "function pointers" (I mean, callbacks, for instance) :
$a = array(10, 20);
function test($param) {echo $param . '<br />';}
array_map('test', $a); // OK (function)
array_map('echo', $a); // Warning: array_map() expects parameter 1 to be a valid callback, function 'echo' not found or invalid function name
I don't have any other idea coming to my mind right now... and I don't know much about the internals of PHP... So that'll be it right now ^^
If you don't get much answers here, maybe you could ask this to the mailing-list internals (see http://www.php.net/mailing-lists.php ), where there are many PHP core-developers ; they are the ones who would probably know about that stuff ^^
(And I'm really interested by the other answers, btw ^^ )
As a reference : list of keywords and language constructs in PHP
After wading through the code, I've found that php parses some of statements in a yacc file. So they are special cases.
(see Zend/zend_language_parser.y)
Apart from that I don't think that there are other differences.
You can override built-in functions. Keywords are forever.