Mysql db class - trouble connecting - php

So I'm trying to make a mysql database class, and I want to keep my db selection in a seperate method from the constructor. For some reason it the setDb() function doesn't want to work.
class mysql
{
public function __construct($server,$user,$pass)
{
if(!$this->mysql_connection = mysql_connect($server,$user,$pass))
print 'Could not connect to MySQL';
}
public function setDb($dbname)
{
$this->database = $dbname;
if(!mysql_select_db($this->database,$this->mysql_connection))
$this->database = '';
print 'Could not connect to the MySQL database';
return false;
return true;
}
private $database;
private $mysql_connection;
}

You could throw an exception in case of a MySQL error, e.g.
class DbMySQL
{
protected $database;
protected $mysql_connection;
public function __construct($server,$user,$pass)
{
$this->mysql_connection = mysql_connect($server,$user,$pass);
if( !$this->mysql_connection ) {
throw new ErrorException(mysql_error(), mysql_errno());
}
}
public function setDb($dbname)
{
if ( !mysql_select_db($dbname, $this->mysql_connection) ) {
throw new ErrorException(mysql_error($this->mysql_connection), mysql_errno($this->mysql_connection));
}
else {
$this->database = $dbname;
}
return $this;
}
}
$m = new DbMySQL('localhost', '...', '...');
$m->setDB('...');
Maybe ErrorException() is not the best choice, but I hope you get the idea ;-)

I don't see any glaring problems. Are you calling your class like below?
$db = new mysql($server, $user, $password);
$db->setDb('YOUR_DATABASE_NAME');

You need to add curly braces after your mysql_select_db line, and before the return true line. Only the first statement under the condition is executed when the condition is met. So the function always returns false.

Related

PHP Creating New Instance of a Class Returns NULL

