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

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.

Related

Why can't I catch the error with PDOException?

Get info passed by POST method, and trim all space in the string, then start a new pdo instance, connect mysql, and insert info passed by POST into table.
$title = trim($_POST["title"]);
$content = trim($_POST["content"]);
$dsn = "mysql:host=localhost;dbname=blog";
$con = new PDO($dsn,"root","xxxx");
$title = $con->quote($title);
$content = $con->quote($content);
try
{
$sql = "insert into tmp (`title`,`content`) values('$title','$content')";
$stmt = $con->prepare($sql);
$stmt->execute();
}
catch(PDOException $e)
{
echo $e->getMessage();
}
The above is my PHP code to make the job done,the most import command is
insert into tmp (`title`,`content`) values('$title','$content')";
No error info is shown by running the above PHP code, and no error exists in /var/log/mysql/error.log, but info has not been inserted into the database.
I changed the
insert into tmp (`title`,`content`) values('$title','$content')";
into
insert into tmp (`title`,`content`) values($title,$content)";
The info passed by POST can be inserted into mysql now, the issue that confuses me is that:
echo $e->getMessage(); take no effect at all.
no error info in /var/log/mysql/error.log
How can I catch these errors?
The exception you are trying to catch will never be thrown, because you need to tell PDO how you want it to handle errors.
$con = new PDO($dsn,"root","xxxx");
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Otherwise, the default PDO::ERRMODE_SILENT will be used:
This is the default mode. PDO will simply set the error code for you to inspect using the PDO::errorCode() and PDO::errorInfo() methods on both the statement and database objects; if the error resulted from a call on a statement object, you would invoke the PDOStatement::errorCode() or PDOStatement::errorInfo() method on that object. If the error resulted from a call on the database object, you would invoke those methods on the database object instead.
Tangentially, you should be using prepared statements. You are using a prepare() call, but you are not parametrizing the query and binding the variables as you should. Using quote() is not secure enough.
2020 Update:
Interestingly, starting with PHP 8, the default behaviour for PDO will change and will throw exceptions by default. The change was voted on this RFC, which mentions:
The current default error mode for PDO is silent. This means that when an SQL error occurs, no errors or warnings may be emitted and no exceptions thrown unless the developer implements their own explicit error handling.
This causes issues for new developers because the only errors they often see from PDO code are knock-on errors such as “call to fetch() on non-object” - there's no indication that the SQL query (or other action) failed or why.
When PHP 8 is released on November 2020, the default error mode will be PDO::ERRMODE_EXCEPTION.

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

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.

Using default values for mysqli constructor fails

I am trying to connect to a database using the default values for the mysqli constructor, which is documented to be:
host = ini_get("mysqli.default_host")
username = ini_get("mysqli.default_user")
passwd = ini_get("mysqli.default_pw")
The reason I want to use the defaults is so I can have the credentials in the config file instead of scattered through my code. However, when I pass no values, the connection succeeds but then subsequent queries fail with no error.
$db = new mysqli();
if ($db->connect_errno) die("Connect failed: " . $db->connect_error);
if ($rs = $db->query("select user();") or die("Query failed: " . $db->error)) {
$row = $rs->fetch_row();
echo $row[0];
$rs->close();
}
This outputs:
Query failed:
That means the connection succeeded, but any query fails with an error. (Other actions, such as select_db, fail the same way.)
Interestingly, I can fix it by changing the first line to:
$db = new mysqli(ini_get("mysqli.default_host"),
ini_get("mysqli.default_user"),
ini_get("mysqli.default_pw"));
... but I'd prefer to not have to type out the default values everywhere I need a database connection. What am I doing wrong? Is there a way to use the mysqli constructor with no arguments?
While writing this question, I happened to scroll down the documentation page and noted the following:
Note: Calling the constructor with no parameters is the same as calling mysqli_init().
Looking up the mysqli_init documentation, it says:
Note: Any subsequent calls to any mysqli function (except mysqli_options()) will fail until mysqli_real_connect() was called.
Therefore, the fix is to change the first line from:
$db = new mysqli();
To:
$db = new mysqli();
$db->real_connect();
I would have expected in that scenario that mysqli_error would have returned something like "not connected" instead of an empty string. That's a bit counter-intuitive, but at least it's somewhat documented.

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());

Access denied error when using mysql_real_escape_string()

i am trying escape some data before it goes into my database, but i keep getting this error:
Warning: mysql_real_escape_string(): Access denied for user
Now this would usually suggest that i have not connected to the database (it also states (using password: NO)).
I was a little confused by this because when connecting to a database i have a 'die' clause so if it fails to connect i get told about it. So i tested this theory by running a simple query in the same function that im trying to escape the data and it works just fine.
So why on earth won't the escape method work or get a connection to the database. I did notice that the user the error states is not the user i use to access the database its something like 'www-data#localhost'. Could it be trying to log in with a different user, if so why and how? Because i another area of my website the escape function works just fine and i didn't do anything special to make it work, just added the code into my web page.
thanks for the help.
Are there any other ways of sanitizing my code?
Okay, so here we go, when the user submits the form, i use AJAX to collect the data and put it into an obj to post(JSON encoding) it to the first PHP script which is here:
http://codepad.org/kGPljN4I
This script checks all the data is there and then calls a function to add it to the database
this Mysql class is called to escape the data and then add a new record to the database, when and instance of the class is made it makes a connection to the database:
http://codepad.org/wwGNrTJm
The third file is for constants, it holds the information for the database like pass, user and so on:
http://codepad.org/dl0QQbi9
any better?
thanks again for the help.
The problem is that you have established your connection using MySQLi, but are then calling mysql_real_escape_string(). You intend to be calling mysqli_real_escape_string() either in procedural context, or object oriented contex.
class Mysql
{
private $conn;
function __construct()
{
$this->conn = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or
die('No Connection to database!');
}
function add_non_member($data)
{
$email = $data->email;
// Procedural call
$san_email = mysqli_real_escape_string($this->conn, $email);
// Or OO call (recommended)
$san_email = $this->conn->real_escape_string($email);
// etc...
}
// etc...;
}
You're mixing ext/mysqli
$this->conn = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME
with ext/mysql functions:
$san_email = mysql_real_escape_string($email);
that last line should be
$san_email = $this->conn->real_escape_string($email);
I also got this access denied warning and I was able to find the solution. The problem is that I have not setup mysql db connection before calling mysql_real_escape_string function.
Solution:
Call mysql_connect($host, $user, $password) first (Or you can call your database connect function)
Then use mysql_real_escape_string($var)

Categories