I hate that google can not search for symbols. I saw this in some sample code and wondered why there is an # sign before the readfile function:
#readfile($filename);
What does it mean different to without an # symbol?
An # before a command in PHP means that no errors are printed. It's called the error control operator.
If you removed the # and readfile would encounter an error (such as not being able to read the file), then—depending on your PHP settings—the error message will be amidst your site content; something you rarely, if ever, want. (It gets worse even, if this happens before a call to header() or start_session() because once content is sent, the headers can't be written anymore.)
I refer to # as being the "stfu operator".
It is PHP's error suppression operator. With it you can suppress error messages.
Tip:
Simply don’t use the error suppression operator with speed-critical code.
Future:
Because # operator is very slow, it won't work on ini_set eg #ini_set in future version of PHP eg PHP6
Important Reading:
Bad uses of the # operator
It's error control operator. Manual will tell you everything...
# means "don't show errors/warnings"
FYI
You can use " " to search queries containing special characters in google.
Example to search - #readfile in PHP? search it
You can search - "#readfile in PHP?" search it
Related
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Reference - What does this symbol mean in PHP?
I'm making a web application that uses URL queries to access different parts of the application. I was looking for a solution to make an invalid query like index.php?page=dashboarrrd display an error 404 message instead of a PHP error.
After some searching, I found that I could use something like the following to do the job:
if(!#include($fileName)){
#include("pageData/404.php");
}
And that makes sense, but I don't know why that works. I mean, what the heck does the # before the include mean? I totally understand include $filename; but I need an explanation for #include ($fileName)
the code you really need is
$fileName = "pagedata/".basename($_GET['page']).".php";
if(is_readable($fileName)) {
include($fileName);
} else {
include("pagedata/404.php");
}
and # has absolutely nothing to do here
# is one of biggest delusions coming from lack of experience.
Ones who using it do expect only one kind of error, while in fact there can be many more. And to gag ALL possible messages to suppress only one of them is definitely like to throw out the child along with the bath.
There is a fundamental problem that makes such misunderstanding so widespread:
Most PHP users cannot distinguish three sides of error control:
error handling
error reporting
user notification.
Most of time in sake of [3] people mess with (1) and (2). While each of them require separate treatment:
your program should raise no intentional errors. No error should be part of program logic. All errors that ever raised should be only unexpected ones.
if you expect some error, you have to handle it. Not gag with #, but gracefully handle. is_readable() in my code exactly for that.
error reporting is for the programmer and should be always at max. So, error logging should be enabled on a live site and a programmer have to check all errors occurred. And of course he would be interested in such errors, thus # will do only harm here.
User-level error messages should be different from system ones. Your 404.php is a good example of such user-friendly behavior. As for the system error messages, a user shouldn't be able to see them at all. Just turn display_errors off and see - there is no use for the # again!
This is the # Error Control Operator (quoting) :
When prepended to an expression in
PHP, any error messages that might be
generated by that expression will be
ignored.
In normal conditions, if include cannot load the file you've passed as a parameter, it'll emit a warning.
Prepending the # operator to include will prevent that warning from being emited -- and, so, from being displayed / logged.
So, the following portion of code :
include 'does-not-exist.php';
Will get you the following warnings :
Warning: include(does-not-exist.php) [function.include]: failed to open stream: No such file or directory
Warning: include() [function.include]: Failed opening 'does-not-exist.php' for inclusion
While this line :
#include 'does-not-exist.php';
Will get you not warning.
And, as a sidenote, for information : Five reasons why the shut-op operator (#) should be avoided
The # suppresses errors. This is generally discouraged, as when developing you want to see errors.
Errors are easy to suppress when moving to a production environment with the display_errors setting to off. So yea, in most cases, there really is no need for the error to be suppressed.
EDIT
As an extra tidbit to "improve" that, what I used to do when dynamically including a file, is have an array which acts as a "white list" of valid requests. This does not "have" to be an array, just what I chose to do an example with.
$whiteList = array('filename1', 'index', 'home', 'about');
if (in_array($filename, $whiteList)) {
include($filename);
}else {
include('page/404.php');
}
This would do a few things, 1 make you not need the error suppressor. Two, it would make it a bit more securer, as without this, you would need to do a basename call to filter the text to prevent certain type of include injections etc. (Not knowing if you did this already, just extra information).
So yea, you may want analyze / look at other ways to achieve this and above is just one method :)
The use of "#" simply suppresses the error that would normally result from (in this instance) a missing file. Whilst generally its use is a very bad idea, there are some rare exceptions, such as the code snippet you provide above.
For more information, see the Error Control Operators section of the PHP manual.
Additionally, you might find the existing Reference - What does this symbol mean in PHP? question worthy of a quick scan.
The # in php suppresses all error output. For instance, if you had error reporting for warnings, an # in front of a function that generated a warning would not display the warning text.
include is an example of such a construct. If the included file is not found, it will display a warning saying so. The # is not necessary in the code at all, it is just there so that the user will not see warnings.
However, it is better to use apache (or php if you prefer) to change ini for displaying errors on the development site and not displaying them on the production site. That would make the # symbol useless.
A better question is why you need to do this 404 include. Why are you including a file for display? Why not have apache handle 404 redirects on its own? Why wouldn't the file exist in the first place?
# suppresses error messages. The parentheses are optional in include, but whoever wrote that snippet included them.
#include() is the opposite of require(). The first will silently ignore an (optional and missing) include script, while the second will throw an error and halt the script when the (critical) dependency is missing.
In this instance it is only senseful within the if(). The second should preferrably not have an error suppression, as it doesn't mask any seriously security-relevant error message.
Why can't you hide errors with the # operator when calling unset? The following results in a parse error:
#unset($myvar);
The # operator only works on expressions, and unset is a language construct, not a function. See the manual page for more information:
Note: The #-operator works only on
expressions. A simple rule of thumb
is: if you can take the value of
something, you can prepend the #
operator to it. For instance, you can
prepend it to variables, function and
include() calls, constants, and so
forth. You cannot prepend it to
function or class definitions, or
conditional structures such as if and
foreach, and so forth.
You can hide errors by prefixing # to functions/statements. However unset is a language construct, therefore it doesn't support the #-rule.
The good thing is that unset() never fails even if the variable didn't exist to begin with, so this shouldn't be necessary.
As nightcracker mentionned though, using # is pretty bad practice.
The error suppression operator only works on expressions:
unset is a language construct and not a function, so # cannot be used.
Why can't you hide errors with the # operator when calling unset?
I do not know. But you should not be using the error suppression operator (#) anyway. There are two distinct scenarios:
Developemnt
You want to see all errors right at the moment they happen, preferably with the raw error message that PHP gives you.
Production
You want to let no PHP error message bubble to the user. Instead you want to log the PHP error message and display your own message that a layman can understand.
You cannot achieve this distinction when you use #. You should separate theses scenarios by configuring display_errors, error_reporting and setting an error handler with set_error_handler.
This question already has answers here:
Reference Guide: What does this symbol mean in PHP? (PHP Syntax)
(24 answers)
Closed 4 years ago.
What does the '#' symbol do in the following code?
#mkdir(ROOT. "cache/");
It suppresses errors from displaying:
PHP supports one error control operator: the at sign (#). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.
If the track_errors feature is enabled, any error message generated by the expression will be saved in the variable $php_errormsg. This variable will be overwritten on each error, so check early if you want to use it.
As noted in the comments, I too cannot imagine a reason to actually use this functionality -- write code that deals appropriately with error states/conditions.
As pointed out, it is the error suppression operator.
But what has not been pointed out, is that it is very bad practice to use - errors should not fail silently.
Check for error returns, and use try/catch blocks where exceptions are being used.
In the specific example...
#mkdir(ROOT. "cache/");
...it ignores any errors from mkdir(). The docs says it returns FALSE on failure, so you should be doing...
if ( ! mkdir(ROOT. "cache/")) {
// Handle error.
}
People seem to forget that PHP was a quick dirty language for getting things done, only recently has it tried to be mature and sophisticated.
Error suppression is a quick and dirty way of making functions behave the way you need them to, because in web-development you cannot predict what will be thrown at you, and sometimes it is not worth caring!
A classic example is the useful function getimagesize, that allows you to get some information about an image that someone has uploaded.
This function chucks a wobbly if the image file is not a standard image file. It is not really the developers role to inspect a file, determine if it can be loaded into getimagesize. There might be elegant ways of doing this, but seriously I don't care!
just do this:
if( !($a = #getimagesize( $_FILE['file']['tmp_name'] )))
{
unlink( $_FILE['file']['tmp_name'] );
//politely tell user that you rejected their image!
}
yes, you could use try and catch statements which are more elegant, but in the end, you have caught the error and suppressed the error message, which is what you wanted without wearing out the tab-key!
Contrary to what above answers say, the # prefix used carefully does not result in a runaway train wreck. It just allows the developer to accommodate errors in the way they prefer.
I am writing a PHP mail function and some examples have #mail(…) and others have just mail(…).
What is the difference and which one is best to use?
Cheers
# supresses all warnings/errors, which mail() function may throw.
It is not good practice to use "#", because you never know if something doesn't work and also it hits the performance of you PHP application too!
It's the same function but with error suppression
PHP: Error Control Operators - Manual
#mail means you are suppressing any errors that might occur while trying to send the email, see this SO question for more information: Suppress error with # operator in PHP
Error suppression is resource-consuming operation.
It is recommended to call functions without # and use exceptions/error handling
I've seen code samples that use an # before fopen as in
$fh = #fopen($myFile, 'w');
What's the significance of this #?
It suppresses errors an expression may display.
You can read more about it here.
Example:
file_get_contents('file_does_not_exist'); //this shows an error
#file_get_contents('file_does_not_exist'); //this does not
Its PHP's error control char.
PHP supports one error control operator: the at sign (#). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.
More here.
Using # is always bad practice. It will suppress an error message if occurrs, while error messages are extremely useful for the programmer and suppressing it is suicide. PHP's fate is to be used mostly not by programmers but by casual users who have no clue. You've got this code from one of that latter kind. So, better to get rid of all #, so, you'll be able to see what happened and correct a mistake.
Note that every error message has it's particular meaning and explain what the problem is.
For example there can be filesystem permissions problem or PHP OPEN_BASEDIR setting to prevent file from open. So, an error message will tell you what to do. Error messages is good and # is evil.