PHP Exits When I Try to Connect to a Database Using MySQLi - php

I have been developing a website recently, and I came across an error. When I tried to do print_r(error_get_last()); It output some text about mysql not being supported anymore, and to use MySQLi. I was all for it. When I edited my database class to support MySQLi, it exits every time it tries to connect. I have put echo 'hi<br />'; before and after the mysqli function, and a or trigger_error("Error: " . print_r(error_get_last())); at the end of it, but all it outputs is hi, and nothing else. My database is created in phpMyAdmin, and has all the correct permissions, but it just cannot connect. This is my connection code:
echo 'hi<br />';
$this->db = mysqli($host, $dbuser, $dbpass, $dbname) or trigger_error("Error: " . print_r(error_get_last()));
echo 'hi<br />';
$this->connect_start = microtime(true);
if ($this->db->connect_errno > 0) die ($this->debug(true));
It is in the constructor of a class that looks like this:
function db($host, $dbname, $dbpass, $dbuser)
and it is called like this:
$db = new db($host, $dbname, $dbpass, $dbuser);

Change this:
$this->db = mysqli()
to
$this->db = new mysqli()
mysqli is not a function, it's a class. If you had error reporting on you'd get a message like this:
PHP Fatal error: Call to undefined function mysqli()
That's the reason why the rest of your code isn't executed, the execution stops right there.
Also note that new mysqli() will never return false, so your or ... part becomes useless. If you want to check for connection errors you have to check $this->db->connect_error after the connection attempt.

Related

How to connect with SLIM REST api with MS SQL server?

I am trying to get results from an API call using Slim connecting with MSSQLSERVER2012
the example used to work with MYSQL getconnection function (see below) but when I am trying to
connect with MsSQL server 2012 I am getting an error like "api call error "invalid data source name"
http://localhost/msapi/api.php/clients
1'api call error "invalid data source name"
require '/Slim/Slim.php';
$app = new Slim();
$app->get('/clients', 'getClients');
$app->run();
function getClients() {
$sql = "select * FROM clients";
try {
$db = getConnection();
$stmt = $db->query($sql);
$clients = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo '{"client": ' . json_encode($clients) . '}';
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
function getConnection_MYSQL() {
$dbhost="SERVER";
$dbuser="USER";
$dbpass="PASSWORD";
$dbname="DB";
$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh;
}
function getConnection() {
$dbhost="SERVER";
$dbuser="USER";
$dbpass="PASSWORD";
$dbname="DB";
$dbh = new PDO ("ADODB.Connection");
$connStr = "PROVIDER=SQLOLEDB;SERVER=".$dbhost.";UID=".$dbuser.";PWD=".$dbpass.";DATABASE=".$dbname;
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->open($connStr); //Open the connection to the database
return $dbh;
}
the function getConnection_MYSQL() is an example that works.
But the getConnection() tryis to connect with MS SQL server ?
Do you see why I am getting an "invalid data source name" with the function getConnection()?
Since you didn't post an alternative DSN-string, I'm assuming you are using the one from your example and just replace host, username and password. This won't work.
When you are running your Slim-application on a windows host you can (and should) use Microsoft's SQL Server Driver for PHP (sqlsrv).
There are 2 versions sqlsrv.dll and pdo_sqlsrv.dll. When you want to reuse most of your code you should use the latter. This way you probably only have to modify your DSN (see php docs):
new PDO("sqlsrv:Server=localhost;Database=testdb", "UserName", "Password");
If you are using the first you have to update the way you connect to the db and create the query. You can read the Beginner's Guide to see a few examples that should make it easy.
If you are running not running your application on a Windows-machine you will probably have to set up ODBC and FreeTDS and then use PDO with an ODBC-DSN. From my experience this will be quite a lot of work, but there are a few good tutorials out there. Just google for "freetds sql server".

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.

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.

PHP Database Class and new() Function

I have, what I think/hope, is a very simple PHP question. I have made a class to create database connections and issue common queries. I am trying to open two different database connections by creating two objects from the same database class. My code is as follows:
//connect to DB
$dbh = new DB('localhost', 'db1', 'user', 'pass');
//check connection
if(!$dbh->getStatus()) {
echo($dbh->getErrorMsg());
die;
}//if
//connect to DB 2
$dbh2 = new DB('localhost', 'db2', 'user', 'pass');
//check connection
if(!$dbh2->getStatus()) {
echo($dbh2->getErrorMsg());
die;
}//if
However, when I call a method for $dbh to query the database, it attempts to query with the credentials for $dbh2.
My DB constructor is below:
class DB {
function __construct($host, $db, $user, $pass) {
$dbh = mysql_connect($host, $user, $pass);
mysql_select_db($db, $dbh);
if(!$dbh) {
$this->status = false;
$this->error_msg = 'Error connecting to database: '.mysql_error();
return(false);
}//if
$this->dbh = $dbh;
$this->resetStatusAndErrors();
return($dbh);
}//_construct
Simple solution: Use PDO instead. It does exactly what you want, probably has better syntax and implementation and abstracts the interface for DB access.
You're not showing the full class, but the most probable reason is that you are not passing the current connection to the mysql_query() command.
Save $dbh as a property of your class, and add the connection parameter to each mysql_ function that accepts it:
mysql_query("SELECT * from.......", $this->dbh);
That said, if you are building this from scratch at the moment, take a look whether you don't want to use PDO instead. It is better, safer and more flexible than the old style mySQL library.
If you are using the mysql extension (using either mysqli or PDO_MySQL would give both superior performance, more features, etc., so check that for new code), you'll have to store the database handle, and use that on every mysql_* call:
class db {
....
function query($query){
return mysql_query($query, $this->dbh);//notice the second parameter.
}
}

Categories