I'm currently creating a really simplistic online ordering website as part of a school project. I am running into an issue where my controller tries to create an instance of a class that interfaces with my order parameters, but creating the new instance simply returns NULL. When the page where the operation is called loads, I receive this error:
Fatal error: Call to a member function getParameters() on null in /home/data/www/z1785732/public_html/467/PlaceOrderController.php on line 31
Here are the files I'm working with:
This is the controller. The specific class that is returning NULL is ParameterInterface.
<?php
include 'ItemDB.php';
include 'OrderDB.php';
include 'ccInterface.php';
include 'ParameterInterface.php';
class PlaceOrderController {
var $itemDB;
var $parameter;
var $orderDB;
var $ccInterface;
function __construct() {
$this->itemDB = new ItemDatabase();
$this->ccInterface = new ccInterface();
$this->parameter = new ParameterInterface();
}
public function displayCatalog() {
return $this->itemDB->displayCatalog();
}
public function searchItem($itemNum) {
return $this->itemDB->searchItem($itemNum);
}
public function getParameters() {
return $this->parameter->getParameters();
}
public function addOrder() {
$this->orderDB->addOrder($array1, $array2);
}
public function ccAuthorize($ccInfo) {
return $this->ccInterface->ccAuthorize($ccInfo);
}
}
?>
Here is ParameterInterface.php, where the function is defined.
<?php
class ParameterInterface {
function connect() {
$servername = '';
$dbname='';
$username = '';
$password = '';
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
echo "Connection failed: ". $e->getMessage();
}
return $conn;
}
public function getParameters() {
$conn = $this->connect();
$query = "SELECT * FROM Admin;";
$result = $conn->query($query);
$row = $result->fetch(PDO::FETCH_ASSOC);
return $row;
}
}
?>
I'm hoping it's just something simple that my eyes aren't catching. Any help would be greatly appreciated.
Thanks in advance!
Implement the Serializable interface to be able to serialize your controller in session:
class PlaceOrderController implements Serializable
{
// ...
public function serialize()
{
return serialize(array(
$this->itemDB,
$this->parameter,
$this->orderDB,
$this->ccInterface
));
}
public function unserialize($serialized)
{
list(
$this->itemDB,
$this->parameter,
$this->orderDB,
$this->ccInterface
) = unserialize($serialized);
}
// ...
}
Remember to start a new session after you do this. (clear your cookie) You may using an old PlaceOrderController object, with no propriety, in your current session.
Also, you may want rethink about this whole script. This isn't Java. Why you want store PlaceOrderController in session?
Your code seems clean enough to me... however; depending on the version of PHP you are using, the var Keyword might not be ideal here since it means Public. If your Member Variables are Public; getters and setters are really more or less not that necessary as such.
Back to the Issue. I would suggest taking a look at the name of the File: ParameterInterface.php because it may not have been properly included which might be a Typo or so in the Filename. Be mindful of cases (Upper & Lower - depending on your Operating System). Try first checking if the file exist to see what you get; like so:
<?php
if(file_exist("ParameterInterface.php")){
include "ParameterInterface.php";
die ("Sure, ParameterInterface.php exists and it has been included...");
}else{
die("Ah haaaa! Gotcha!!! So, 'ParameterInterface.php' does not exist in the current Directory....");
}
//AFTER THIS QUIRK DEBUGGING... YOU MIGHT JUST KNOW MORE...
Would You mind to try redefining your Class, instead? Like so:
<?php
class ParameterInterface {
/**
* #var PDO $CON_LINK
*/
protected static $CON_LINK;
//WOULDN'T HURT TO ADD AN EMPTY CONSTRUCTOR... NOW, WOULD IT?
function __construct(){
$servername = '';
$dbname = '';
$username = '';
$password = '';
if(!self::$CON_LINK) {
try {
self::$CON_LINK = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
self::$CON_LINK->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
}
}
function connect() {
return self::$CON_LINK;
}
public function getParameters() {
$conn = $this->connect();
$query = "SELECT * FROM Admin;";
$result = $conn->query($query);
$row = $result->fetch(PDO::FETCH_ASSOC);
return $row;
}
}
?>
Hope this helps a little...

How to create global connection?

I want create a global connection, so in the entire script I can access to a single object. Actually I made this class:
<?php
class Database {
private static $db;
private $connection;
private function __construct($conn) {
$this->connection = $conn;
$this->init();
}
private function init(){
// here the connection is going to execute
$host = $this->_connection['host'];
//etc...
}
function __destruct() {
$this->connection->close();
}
public static function getConnection($conn) {
if (self::$db == null) {
self::$db = new Database($conn);
}
return self::$db->connection;
}
}
?>
I pass the details of connection like this: $db = Database::getConnection($connection); Now $connection contains an array with the credentials access. Here no problem all working good. The main problem is that $db = Database::getConnection($connection); is called only when the index create the instance of the connection. My goal is call the $connection object in any models or controller, example:
class Model
{
function __construct()
{
$this->db = Database::getConnection();
}
}
how you can see I can't pass the connection parameter 'cause I want just use the connection previously established by the index.php call. How I can access to this connection without pass parameter?
You need to both make the $conn parameter optional and make sure it is passed on the first call:
public static function getConnection($conn=null) {
if (self::$db == null) {
if ($conn === null) {
throw new Exception('Can not initialize the database');
}
self::$db = new Database($conn);
}
return self::$db->connection;
}
Then you need to call the getConnection somewhere during the application start and pass the configuration to it.
After that you can use it without parameters.
If, by mistake, you don't configure the database, you'll have a clear error.
You could try this
public static function getConnection($conn = null) {
if (self::$db != null) {
return self::$db->connection;
}
//maybe add some validation here to ensure that the $conn value has been set
self::$db = new Database($conn);
return self::$db->connection;
}
or this works as well although it will throw an error if you don't set the $conn on the first call.
public static function getConnection($conn = null) {
if (self::$db == null && $conn) {
self::$db = new Database($conn);
}
return self::$db->connection;
}
It changes your logic a bit but should now work as you expect it to.
If the $conn is not supplied then it wont throw an error.

Mysqli inside namespace

I need to use mysqli and prepared statements inside a namespace, this is working fine up until the point where I try and bind parameters, it connects find and prepare works but form there on I get an error saying call to undefined method.
I have already googled this and all that I could find from google is do
use Mysql;
This doesn't seem to help though. Stack overflow is my last resort.
This is the entire page:
<?php
namespace KrowdUp\Core;
use Mysql;
class DatabaseConnect
{
private $user;
private $password;
private $database;
private $server;
//Variable for database connect
public $db;
//Variable for sql
public $dbSQL;
//Variable for db transaction
public $getData;
//Variable for db error
public $dbERROR;
public function __construct()
{
$this->user = "user";
$this->password = "password";
$this->database = "databse";
$this->server = "server";
$this->db = new \mysqli($this->server, $this->user, $this->password, $this->database);
if($this->db->connect_errno > 0){
die('Unable to connect to database [' . $db->connect_error . ']');
//Handle error
}
}
//Set the SQL
public function setSQL($sql)
{
$this->dbSQL = $sql;
}
//Check the SQL
public function checkSQL()
{
if ($this->getData = $this->db->prepare($this->dbSQL)) {
$this->dbERROR = 1;
return 1;
//Handle error properly
} else {
$this->dbERROR = 0;
return 0;
//Handle error properly
}
}
//Bind paramaters
public function bindParam($param)
{
$this->db->bind_param('i',$param);
}
}
Is this because I am doing something stupid and not noticing or am I missing something? Thank you in advance for your help.
bind_param is a function of mysqli_statement, not the mysqli connection
try
$this->getData->bind_param('i', $param);
http://php.net/manual/en/mysqli-stmt.bind-param.php

Class methods over different files

I am attempting to place a commonly used method (opendb) in the same class and file as my connect configuration file (connect.php) See fig A
class qcon{
public static $conn;
function dbcon()
{
if (empty($conn))
{
$host = 'x';
$username = 'x';
$password = 'x';
$dbname = 'x';
$conn = mysqli_connect($host , $username , $password ,$dbname) or die("Oops! Please check SQL connection settings");
}
return $conn;
}
function openDB($conn)
{
if (!$conn)
{
$this->error_msg = "connection error could not connect to the database:! ";
return false;
}
$this->conn = $conn;
return true;
}
Now I want to be able to pass the connection output of fig A so I can properly use the methods in another class file. Call it class.php. Here's one example function on class.php for viewing records. See fig. B
require_once("assets/configs/connect.php");
class dbcats {
var $conn;
function getResult(){
$result = mysqli_query($this->conn , "SELECT * from felines" );
if ($result) {
return $result;
}
else {
die("SQL Retrieve Error: " . mysqli_error($this->conn));
}
}
function closeDB() {
mysqli_close($this->conn);
}
Now, to get the call to work, Fig C below is where I'm at. I'm a tiny bit stuck.
$db1 = new qcon();
$helper = new dbcats();
$db1->openDB();
$helper = $db1;
$result = $helper->getResult();
So here we are. The logic is simple enough (I'll update the question if I'm not quite clear) So would someone advise on what amendments I need to get the call operational?
Orangepill's solution is fine and will more than likely get you going quickly. However, I would recommend making some minor alterations to your classes to allow you to more easily reuse their functionality across your programs.
Here, qcon holds your database connection information and functionality. It has a getter method, getConn() that allows you to get, and pass around that connection as you need.
class qcon
{
protected $conn;
public function __construct() { ... }
public function dbcon() { ... }
public function openDB() { ... }
public function closeDB() { ... }
public function getConn() { return $this->conn; }
}
Here's an example of an alternative dbcats class. It takes in your qcon class in part of its construction and holds it in as a protected member variable that it can use whenever it needs it. It also has getters and setters so that you can change or retrieve your database connection for this class at any time via getQConn() and setQConn().
class dbcats
{
protected $qcon;
public function __construct(qcon $q) { $this->qcon = $q; }
public function getResult() { ... }
public function getQConn() { return $this->qcon; }
public function setQCon(qcon $q) { $this->qcon = $q; }
}
It may not be the quickest fix, but I believe practices such as this will serve you better in the long-run.
From what I can see you are missing the end curly bracket } on both your classes. Everything would be much easier to see if you make the indentation correctly. That is, each time you have a left curly bracket { the following lines will be indented with one tab. Like this:
class qcon {
public static $conn;
function dbcon()
{
if (empty($conn))
{
$host = 'x';
$username = 'x';
$password = 'x';
$dbname = 'x';
$conn = mysqli_connect($host , $username , $password ,$dbname) or die("Oops! Please check SQL connection settings");
}
return $conn;
}
function openDB($conn)
{
if (!$conn)
{
$this->error_msg = "connection error could not connect to the database:! ";
return false;
}
$this->conn = $conn;
return true;
}
} <<< Missing this one
class dbcats {
var $conn;
function getResult(){
$result = mysqli_query($this->conn , "SELECT * from felines" );
if ($result) {
return $result;
}
else {
die("SQL Retrieve Error: " . mysqli_error($this->conn));
}
}
function closeDB() {
mysqli_close($this->conn);
}
} <<< Missing this one
You need to inject an instance of the qcon class into the dbcats class.
require_once("assets/configs/connect.php");
class dbcats {
var $conn;
public function __construct(qcon $dbconn){
$this->conn = $dbconn;
}
function getResult(){
$result = mysqli_query($this->conn , "SELECT * from felines" );
if ($result) {
return $result;
}
else {
die("SQL Retrieve Error: " . mysqli_error($this->conn));
}
}
function closeDB() {
mysqli_close($this->conn);
}
}
Then when you create an instance of dbcats pass in an instance of conn like ...
$db1 = new qcon();
$db1->openDB();
$helper = new dbcats($db1);
$result = $helper->getResult();

Having issue with understanding two singleton Php code for conecting to mongoDb

I have these two code to use to connect to mongodb.
First i used this code but this doesn't seem to work.I dont know why.
class DbConnection
{
static $db = NULL;
static function getMongoCon()
{
if (self::$db === null)
{
try {
$m = new Mongo("mongodb://username:password#localhost:27017");
} catch (MongoConnectionException $e) {
die('Failed to connect to MongoDB '.$e->getMessage());
}
self::$db = $m;
}
else
{
return self::$db;
}
}
}
After this i used this way to connect mongo in another class
$db=DbConnection::getMongoCon();
$database=$db->databasename;
$collection=$db->users;
But this doesn't seem to work always . i always get error $db not defined or some other undefined error.
Second Code is this . which i used to connect to mongodb without having to create multiple connection. This works fine without having problem.
class DbConnection{
static protected $_instance;
protected $db = null;
final protected function __construct() {
$m = new Mongo("mongodb://username:password#localhost:27017");
$this->db = $m->selectDB( "databasename" );
}
static public function getInstance() {
if (!(self::$_instance instanceof self)) {
self::$_instance = new self();
}
return self::$_instance;
}
public function getConnection() {
return $this->db;
}
final protected function __clone() { }
}
To use this code in another class i used
$db=DbConnection::getInstance()->getConnection();
$collection=$db->users;
I dont know why second one worked but not the first code. if i use both in mysql both works fine.
Also can this be issue than in second code i have create connection to mongodatabase and kept it open and directly used in another class.
please describe simply why the second code worked fine and first didn't worked.
In the first piece of code, when the $db variable is null and you create a new connection, your getMongoCon function doesn't return anything, hence when you try to use it on the example, $db=DbConnection::getMongoCon(); end ups asigning null to the $db variable.
To make it work correctly, you should do something like this:
...
static function getMongoCon()
{
if (self::$db === null)
{
try {
$m = new Mongo("mongodb://username:password#localhost:27017");
} catch (MongoConnectionException $e) {
die('Failed to connect to MongoDB '.$e->getMessage());
}
self::$db = $m;
}
return self::$db;
}
...

Categories