can't connect to db through another class - php

I have an issue that I can't figure out. I have a class Database which if I use it directly I connect to db regularly. I have another class Categories and I want to call a Database object. The problem is that if I call $db->connect in categories does not work. I tried call mysql_connect directly in Categories and it works fine!
Why can't I use $db->connect (the error is Access denied for user 'user'#'0.0.0.0' (using password: YES).
My code in class Database is:
public function connect($new_link=false){
$this->link_id = #mysql_connect($this->server,$this->user,$this->pass,$new_link);
echo "<br/>link_id = ".$this->link_id;
if (!$this->link_id){//open failed
$this->oops("Could not connect to server: <b>$this->server</b>.");
}
else{
echo "Connected to server <br/>";
}
if(!#mysql_select_db($this->database, $this->link_id)){//no database
$this->oops("Could not open database: <b>$this->database</b>.");
}
else{
echo "Database opened <br/>";
}
// unset the data so it can't be dumped
$this->server='';
$this->user='';
$this->pass='';
$this->database='';
}#-#connect()
My code in class Category is:
public static function selectAll() { // SELECT All Function
$db = Database::obtain();
// connect to the server
$db->connect();
$sql = "SELECT * FROM productCategory";
$rows = $db->fetch_array($sql);
return $rows;
}
Database::obtain code
public static function obtain($server=null, $user=null, $pass=null, $database=null){
if (!self::$instance){
self::$instance = new Database($server, $user, $pass, $database);
}
return self::$instance;
}#-#obtain()
Am I doing sth wrong, that I can't see?

Well, the error message is "Access denied for user 'user'#'0.0.0.0'"
That means when you instantiate your class with $db = Database::obtain(); You don't set the values for server, user, pass, database. Probably the class Database implements a singleton pattern, and the method obtain() just returns the instance without any properties set.

Related

Is this right way to use php oop and mysqli?

I am not very experienced in php oop. Moreover, when mysqli comes with php oop, it make me more confused about using it in best efficient way. Anyway, first look at my connection class:
<?php
//connectionclass.php
class connection{
public $conn;
public $warn;
public $err;
function __construct(){
$this->connect();
}
private function connect(){
$this->conn = # new mysqli('localhost', 'sever_user', 'user_password');
if ($this->conn->connect_error) {
$this->conn = FALSE;
$this->warn = '<br />Failed to connect database! Please try again later';
}
}
public function get_data($qry){
$result = $this->conn->query($qry);
if($result->num_rows>=1){
return $result;
}else{
$this->err = $this->conn->error;
return FALSE;
}
$result->free();
}
public function post_data($qry){
$this->conn->query($qry);
if($this->conn->affected_rows>=1){
return TRUE;
}else{
$this->err = $this->conn->error;
return FALSE;
}
}
}
?>
Now please structure of a php page which uses mysql database to store and get data:
<?php
//login.php
include('/include/connectionclass.php');
$db = new connection();
$query = "SELECT * FROM USERS WHERE user_country='India'";
$data = $db->get_data($query);
if($data){
while($row=$data->fetch_assoc()){
echo 'User Name: ':.$row["user_name"].' Age: '.$row["age"];
}
}
?>
So my login.php uses connection class to get data about users. All the things are running well. But one things made me confused. In connectionclass.php $this->conn is itself an object as it calls new mysqli. So this is an object inside another object $db. Moreover, When I am using $data = $db->get_data($query);, a result set is created inside object $db by method get_data, then this result set is copied into a variable $data inside login.php page.
So according to me, actually two result sets/data sets are creating here, one inside db object and one inside login page. Is it right way to use mysqli and php to get dataset from mysql database? Will it use more memory and server resources when the dataset is larger (when have to get large amount of data for many users)?
If it is not right way, please explain your points and please give me code which can be used efficiently for php oop and mysqli.

Can't use pdo in class function using constructor

