Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialKeith Colleluori
9,577 PointsWhy are all these PHP statements written with the not (!) operator?
If you go here: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
You will see that all of these statements are written basically as if we don't connect, or if we don't request, or if we don't obtain... but I don't see them actually trying to do these things (for the most part) only giving what I would consider the else echo for when something doesn't happen....
What am I missing?
2 Answers
Kevin Korte
28,149 PointsI subscribe to the same mindset as you're seeing in the docs, as to many other developers, and that is that we right code to first cover every possible way something might go wrong. For two reasons, one is it helps to remember all the ways something can fail by first addressing those scenarios, and only lastly addressing what to do if it was successful. The second, is many times code is not asynchronous, meaning that it runs one step at a time. This means we can be sure that our code goes through every check for failure first, before getting to the successful code part.
It's like a rocket launch. They check every system for failure, and only after they are sure that every check they threw at it did not fail, do they give the go ahead for a successful launch.
By first checking for all the failures, we can be reasonable assured our code was successful. If you check first if it was successful, you may have a lot of things you need to check for to be sure it actually was successful, which leads to messier, and possibly less dry code.
Jason Anello
Courses Plus Student 94,610 PointsHi Keith,
Is it correct that in these examples with the negation operator, you don't think that any database operations are being performed? In other words, the code isn't doing any actual database work here, it's only saying that error messages should be echoed if things don't work?
The database work is actually being performed in the evaluation of the if conditions.
It might help to look at an example from the link you provided.
Here's the first example with a non prepared statement:
/* Non-prepared statement */
if (!$mysqli->query("DROP TABLE IF EXISTS test") || !$mysqli->query("CREATE TABLE test(id INT)")) {
echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
So the php interpreter needs to evaluate that if condition to see if it's true
or false
. To do that it needs to call the query method on the $mysqli object and that method will return a value back to the if condition for further evaluation.
So when the query method is called is when the actual attempt to drop the table happens. If will return true if successful and false on failure.
If it failed then you have !false
which is true
which means you'll execute the if block and echo an error message.
On the other hand, let's suppose it succeeded. This means it needs to evaluate the right side of the OR
operator. Again, this involves calling the query method and attempting to create the table. This will either return true or false depending on the result.
If that succeeded as well then the entire if condition evaluates to false and you won't print an error message.
So when you've reached the end of the if statement, you've either printed an error message because what you tried to do failed or the database operation was successful and you skipped over the if block.
Does that help at all?
Keith Colleluori
9,577 PointsOk so I think what I am reading is that asking PHP if the query fails doubles as asking it to perform the query? So by writing the query this way you save the step of having to perform the query as well as error check, and combine them into one?
It seems like thats not the right answer to me because its too convenient lol. Maybe I'll just go try it out myself ;)
Jason Anello
Courses Plus Student 94,610 PointsYes, you can think of it as performing the query and checking if it failed combined into one.
What if the code was rewritten like this:
/* Non-prepared statement */
$failure = !$mysqli->query("DROP TABLE IF EXISTS test") || !$mysqli->query("CREATE TABLE test(id INT)")
if ($failure) {
echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
Does that make it easier to understand? It does the same thing but requires an extra line of code and variable.
This separates running the queries and then checking if it failed.
Keith Colleluori
9,577 PointsKeith Colleluori
9,577 PointsOk I think I see what you are saying. BUT how can you check if something failed without commanding the computer to do it? So lets just say that code says if no connection established echo failure to connect... how could there be a connection if we didn't ask it to? Writing the statement in the negative doesn't attempt to do the connection, correct? Still feel I am missing something.
Kevin Korte
28,149 PointsKevin Korte
28,149 PointsGood question, in the scope of the examples, in the link, it doesn't make much sense. It would make more sense if you were making a connection (especially with an api), and where wanting to check a few different ways it could fail first. By say !something we're just saying the if statement evaluates true, if the statement in it is not true.
Here is a real world example, in javascript, but the same principals apply. You can extract the principals from the code, and relate it back to php. And this is pretty readable even if you don't know javascript well.
https://themeteorchef.com/recipes/building-a-saas-with-meteor-stripe-part-1/
Basically, it's checking if the first call errored - no, okay, did the response from the api error - no, okay call this new function, did it error - no, okay now go to this new url
/lists
.