This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
PHP - and / or keywords
I saw several bits of PHP code using or in a way I was unfamiliar with. For example:
fopen($site,"r") or die("Unable to connect to $site");
Is this equal to this ||?
Why would you use this instead of a try catch block? What will cause the program run the or die()?
It is for the most part, but...
The reason for the two different
variations of "and" and "or" operators
is that they operate at different
precedences.
See http://php.net/manual/en/language.operators.logical.php
or is equal to || except that || has a higher presedense than or.
Reference:
http://www.php.net/manual/en/language.operators.precedence.php
or has an other precedence. The concrete statement is little trick with boolean operators. Like in a common if-test-expression the second part is only executed, if the first is evaluated to false. This means, if fopen() does not fail, die() is not touched at all.
However, try-catch only works with Exceptions, but fopen() doesnt throw any.
Today something like this is "not so good" style. Use exceptions instead of hard abortion
if (!($res = fopen($site, 'r'))) throw new Exception ("Reading of $site failed");
or die happens with the first command fails.
It is similar to a try catch, but this is more direct approach.
Note that this is a classical test:
fopen($site,"r") or die("Unable to connect to $site");
Only if fopen($site,"r") returns false, will the second half of the test be run: 'die('error')'.
Same is if(a || b); b is only run if a returns false.
Die in PHP is the same as exit();
http://www.php.net/manual/en/function.exit.php
Stops execution of the current script entirely, and prints out the error message.
Yes it equals ||
In this case it is explicitly stopping the execution of the page and printing that error message.
Related
For some reason when I run the .php script:
$s = yaml_parse_file("../config.yaml") || die("YAML file not found");
var_dump($s);
it returns:
bool(true)
What on earth is going on? This has happened out of nowhere it was working fine for a week and I can't seem to fix it. I have installed using pecl install yaml and added "extension=yaml.so" to php.ini?
I have used online yaml regex testers and they return that it is okay. The format is (obviously with content):
title:
email: hello#
logo: images/logo.png
download-file: .dmg
recaptcha:
pub:
priv:
meta:
keywords: mac, osx
description:
ico: images/icon.ico
You're assigning the result of the boolean operation to $s, since the || operator has a higher precedence than the assignment. So it's being evaluated as follows:
$s = (yaml_parse_file("../config.yaml") || die("YAML file not found"));
This returns true, since the initial expression returns a "truthy" value.
If you wrap the assignment in brackets, it will work as you are expecting:
($s = yaml_parse_file("../config.yaml")) || die("YAML file not found");
...
See https://eval.in/960405
The code worked before, when it used to read:
$s = yaml_parse_file("../config.yaml") or die("YAML file not found");
You recently changed or with || (why?) without knowing that they are different operators and they have different precedence.
or has the lowest precedence and the expression above is evaluated as:
($s = yaml_parse_file(...)) or die(...)
|| has higher precedence than the assignment (=) and the expression posted in the question evaluates as:
$s = (yaml_parse_file(...) || die(...))
To solve the issue, first you should forget about or die(). It is bad coding practice spread out by PHP tutorial more than 15 years ago. It's sad that many of them are still available on the web and teach the newbies how to throw a white page on the face of their visitors when an error happens.
or die() is useless. If yaml_parse_file() (or whatever function call you "handle" using it) returns FALSE, the next statement that attempts to use the result most probably will fail anyway. And you'll get a more or less descriptive error message in php_errors.log. That error message help you debug the code and identify and fix the errors. or die doesn't help with anything. It just hides the error under the carpet and tells the visitor what they can see by themselves: that your site doesn't work. But it doesn't tell you what was the error or how to fix it.
$file= #fopen("ssssss.php", r) or die("not found");
(#include("ssssss.php")) or die("not found");
In the first statement we don't put ( ) around #fopen and it is working fine.
But in the second if I didn't put these () it does't show any message.
so why with include I must round it with ( ) ?
I agree with the suggestions in the other answers but the actual answer to your question is this:
In the PHP documentation they say to take care when comparing the return value of include.
That's because it is a special construct and parentheses are not needed.
So when you do this (without wrapping parentheses):
#include("ssssss.php") or die("not found");
You're actually doing this, because or is evaluated first:
#include (("ssssss.php") or die("not found"));
Now, "ssssss.php" is a non empty string that evaluates logically to true.
or is a logical operator that gives true if any of the parameters is true (or both of them).
Also, this operator is short-circuit: if the first parameter is true, php already knows that the operator or will return true, so it doesn't waste time evaluating the second parameter, and die() is not executed.
So finally, or gives true and your sentence becames this:
#include (1);
Php tries to "include 1", and it would raise a warning but it does not because of the #.
Here you have a similar example in php.net.
Your first sentence is not the same case.
$file= #fopen("ssssss.php", r) or die("not found");
fopen is just a regular Php's function with its parentheses. Here you need to have in mind two operators: = and or.
= has higher precedence than or, so, if fopen's result is correctly assigned to $file (and it is), that operation will return true. And, as I explained before, "true or anything else", gives true but die() is not executed because of the short-circuit operator.
You should be using file_exists instead of using the # as the later covers all sorts of issues. A better solution would be...
if (file_exists("ssssss.php")) {
$file= #fopen("ssssss.php", r);
}
and
if (file_exists("ssssss.php")) {
include("ssssss.php");
}
That's not really a good use of include. If you need to include a php file and generate an error on failure, use require or require_once.
If you need to get the contents of the whole file, you could use file_get_contents().
Also, I agree with Nigel Ren about the use of # - it is a dangerous practice and should be avoided.
Seeing the exit() PHP documentation got me thinking:
$filename = '/path/to/data-file';
$file = fopen($filename, 'r')
or exit("unable to open file ($filename)");
Couple questions:
What are common use cases besides opening files for using exit()?
Since not every function everyone ever writes ends in exit(), how do you know to use it in some contexts vs. others?
Are if/else and or/exit interchangeable?
In that context, the or in that statement is one of PHP's logical operators which when used like that, will execute the second statement if and only if the first one fails due to short circuit evaluation.
Since fopen returned false, the or exit statement gets executed since the first part failed.
To understand it better, here is a quick explanation of short-circuit evaluation.
$x = 5;
$y = 42;
if ($x == 5 or $y == 42) {
echo "x or y is true";
}
In the above code, the expression $y == 42 is never evaluated because there is no need since the first expression was true.
In that example, they are using the same logic for deciding whether or not to evaluate the statement that calls exit.
To address your questions:
I wouldn't use exit when opening a file failed unless the program was very specific. The better thing to do would be to log an error and then return the error to the caller so they can decide what to do.
When to use exit completely depends on the code you are writing.
Given the explanation about short-circuiting, yes they are interchangeable in that sense. Using or exit is just a bit shorter than using if/else.
Hope that helps.
CLI scripts, exit can take an integer parameter which is fed back to the console to indicate success or some form of error
I'm not inclined to use exit() or die() in application code, since exceptions are preferred. However, I personally think you might be overcomplicating things a little bit... it kills script execution, so use it when you need to kill a script. Truthfully I mostly only ever kill scripts mid-execution when debugging (one-off breakpoints) and that's not ideal either (again exceptions do a better job).
The use of or is mostly convenient. Here's an interesting point though...
Why does
$resource = mysql_connect() || die('dead')
not work?
The answer is that the = operator takes precedence over or so that the assignment is made first like so: ($resource = mysql_connect()) or die(). In this way its exactly like doing an if(!($resource = mysql_connnect())) { die() }
I tend to avoid using exit() at all as it's a really ugly way to handle errors from the user's perspective.
If you must use it, any non recoverable error would be a candidate. For example, database query or connection failures, or remote request failures.
if/else is equivalent to ...or whatever(). It's just a style thing, with the latter form being more succinct.
I would say you use exit in a situation where your code cannot continue if the function you were doing failed. For example reading a file that is needed.
This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
PHP - and / or keywords
PHP shorthand syntax
Quick question. I keep seeing shorthand expressions in libraries around the place, and despite having been a PHP developer for over 3 years, I struggle to quite see how the following would evaluate.
What exactly does the PHP interpreter do with the following shorthand lines of code when it encounters them?
<?php
defined('foo') OR exit('foo is not defined!');
$foo AND $this->bar();
I'm guessing that it' obviously conditional execution - i.e. the second statement won't get executed unless the first bit is true... but the use of the bitwise operators confuse me a bit.
Can someone elaborate?
Thanks :)
I believe that this is a form of short-circuit evaluation: http://en.wikipedia.org/wiki/Short-circuit_evaluation
Essentially, when evaluating an entire expression, the interpreter short circuits once it is certain of the result. For example:
true OR do_something();
This expression never calls do_something() because the first operand of OR is true, so the entire expression must be true.
Back when I was learning PHP I remember reading the 'do or die' style commands and not fully understanding them at the time, the classic example is:
mysql_connect() or die('couldn\'t connect');
Bear in mind that the conditions will only run if they're required, for example:
if (a == b && b == c)
Here b == c will only be tested if a == b. The same theory applies to or:
if (a == b || b == c)
Now b == c will only be tested if a != b.
In this case you are relying on this order to run a command (exit or $this->bar()) in certain conditions.
Be Aware... exit() is a bad idea in this circumstance - if you exit('something went wrong') there's nothing anyone can do to hide this error from the user, also it's likely to issue a 200 OK HTTP status where a 500 Internal Server Error would be much more appropriate, I would consider something more like:
defined('foo') OR throw new Exception('foo is not defined!');
Here you have a chance to either catch the Exception or at least let PHP catch it and issue a 500 status.
Mat
Much less elaborate than you think. The or keyword is the same as ||, except it has lower precedence. See the corresponding PHP page for details.
The actual execution of this statement relies on a separate concept involving logical operators: short circuiting. This means that, in the case of or, the second statement is not evaluated if the first statement turns out to be true. (Since in a conditional, for instance, the entire condition would return true without ever needing to see the second half.)
Sometimes you have a function that looks something like:
function test()
{
$foo = TRUE;
$bar = FALSE;
return $foo && $bar;
}
In this case, if some does:
$bla = test();
if($bla) {
... do something
}
The "...do something" will not get executed, because the function as a whole returned false.
return $foo && $bar means that both variables have to be true in order for the function to return true.
On the other hand, if it stated: return $foo || $bar; then the function would return true, because at least one variable is true.
I'm writing a php app to access a MySQL database, and on a tutorial, it says something of the form
mysql_connect($host, $user, $pass) or die("could not connect");
How does PHP know that the function failed so that it runs the die part? I guess I'm asking how the "or" part of it works. I don't think I've seen it before.
If the first statement returns true, then the entire statement must be true therefore the second part is never executed.
For example:
$x = 5;
true or $x++;
echo $x; // 5
false or $x++;
echo $x; // 6
Therefore, if your query is unsuccessful, it will evaluate the die() statement and end the script.
PHP's or works like C's || (which incidentally is also supported by PHP - or just looks nicer and has different operator precedence - see this page).
It's known as a short-circuit operator because it will skip any evaluations once it has enough information to decide the final value.
In your example, if mysql_connect() returns TRUE, then PHP already knows that the whole statement will evaluate to TRUE no matter what die() evalutes to, and hence die() isn't evaluated.
If mysql_connect() returns FALSE, PHP doesn't know whether the whole statement will evaluate to TRUE or FALSE so it goes on and tries to evalute die() - ending the script in the process.
It's just a nice trick that takes advantage of the way or works.
It works as others have described.
In PHP, do not use "die", as it does NOT raise an exception (as it does in Perl). Instead throw an exception properly in the normal way.
die cannot be caught in PHP, and does not log - instead it prints the message ungracefully and immediately quits the script without telling anybody anything or giving you any opportunity to record the event, retry etc.
If you would like to add more code if the connection doesn't work, beyond a die statement:
$con=mysql_connect($host, $user, $pass)
if(!$con)
{
// ... add extra error handling code here
die("could not connect");
}
else
{
echo "Connected";
}