suppose I have the class named as User and user is an object of that class,
now I call a function named as storevalues from user(an object of class User).
In the storevalues function,__construct function is called which assign the value to the class member.$this->name,$this->email,$this->password.
finally I try to store these values in DATABASE through PDO.
$conn = new PDO(DB_DSN,DB_USERNAME,DB_PASSWORD);
$sql="insert into user_info(name,email,password)values(:name,:email,:password)";
$st=$conn->prepare($sql);
$st->bindValue(":name",$this->name,PDO::PARAM_STR);
$st->bindValue(":email",$ths->email,PDO::PARAM_STR);
$st->bindValue(":password",$this->password,PDO::PARAM_STR);
$st->execute();
But the above code is not working.The connection is successfull made to the database but query is not executed.I want to know what mistake I have done in this code.
When I try assigning the class members value to the new variable then it works.The code below shows that method
$name=$this->name;
$email=$this->email;
$password=$this->password;
$conn = new PDO(DB_DSN,DB_USERNAME,DB_PASSWORD);
$sql="insert into user_info(name,email,password)values(:name,:email,:password)";
$st=$conn->prepare($sql);
$st->bindParam(":name",$name,PDO::PARAM_STR);
$st->bindParam(":email",$email,PDO::PARAM_STR);
$st->bindParam(":password",$password,PDO::PARAM_STR);
$st->execute();
I am a beginner in php and pdo and I know that my code is inefficient.Help me in finding the mistake in first method and identifying my mistakes.
User class
class User
{
public $name=null;
public $email=null;
public $password=null;
public function __construct($data=array())
{
if(isset($data['name']))
$this->name=$data['name'];
if(isset($data['email']))
$this->email=$data['email'];
if(isset($data['password']))
$this->password=$data['password'];
}
public function storevalues($result=array())
{
$this->__construct($result);
$conn = new PDO(DB_DSN,DB_USERNAME,DB_PASSWORD);
$sql="insert into user_info(name,email,password)values(:name,:email,:password)";
$st=$conn->prepare($sql);
$st->bindParam(":name",$this->name,PDO::PARAM_STR);
$st->bindParam(":email",$this->email,PDO::PARAM_STR);
$st->bindParam(":password",$this->password,PDO::PARAM_STR);
$st->execute();
}
}
You may catch the SQL error after the execute:
if ( ! $st->execute) {
Throw new exception('Mysql Error - ' . implode(',', $st->errorInfo()));
}

error on mysqli multiple connection via class

i have the following problem which costs me the last couple of hours...
i have a class for mysqli connections:
class database extends SplObjectStorage{
private $db_link;
public function __construct($MySQLi_DB){
if(!file_exists($_SERVER["HOME"].'/'.(substr($_SERVER['PHP_SELF'], 1, strpos(substr($_SERVER['PHP_SELF'], 1),'/'))).'/includes/mysqli.inc.php')){
echo "MySQLi Include Datei nicht vorhanden";
}else{
if (!$this->create_connection($MySQLi_DB) == true){
echo "Error creating Database. Parameter '".$MySQLi_DB."' unknown<br><br>";
}
}
}
public function query($query){
Return $this->db_link->query($query);
}
public function close(){
mysqli_close($this->db_link);
}
private function create_connection($MySQLi_DB){
include_once($_SERVER["HOME"].'/'.(substr($_SERVER['PHP_SELF'], 1, strpos(substr($_SERVER['PHP_SELF'], 1),'/'))).'/includes/mysqli.inc.php');
$this->db_link = new mysqli($MySQLi_Host, $MySQLi_User, $MySQLi_Passw, $MySQLi_Praefix.$MySQLi_DB);
$this->attach($this->db_link);
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQLi: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
return false;
}else{
return true;
}
echo $mysqli->host_info . "\n";
}
The constructor initializes the class by looking for an include-file which contains all connectiondata like user, pwd, etc.
it although receive a parameter ($MySQLi_DB) which is similar to the databasename.
When i call this class with this command:
$SSO_DB = new database('SSO');
This class works fine.
Changing the parameter do another databasename is no problem.
e.g.: $Social_DB = new database('social');
This is even no problem until i call two instanzes of my class on the same page!
e.g.:
$SSO_DB = new database('SSO');
$Social_DB = new database('social');
Returns this error:
Warning: mysqli::mysqli(): (HY000/1044): Access denied for user ''#'localhost' to database 'social' in /volume1/web/portal/classes/database.class.php on line 41
Line 41 is:
$this->db_link = new mysqli($MySQLi_Host, $MySQLi_User, $MySQLi_Passw, $MySQLi_Praefix.$MySQLi_DB);
When i remove one of the classcalls no error.
No matter which call i remove...
Any idea?
changing include_once() into include() solved the problem! php seems to store how often the class is called on one page and did not included the file a second time.

Should objects be created chronologically as class defined?

