Call to a member function prepare() - php

<?php
date_default_timezone_set('Europe/Istanbul');
try{
$db_host = 'localhost';
$db_name = 'db_name';
$db_kadi = 'root';
$db_sifre = '';
$pdo = new PDO("mysql:host=".$db_host."; dbname=".$db_name, $db_kadi, $db_sifre, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
}catch(PDOException $hata){
if($hata->getCode() == "1044"){
die("<h4>Sistem Bağlantı Hatası</h4><p>Sistem bağlantısı yok !</p>");
}else if($hata->getCode() == "1049"){
die("<h4>Database Sistem Hatası</h4><p>Database bağlantısı yok !</p>");
}
}
?>
<?php
public function fetch_data($data){
global $pdo;
$query = $pdo->prepare($data);
$query->closeCursor();
$query->execute();
return $query->fetch(PDO::FETCH_ASSOC);
$query->null;
}
?>
Fatal error: Call to a member function prepare() on null in
I do not understand how I got to this error. I've tried almost everything I encounter the same problem. If you have friends that will help me with this please write. Thank you
PDO module active, installed mysqli a stronge error.

The reason this is happening is because $data is null. When preparing the statement here ~>
$query = $pdo->prepare($data);
The data from your constructor is null. So go through and make sure wherever fetch_data is being called that the value you're passing isn't null.
EDIT:
It's because PDO is null. There must be something with how you're setting it up, as the global reference should give you access to the PDO.
Use this as a reference: http://www.w3schools.com/php/php_mysql_prepared_statements.asp

Well, first off, the error is that $pdo (even though you are using the global scope) is null. In your try, you are setting the $pdo variable, but if it fails, $pdo is never set. If $hata->getCode() doesn't return "1044" or "1049", the thread never dies.
Double check your connection string. Can you make a connection to it from your PC? I'm a little bit suspect of the '' password.

Fatal error: Call to a member function prepare() on null
Here's the explanation of that error:
$pdo->prepare($data);
You can call a method from $pdo only if $pdo is an object of a class with that method. In this case, $pdo is null, which is no type of object. A null has no methods, so it's a fatal error to try to call any method on a null.
The cause of this problem is that when you get a PDO connection, you're checking only error codes 1044 and 1049. If any other error code is the cause of the exception, then your code does not call die(), it proceeds to the second block of code.
But then $pdo still has not been set to a valid database connection!
It's like if you call someone on the phone, but your mobile phone has no signal. But you start talking to your friend anyway?!?
If the code in the catch() block is executing, it means something went wrong, and new PDO() was not successful. You must call die() in the catch() block one way or the other.
To fix this, I would recommend the following. In your catch() block, make sure you call die() by the end of the block, no matter what the error code is (example below).
I also recommend that you save the exception message into your error log. This is to help you troubleshoot. Don't display the error to users in the HTML output, because they don't know what that error means anyway. But you can look for it in your PHP error log (which is typically your Apache error log).
<?php
date_default_timezone_set('Europe/Istanbul');
try{
$db_host = 'localhost';
$db_name = 'db_name';
$db_kadi = 'root';
$db_sifre = '';
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_kadi, $db_sifre,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
} catch (PDOException $hata) {
error_log($hata->getMessage()); // log the error!
if ($hata->getCode() == "1044") {
die("<h4>Sistem Bağlantı Hatası</h4><p>Sistem bağlantısı yok !</p>");
} else if ($hata->getCode() == "1049") {
die("<h4>Database Sistem Hatası</h4><p>Database bağlantısı yok !</p>");
}
// make sure to call die() if any other error code occurs!
die("<h4>Database Sistem Hatası</h4><p>Veritabanı yöneticisine başvurun !</p>"
}
?>
Once you do this, you can guarantee either $pdo is valid, or else the code has called die() and will not try to use an invalid $pdo.

Related

Get a database connection error in a class

I didn't realize there was an OO way to use mysqli, so I built a class called DB. During __construct it takes the hostname, username, password, and database name. Given the following code:
$myDB = new DB("localhost", "user", "password", "database");
$myDBConnect = $myDB->connect();
if(!$myDBConnect) {
echo "<strong>The following error has occurred: " . $myDB->getError();
}
The variable obviously contains FALSE because this if statement is currently returning TRUE. Here is the method from the DB class:
public function connect() {
// Create connection
$this->dbConnx = mysqli_connect($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbName);
if(mysqli_connect_errno($this->dbConnx)) {
$this->dbError = mysqli_error($this->dbConnx);
return false;
}
}
I'm not getting any error detail. I tried adding or die(mysqli_error()); in the connect method, but it always just outputs the text from the file that $myDB is instantiated in. I also tried variations on the error reporting code, including having no argument in mysqli_connect_errno() and using $this->dbError = mysqli_connect_error() with and without the connection argument.
Is this needlessly complicating the OO way to use mysqli? or am I missing something simple that will allow me to move on using the code I've already got?
Thanks in advance for your time.
if is not variable
if(!$myDBConnect) {
^--remove variable sign here
EDIT:
your connection should be
$myDB = new mysqli("localhost", "user", "password", "database");
Maybe you forgot the return true statement in the "connect" method?
Also you should use PDO.
Your connect() function is returning false on failure and nothing on success, so it will always fail the if. Try adding return true; at the end of that function.

PHP function to open database using PDO

I realize this is probably super simple but i just started taking peoples advice and im converting a small program from mysql to PDO as an attempt to learn and switch to PDO.
The script is a script that shows you how to build a shopping cart, so keep in mind its focused on a learning audience like myself. Anyway i converted the old script here:
function db_connect()
{
$connection = mysql_pconnect('localhost', 'database_1', 'password');
if(!$connection)
{
return false;
}
if(!mysql_select_db('database_1'))
{
return false;
}
return $connection;
}
to this which does connect fine:
function db_connect() {
//Hostname
$hostname = 'xxx.com';
//username
$username = 'xxx';
//password
$password = 'xxx';
try {
$connection = new PDO("mysql:host=$hostname;dbname=database_1", $username, $password);
}
catch(PDOException $e){
echo $e->getMessage();
}
}
Now in other parts of the script before accessing the database it does this:
$connection = db_connect();
Now i have 2 questions. First is to help me understand better what is going on.
I understand in the original mysql function we connect to the database, if the connection is unsuccessful or the database doesnt exist it returns false. If it does connect to the database then it returns true.
With that i mind i dont understand this:
$connection = db_connect();
Isnt that just assigning true or false to the $connection variable, if so then whats going on in this part of the code.
$price = 0.00;
$connection = db_connect();
if (is_array($cart))
{
foreach($cart as $id => $qty)
{
$query = "SELECT price
FROM products
WHERE products.id = '$id' ";
$result = mysql_query($query);
if($result)
{
$item_price = mysql_result($result, 0, 'price');
$price += $item_price * $qty;
}
}
}
Instead couldn't i just create an include file with the PDO connection and no function and include that at the top of each page i run scripts on. I just don't understand where the $connection = db_connect comes in.
So the 2nd question if my above suggestion is not the answer is how do i return a boolean value from the connection function to return true or false (If i even need to)
There is one essential difference between old mysql and PDO: both these libraries require a resource variable to connect with. If you take a look at mysql_query() function definition, you will notice the second parameter, represents such a resource.
$connection variable returned by your old function by no means contain boolean value but such a resource variable. Which can be used in every mysql_query call.
But while for mysql ext this resource parameter being optional, and used automatically when not set, with PDO you have to address this resource variable explicitly. Means you cannot just call any PDO function anywhere in the code, but only as a method of existing PDO object. Means you have to make this variable available wherever you need PDO.
Thus, you need not a boolean but PDO object.
Here is the right code for the function:
function db_connect()
{
$dsn = "mysql:host=localhost;dbname=test;charset=utf8";
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
return new PDO($dsn,'root','', $opt);
}
now you can use it this way
$pdo = db_connect();
but note again - unlike with mysql_query(), you have to always use this $pdo variable for your queries.
Further reading is PDO tag wiki
As you guessed from the context, db_connect() is supposed to return the connection object. Your converted version doesn't return anything, which is a problem.
With the mysql module, you can run queries without using the connection object - this is not the case with PDO. You'll need to use the connection object to run any queries -
$result = $connection->query('SELECT * FROM foo');
First off, let me congratulate you for making the effort to learn PDO over mysql_*. You're ahead of the curve!
Now, a few things to understand:
PDO is OO, meaning the connection to the database is represented by a PDO Object.
Your db_connect() function should return the object that gets created.
Passing in the parameters required by PDO will give you more flexibility!
So what we have is:
function db_connect($dsn, $username, $password)
{
$conn = new PDO($dsn, $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //This makes sure that PDO will throw PDOException objects on errors, which makes it much easier enter code hereto debug.
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //This disables emulated prepared statements by PHP, and switches to *true* prepared statements in MySQL.
return $conn; //Returns the connection object so that it may be used from the outside.
}
Now, you may have noticed we aren't checking for PDOExceptions inside of the function! That's because you can't handle the error from inside of the function correctly (becuase you don't know what you would want to do? Would you terminate the page? Redirect to an error message?). So you can only know it when you call the function.
So usage:
try {
$connection = db_connect("mysql:host=$hostname;dbname=database", "user", "pass");
}
catch (PDOException $e) {
echo "Database error! " . $e->getMessage();
}
Further Reading!
The PDO Manual entry - is super easy and super useful. I recommend you read all of it.

Using $dsn string variable as parameter in database PDO

Goal: to simply fetch array from a MySQL database.
Issue: I am using the $dsn "string variable" as a parameter in the PDO Statement but there appears to be an uncaught exception and it has something to do with invoking the driver or the (PDO->__construct) -- I am not sure. Do you have any ideas on how to fix the $dsn string variable or other areas of this code that would cause it to fail? Thanks in advance.
// Define Database Parameters
$dbhost = "localhost";
$dbname = "x";
$dbuser = "y";
$dbpass = "z";
// Invoke Driver (as a variable string)
$dsn = "mysql:host=$dbhost;dbname=$dbname";
// Connect to newly created db object
$dbh = new PDO($dsn, $dbuser, $dbpass);
// Set the PDO error mode to enable exceptions
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
// Execute query to the database
$sql = "SELECT * FROM a_aif_remaining";
$sth = $dbh->prepare($sql);
$sth->execute();
// Present results from query
print("PDO::FETCH_ASSOC: ");
print("Return next row as an array indexed by column name");
$result = $sth->fetch(PDO::FETCH_ASSOC);
print_r($result);
print("");
return $results;
// Close db connection
$dbh = NULL;
?>
Put your code in a try catch block. And see the error message reported. An example of this below:
try
{
if ( !class_exists( 'PDO' ) )
throw new Exception( 'PHP without PDO' );
if ( array_search( PDO::getAvailableDrivers(), 'mysql' ) === false )
throw new Exception( 'PHP without PDO mysql driver' );
$dbh = new PDO( ... );
...
}
catch ( PDOException $e )
{
print $e->getMessage();
}
catch ( Exception $e )
{
print $e->getMessage();
}
There can't be any problem where you're looking for it. Substituting a string with a variable is okay and cannot cause any issues. So, it is somewhere else. Luckily PHP reported of it, but strangely, you paid not much attention to that report.
there appears to be an uncaught exception
Uncaught exceptions often contains the error message.
Most of PHP error messages are quite informative. One have to read them through to get the explanation of the problem. After all, it's the only your source of information. No one can tell you what is wrong on your server but server itself. If you have difficulties with interpreting the error message - it is essential to post it along with your question, to let people interpret it for you. So, every error message you get, should be posted in your question, whole and intact. Simple but very important rule.

PHP try/catch and fatal error

I'm using the following script to use a database using PHP:
try{
$db = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$db, $user, $pass, $options);
}
catch(Exception $e){
$GLOBALS['errors'][] = $e;
}
Now, I want to use this database handle to do a request using this code:
try{
$query = $db->prepare("INSERT INTO users (...) VALUES (...);");
$query->execute(array(
'...' => $...,
'...' => $...
));
}
catch(Exception $e){
$GLOBALS['errors'][] = $e;
}
Here is the problem:
When the connection to the DB is OK, everything works,
When the connection fails but I don't use the DB, I have the $GLOBALS['errors'][] array and the script is still running afterwards,
When the connection to the DB has failed, I get the following fatal error:
Notice: Undefined variable: db in C:\xampp\htdocs[...]\test.php on line 32
Fatal error: Call to a member function prepare() on a non-object in C:\xampp\htdocs[...]\test.php on line 32
Note: Line 32 is the $query = $db->prepare(...) instruction.
That is to say, the script crashes, and the try/catch seems to be useless. Do you know why this second try/catch don't works and how to solve it?
Thanks for the help!
EDIT: There are some really good replies. I've validated one which is not exactly what I wanted to do, but which is probably the best approach.
try/catch blocks only work for thrown exceptions (throw Exception or a subclass of Exception must be called). You cannot catch fatal errors using try/catch.
If your DB connection cannot be established, I would consider it fatal since you probably need your DB to do anything meaningful on the page.
PDO will throw an exception if the connection cannot be established. Your specific problem is that $db is not defined when you try to call a method with it so you get a null pointer (sort of) which is fatal. Rather than jump through if ($db == null) hoops as others are suggesting, you should just fix your code to make sure that $db is either always defined when you need it or have a less fragile way of making sure a DB connection is available in the code that uses it.
If you really want to "catch" fatal errors, use set_error_handler, but this still stops script execution on fatal errors.
In PHP7, we now can using try catch fatal error with simple work
try {
do some thing evil
} catch (Error $e) {
echo 'Now you can catch me!';
}
But usualy, we should avoid using catch Error, because it involve to miss code which is belong to programmer's reponsibility :-)
I will not report what has already been written about testing if $db is empty. Just add that a "clean" solution is to artificially create an exception if the connection to the database failed:
if ($db == NULL) throw new Exception('Connection failed.');
Insert the previous line in the try - catch as follow:
try{
// This line create an exception if $db is empty
if ($db == NULL) throw new Exception('Connection failed.');
$query = $db->prepare("INSERT INTO users (...) VALUES (...);");
$query->execute(array(
'...' => $...,
'...' => $...
));
}
catch(Exception $e){
$GLOBALS['errors'][] = $e;
}
Hope this will help others!
If database connection fails, $db from your first try .. catch block will be null. That's why later you cannot use a member of non-object, in your case $db->prepare(...). Before using this add
if ($db) {
// other try catch statement
}
This will ensure that you have db instance to work with it.
Try adding the following if statement :
if ($db) {
$query = $db->prepare("INSERT INTO users (...) VALUES (...);");
$query->execute(....);
}
else die('Connection lost');
try{
if(!is_null($db))
{
$query = $db->prepare("INSERT INTO users (...) VALUES (...);");
$query->execute(array(
'...' => $...,
'...' => $...
));
}
}
catch(Exception $e){
$GLOBALS['errors'][] = $e;
}

PDO Error In SignUp Class

I'm working on my own SignUp class but it seems I have a problem with the PDO calls
The browser returns this to me:
Fatal error: Call to a member function query() on a non-object
I have my database configuration in a file included then on the main page. It's as follows:
<?
$dsn = 'mysql:dbname=magazin-online;host=localhost;';
$username = 'root';
$password = '';
try{
$pdo = new PDO($dsn, $username, $password);
}catch(PDOException $e){
echo 'Connection failed!: '.$e->getMessage();
}
An the line in the SignUp class causing the error is this:
$pdo->query("insert into ... () ... values ());
Now, I don't make any db connection in my SignUp class because I already included the file resposible for it.
How can I get rid of that error?
try using exec instead of query:
$pdo->exec("insert into ... () ... values ());
You are catching the exception generated by the new PDO, and then continue execution.
By doing it this way, you have to check that the class exists, so change:
if( $pdo)
$pdo->query("insert into ... () ... values ());
But .. a better way is not to continue execution after a critical error like this.
So better change the connection like this:
$dsn = 'mysql:dbname=magazin-online;host=localhost;';
$username = 'root';
$password = '';
try{
$pdo = new PDO($dsn, $username, $password);
}catch(PDOException $e){
echo 'Connection failed!: '.$e->getMessage();
die;
}
If I understand correctly, $pdo is a global variable. If you are calling $pdo->query inside a function, you either have to pass the $pdo connection as a parameter or declare it as global
global $pdo;
in the beginning of the member function.

Categories