What does if($con->connect_errno) mean? - php

I'm learning php and i have a file that connects to a mysql database, i'd like to know what is the condition inside the brackets of the following "if structure" in the file, $con is an instance of the class mysqli:
if ($con->connect_errno)
{
echo "fail to connect to mysql";
}
I know that $con is invoking to connect_errno but what is conditioning if(what?){...}?

That's a status flag for mysqli handles.
See http://php.net/manual/en/mysqli.connect-errno.php
It's not a function, but a property (or a "variable" if you will). It's 0 when the connection was correctly established. It contains other values (e.g. 1043) for connection problems (such as wrong password, inavailable database server).
So the if ($con->connect_errno) check asserts that your $con instance is usable.
When ->connect_errno == 0 then the if block will be skipped.
If ->connect_errno > 0 (any other value) the error message will be printed out. (You'd more commonly see die(), trigger_error() or new Exception() than just an echo there.)
Alternatively mysqli can be configured to throw an error/exception by itself. Which would make this whole condition/block redundant.

Related

What diffrence does a space between dbname and = does in PDO

This is the code when I try connecting to database. I have intentionally given wrong database name.
<?php
try
{
$pdo = new PDO('mysql:host=localhost;dbname=ehrp', 'root', '');
}
catch (PDOException $e)
{
echo $e->getMessage();
}
?>
This is the exception that I get, which is fine :
SQLSTATE[HY000] [1049] Unknown database 'ehrp'
But when I write this :
$pdo = new PDO('mysql:host=localhost;dbname =ehrp', 'root', '');
Notice a space between dbname and = I get nothing on screen.No error is shown.
Why is that?
The argument you're passing to the PDO constructor is in URI form, and a URI cannot contain arbitrary spaces, they all mean something. So what you've actually supplied the PDO constructor as far as it can tell is mysql:host=localhost; followed by an assigned property called "database " (with a space at the end). Since PDO does not know anything about a property called "database " there are no errors (it's a legal URI property value assignment), and as an unknown property, it just gets ignored. No errors, no warnings, you've done nothing wrong and PDO does what you ask it do to.
The PDO connection to your server on localhost succeeds, and you now have a PDO instance that is connected, and simply has not been tied to a specific database yet.
To verify this, prepare a SELECT DATABASE() statement with your PDO object, and then execute it: it should work just fine, and come back with a response indicating that you're not connected to a database yet.

php connect_errno vs checking if db == false

I am working on on a small personal project to understand PHP and MySql. I set up a simple class to get started to make a connection to a database and wanted to verify the connection was good and was attempting to use the connect_errno property but I am not getting the results I expected. This is just test code so it may be missing some of the error/security checking that would normally be included in such code.
Please note that the code is running on a LAMP Stack with Ubuntu 16.04 and PHP Version of: PHP Version 7.0.22-0ubuntu0.16.04.1
In the code below I intentionally set the DB_PASS constant to an invalid value to test two different methods of verifying the connection.
Using the connect_errno method does not seem to work.
class Database
{
public $conn;
public $connStatus;
public function __construct()
{
echo "Hi There, I am a database! <br><br>";
$this->conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if($this->conn->connect_errno)
{
echo "Bad Connection using connect_errno method <br/>";
}
else
{
echo "Good Connection using connect_errno method <br/>";
}
if ($this->conn == false)
{
echo "Bad Connection using db==false method <br/>";
}
else
{
echo "Good Connection using db==false method <br/>";
}
}
}
This code block indicates that the connection is good despite the incorrect DB_PASS. Return: Good Connection using connect_errno method.
if($this->conn->connect_errno)
{
echo "Bad Connection using connect_errno method <br/>";
}
else
{
echo "Good Connection using connect_errno method <br/>";
}
This code block indicates that the connection is bad, which is correct due to the incorrect DB_PASS. Return: Bad Connection using db==false method
if ($this->conn == false)
{
echo "Bad Connection using db==false method <br/>";
}
else
{
echo "Good Connection using db==false method <br/>";
}
I am fine with using the 'db==false' method of checking but I was curious about this. I have read several posts within Stack Exchange and tried some of those examples but they did not seem to work.
Example1: echoing-mysqli-connect-errno-not-working.
Example2: error on mysqli::connect_errno
Ok, after going back and reviewing the other posts I now understand the issue. The procedural method sets it up like this:
$this->conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
while the OOP method sets it up like this:
$this->conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
So I guess being relatively new to PHP and MySQL I did not really see the difference until taking a step back. Thanks for everyones help!
The difference is that mysqli_connect() will return either a mysqli object or a boolean false. But you can't use the -> operator on a variable that isn't an object.
$x = false;
echo $x->attrib; // fatal error, booleans can't have OO members or methods
This is one of the WTF moments in PHP. Because of its history, PHP language design is a Frankenstein's monster of object-oriented and non-object-oriented (made worse by many years of developing the language with no sensible design process).
So there are lots of functions in PHP which return either an object or a non-object. This makes it hard to write safe code, because you never know if you can use -> on the thing returned by a function, until you check what type it is.
The confusion is reduced if you use new mysqli(), because the OO operator new is guaranteed to return an object of that type, even if the connection fails because you gave an incorrect password or something.
$conn = new mysqli(...);
if ($conn->connect_errno) { // this is not a fatal error even if the connect failed
...
}

die() or try/catch when interacting with MySql database in PHP?

A lot of tutorials and books I have been over and read have used the die() method to catch an exception when interacting with a local MySQL database
For example:
mysql_connect($dbhost, $dbuser, $dbpass)or die(mysql_error());
Would a try/catch block be more beneficial over the die() method or is that just the standard way that exception handling works with db connections?
or die() is an extremely primitive way to "handle" errors and only for examples or debugging at best. In practice, it depends on how you handle your errors. You may want to return false from a function call or you may want to throw your own exception instead; e.g.:
if (!$con = mysql_connect(..)) {
throw new DatabaseConnectionError(mysql_error());
}
try..catch will do exactly nothing with mysql, since mysql never throws any exceptions. It only ever returns false on failure.
You will have to have your own error handling strategy. You'll probably want to log errors and display a user friendly error page instead of cryptic error messages. mysql is not concerned with that part. It only gives you a way to check whether an operation was successful or not (check if it returns false); what you do with this information is up to you. die kills the entire application and at least doesn't allow the problem to propagate further; but it certainly does not display any user friendly error pages.
Having said all this, mysql is old and deprecated. If you'd use something newer like PDO instead, it can properly throw exceptions itself.
The mysql_connect method does not throw exceptions and thus die() is used by many applications to terminate when there is no connection available.
You can use the solution mentioned here: how to use throw exception in mysql database connect
Included for completeness:
try
{
if ($db = mysqli_connect($hostname_db, $username_db, $password_db))
{
//do something
}
else
{
throw new Exception('Unable to connect');
}
}
catch(Exception $e)
{
echo $e->getMessage();
}
Alternatively use the new and more OOP styled database access: http://php.net/manual/en/book.pdo.php
The reason a lot of applications uses die is from the fact that they are so reliant on the database that continuing without a connection is utterly fruitless.
Edit As mentioned in the comments, the code example above is for illustrational purposes. Catching right after throwing is pointless.

Understanding PHP assignments

I am having some issues trying to grasp the idea behind certain lines of code that may be above me at this moment since I am fairly sure they have to do with OOP(something that I don't know much about as I am just starting on the concept behind OOP)This came to me as I was readig a PHP book.The code is as follows.
$mysqli = new mysqli('example','example','example');
if(!$mysqli){
die("Could not connect".mysql_error());
}
else {
echo("Connection established");
}
if($mysqli->query("CREATE DATABASE querycreation1")===TRUE){
echo"<p>Database Querycreation1 created</p>";
}
else {
echo "Error creating database".mysql_error();
}
I understand the first couple of lines(and appreciate input on best practices),but the part that I am having issues is after the next set of if-else statements.
The second if statement checks if the creation of a database is true,but can someone explain at what time exactly was the database created? do I need to create one and then check for it in the future? Any input would be greatly appreciated.
In a comparison in PHP first all expressions get evaluated. This means that in
if($mysqli->query("CREATE DATABASE querycreation1")===TRUE)
PHP will first run the query() function on the $mysql-object. That function returns a result. In the case of successfull creating a database it will return TRUE (http://nl1.php.net/mysqli_query). The result of calling this function (TRUE) is then compared to TRUE.
Perhaps more verbose for you to see this:
$databaseCreated = $mysqli->query("CREATE DATABASE querycreation1");
if($databaseCreated ===TRUE){
echo"<p>Database Querycreation1 created</p>";
}
else {
echo "Error creating database".mysql_error();
}
$mysqli->query() performs the query, in this case, a CREATE query. The function then returns TRUE if the query was executed successfully and FALSE if an error occurred. So the database is created exactly at the time the first argument to the === comparison is evaluated.
Generally, creating databases in php scripts won't happen often, usually only in "installation" scripts use to setup some php driven piece of software (such as a discussion board/forum). Other than that, you'll want to create the databases once either through a database management system such as phpMyAdmin or a script you delete afterwards. Then in your actual site scripts, you just assume the databases exist because you also usually don't just delete them.
You could write it differently by assigning the return value of the query to a variable and checking against that:
$success = $mysqli->query("CREATE DATABASE querycreation1");
if ($success===TRUE){
// ...
But that's purely a matter of preference.
Also, the first else is not strictly necessary because of the die statement. There is a number of ways you could simplify (or let's say modify) that part:
// The "just no else" version
if (!$mysqli)
die("Could not connect".mysql_error());
echo("Connection established");
// The one-liner version
if (!$mysqli) die("Could not connect".mysql_error());
echo("Connection established");
// The short-circuit version
$mysqli OR die("Could not connect".mysql_error());
echo("Connection established");
// same using the symbolic version of OR
$mysqli || die("Could not connect".mysql_error());
echo("Connection established");
// you can also include that in the first call
$mysqli = new mysqli('example','example','example') OR die("Could not connect".mysql_error());
echo("Connection established");
The last three examples work based on the fact that php handles logical operators in a short-circuit way, that is, if the first part is TRUE, then the entire OR expression will be TRUE no matter what the second argument is, so php doesn't even bother evaluating it. If the first part is FALSE, however, the expression's value depends on the second argument, so it is evaluated.
Point one:
You are creating an instance of a class mysqli which contains methods to connect, query, manage database. You need to pass some parameters which are used by the class'es constructor to connect to the database.
This instance is called an object and now this object has the connection and can use the methods from the class to query, manage that database.
For better understanding: http://www.php.net/manual/en/language.oop5.php

How do I check the DB connection

I have host, database name, username and the password given as form inputs like:
$form['dbname']->getData()
I need to check if these data is correct for the mysql connection. So I chose to use mysql_connect() to check this:
$conn = mysql_connect($form['host']->getData(), $form['username']->getData(), $form['password']->getData(), $form['dbname']->getData());
if($conn) // ...
else // ...
But it displays some mysql_connect() warning with no other specific message...
What's wrong? Does the symfony 2 has any mechanism to check the connection?
Symfony uses repositories and entities to manage the database. The programmer doesn't manipulate the connection itself (Doctrine).
You could try to check a connection using PDO. Try to instance a PDO Object, and catch exceptions (PDOException for connection errors). However, you're "breaking" the framework's philosophy, trying to initiate an "extern" DB connection. If you need to work with several connections in Symfony, I suggest this reference :
http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html
use the following format to receive the connection error if there is any.
$con = mysql_query() or die(mysql_error());

Categories