I am having a strange error while creating objects. While I create an objects in chronological orders as classed defined, it is going on good. But when I change the order or object creation, it gives error.
The classes I am using are as follows:
<?php
class dbClass{
private $dbHost, $dbUser, $dbPass, $dbName, $connection;
function __construct(){
require_once("system/configuration.php");
$this->dbHost = $database_host;
$this->dbUser = $database_username;
$this->dbPass = $database_password;
$this->dbName = $database_name;
}
function __destruct(){
if(!$this->connection){
} else{
mysql_close($this->connection);
}
}
function mysqlConnect(){
$this->connection = mysql_connect($this->dbHost, $this->dbUser, $this->dbPass) or die("MySQL connection failed!");
mysql_select_db($this->dbName,$this->connection);
}
function mysqlClose(){
if(!$this->connection){
} else{
mysql_close($this->connection);
}
}
}
class siteInfo{
private $wTitle, $wName, $wUrl;
function __construct(){
require_once("system/configuration.php");
$this->wTitle = $website_title;
$this->wName = $website_name;
$this->wUrl = $website_url;
}
function __destruct(){
}
function showInfo($keyword){
if($keyword=="wTitle"){
return $this->wTitle;
}
if($keyword=="wName"){
return $this->wName;
}
if($keyword=="wUrl"){
return $this->wUrl;
}
}
}
?>
The problem is when I create objects in the following order, it is working perfectly:
include("system/systemClass.php");
$dbConnection = new dbClass();
$dbConnection -> mysqlConnect();
$siteInfo = new siteInfo();
But if I change the order to following
include("system/systemClass.php");
$siteInfo = new siteInfo();
$dbConnection = new dbClass();
$dbConnection -> mysqlConnect();
It gives error!
Warning: mysql_connect() [function.mysql-connect]: Access denied for user '#####'#'localhost' (using password: NO) in /home/#####/public_html/#####/system/systemClass.php on line 19
MySQL connection failed!
Your problem comes from the unconventional use of a configuration file that is read ONCE, but should be used in all classes.
When you instantiate the dbclass first, the configuration is read, probably variables get assigned, and you use these in the constructor.
After that, instantiating siteinfo will not read that file again, which is less harmful, because you only end up with an empty object that does return a lot of null, but does work.
The other way round, you get a siteinfo object with all the info, but a nonworking dbclass.
My advice: Don't use a configuration file that way.
First step: Remove the require_once - you need that file to be read multiple times.
Second step: Don't read the file in the constructor. Add one or more parameters to the constructor function and pass the values you want to be used from the outside.
Info: You can use PHP code files that configure stuff, but you shouldn't define variables in them that get used outside. This will work equally well:
// configuration.php
return array(
'database_host' => "127.0.0.1",
'database_user' => "root",
// ...
);
// using it:
$config = require('configuration.php'); // the variable now has the returned array

Cant pass mysqli connection to class

I am trying to pass an mysqli database connection to a php class. The code I have so far (cut down for simplicity) is as follows:
db.php
$db_host = 'localhost';
$db_name = 'dbname';
$db_user = 'username';
$db_password = 'password';
$db = array('db_host'=>$db_host,
'db_name'=>$db_name,
'db_user'=>$db_user,
'db_password'=>$db_password);
$dbCon = new mysqli( $db['db_host'],
$db['db_user'],
$db['db_password'],
$db['db_name']);
if (mysqli_connect_errno())
{
die(mysqli_connect_error()); //There was an error. Print it out and die
}
index.php
<?php
require_once($_SERVER["DOCUMENT_ROOT"] . "/db.php");
$sql = "SELECT id FROM usr_clients";
$stmt = $dbCon->prepare( $sql );
if ($stmt)
{
$stmt->execute();
$stmt->bind_result($id);
while($stmt->fetch())
{
$cl = new Client($id, $dbCon);
$cl->doIt();
}
$stmt->close();
}
?>
client.php
<?php
Class Client
{
private $con;
public static $clientCount = 0;
public function __construct( $id, $con )
{
$this->con = $con;
$sql = "SELECT id FROM usr_clients WHERE id = $id";
$stmt = $this->con->prepare( $sql );
if ($stmt)
{
echo "it worked!";
}
else
{
echo "it failed";
}
}
}
?>
Now the index.php page successfully recognises the database connection declared in db.php, and returns a list of all clients. It then loops through each client, and creates a "client" object, passing it the database connection.
It is here that the problem seems to start. In the client class, the database connection is not recognised. I get multiple errors on the page saying "it failed". In the logs, there is a line about calling prepare() on a non object.
Can anyone explain why the connection works in index.php, but not in the client class?
Thanks
Your main problem is assumptions.
You are assuming that there is no connection passed, judging by indirect consequence.
But a programmer should be always logically correct in their reasoning.
Talking of connection? Verify the very connection. var_dump($con) in the constructor. var_dump($this->con) in the method. If it fails - only now you can blame connection and start for the solution.
If not - there is no reason in looking for another connection passing method. Yet it's time to find the real problem.
If your query fails, you have to ask mysql, what's going on, using $this->con->error, as this function will provide you with a lot more useful information than simple "it fails". The right usage I've explained here: https://stackoverflow.com/a/15447204/285587

Categories