Can't use pdo in class function using constructor - php

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

Related

PHP - Can't access database-connector class from another class. What am I doing wrong?

I'm trying to accomplish the same ends as outlined in this question but my application of that answer just does not work. I get blank white screens when attempting to perform any operation involving the database class.
This should be simple-- a user inputs a username and password into a form. If both are received by the controller, I query the database and compare a hash of the submitted password with the hash on file. The problem is, my page does not load once I start making database calls.
I have a controller and two classes. One class is a database connector, the other is an authentication module that depends on the database connector.
Database connector class:
class inquiry
{
protected $pdo;
// Set up the initial db connection
function __construct()
{
try
{
$this -> pdo = new PDO('mysql:host=127.0.0.1;dbname=mysqlserver','mydatabase','ffffffffffffffff');
$this -> pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this -> pdo -> setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_EMPTY_STRING);
$this -> pdo -> setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$this -> pdo -> exec('set names "utf8"');
}
catch (PDOException $e)
{
echo $e -> getMessage();
}
}
}
Then, the authentication class:
class auth
{
private $username;
private $password;
private $db;
function __construct(inquiry $db)
{
$this -> db = $db;
}
function login($username, $password)
{
$this -> username = $username;
$this -> password = $password;
// Query database, get hashed password for username
$this -> db -> query('select password from users where username="bob";');
// Data needs to be fetched but PHP does not process anything past this point anyway
return true;
}
}
Then, in the controller:
require_once '../inc/class.inquiry.php';
require_once '../inc/class.auth.php';
if (isset($_POST['username']) && isset($_POST['password']))
{
// Probably doing something wrong here
$dbconnect = new inquiry();
$user = new auth($dbconnect);
$authorized = $user -> login($_POST['username'], $_POST['password']);
if ($authorized == true)
{
// Send user to index page
header('Location: index.php');
exit();
}
}
I've commented the sections where I think I'm going wrong, but I don't know what to actually do about it. Any tips would be appreciated!
All of your code is wrong on many levels. Starting from code standards where class should start with uppercase letter, formatting the code, finishing to calling a non-existent method.
First of all, your inquiry class does not have the desired query() method. It seems you try to give us a code you have not written by yourself, to debug.
Second, your class is completely USELESS. Even though it does not have a custom wrapping query method, you still could use PDO's method for querying and execute a query. However, even you are assigning value of object of type PDO to your protected $pdo you have absolutely NO ACCESS to this $pdo outside the class i.e. from auth class. You should write an accessor for $pdo, so you can use something like
$this->db->getPdo()->prepare("SELECT ......");

can't connect to db through another class

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.

PDO Active Record prepared statement in separate classes

I need to do continuous parsing of several external stomp data streams, inserts of relevant fields into a MySql db, and regular queries from the db. All of this is in a protected environment - ie I'm not dealing with web forms or user inputs
Because I'm implementing a range of inserts into + queries from different tables, I've decided to set up a PDO active record model - following the advice of Nicholas Huot and many SO contributors.
I've got a simple repeated insert working OK, but after several days of grief can't get a prepared insert to fly. I want to use prepared inserts given there are going to be a lot of these (ie for performance).
Relevant bits of the code are :
=========
Database class :
private function __construct()
{
try {
// Some extra bad whitespace removed around =
$this->dbo = new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPSW, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
public static function getInstance()
{
if(!self::$instance)
{
self::$instance = new self();
}
return self::$instance;
}
public function prepQuery($sql) // prepared statements
{
try {
$dbo = database::getInstance();
$stmt = new PDOStatement();
$dbo->stmt = $this->$dbo->prepare($sql);
var_dump($dbo);
}
catch (PDOException $e) {
echo "PDO prepare failed : ".$e->getMessage();
}
}
public function execQuery($sql) // nb uses PDO execute
{
try {
$this->results = $this->dbo->execute($sql);
}
catch (PDOException $e) {
echo "PDO prepared Execute failed : \n";
var_dump(PDOException);
}
}
=========
Table class :
function storeprep() // prepares write to db. NB prep returns PDOstatement
{
$dbo = database::getInstance();
$sql = $this->buildQuery('storeprep');
$dbo->prepQuery($sql);
return $sql;
}
function storexecute($paramstring) // finalises write to db :
{
echo "\nExecuting with string : " . $paramstring . "\n";
$dbo = database::getInstance(); // Second getInstance needed ?
$dbo->execQuery(array($paramstring));
}
//table class also includes buildQuery function which returns $sql string - tested ok
=======
Controller :
$dbo = database::getInstance();
$movements = new trainmovts();
$stmt = $movements->storeprep(); // set up prepared query
After these initial steps, the Controller runs through a continuous loop, selects the fields needed for storage into a parameter array $exec, then calls $movements->storexecute($exec);
My immediate problem is that I get the error message "Catchable fatal error: Object of class database could not be converted to string " at the Database prepquery function (which is called by the Table storeprep fn)
Can anyone advise on this immediate prob, whether the subsequent repeated executes should work in this way, and more widely should I change anything with the structure ?
I think your problem in this line $dbo->stmt = $this->$dbo->prepare($sql);, php want to translate $dbo to string and call function with this name from this. Actually you need to use $this->dbo.
And actually your functions not static, so i think you don't need to call getInstance each time, you can use $this.

PDOException not triggering / possible scope related?

In anticipation of mysql_query being deprecated PHP 5.5.0, I have been working on a class to handle all my DB queries :
class DataBaseClass {
//.....some other function and variables declared here....
function GetConnection() {
try {
$this->conn = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS);
$this->conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch(PDOException $e) {
echo $e->getMessage();
}
return $this->conn;
}
function Query($str_sql, $arr_parameters = array()) {
try {
$this->str_mysql_error = $this->int_num_rows = $this->int_num_affected_rows = $this->int_mysql_insert_id = '';
if (count($arr_parameters) > 0) {
$obj_result = $this->conn->prepare($str_sql);
$obj_result->execute($arr_parameters);
} else {
$obj_result = $this->conn->query($str_sql);
}
}
catch(PDOException $e) {
$this->str_mysql_error = $e->getMessage() . $str_sql;
}
}
}
Then I have another class to create new user:
class AddNewUser {
//.....some other function and variables declared here....
function InsertUser() {
$str_sql = "INSERT INTO (uname, name, email, pass, user_regdate, theme) VALUES )";
$_SESSION['db_connection']->Query($str_sql, '');
}
}
Now on my main user creation page I have :
$_SESSION['db_connection'] = new DataBaseClass;
//Reason I used $_SESSION to store my DB object, is so that it can be accessible everywhere.
//Did not want to use "global" everywhere. Not sure if this is he best way???
$cls_new_user = new AddNewUser ();
$cls_new_user->InsertUser(); //Does not raise PDOExecption although SQL cleary wrong inside this method
if ( $_SESSION['db_connection']->str_mysql_error) {
//show error in error div
}
$str_sql = "SELECT some wrong SQL statment";
$_SESSION['db_connection']->Query($str_sql); // This does raise PDOExecption
if ( $_SESSION['db_connection']->str_mysql_error) {
//show error in error div
}
I'm not sure why the DB class function "Query" would not raise an exception on clearly wrong SQL when called from another class. But same function called from main page code (not inside function / class) raises and exception error.
Also, the "InsertUser" function does not execute / insert anything into DB even if SQL correct.
Could it be scope related, or the fact that I'm trying to enforce global scope of my DB object by putting it in $_SESSION ??
Am I going about this the wrong way? Reason for going class route to encapsulate all my DB calls was to avoid any deprecation issues in future - only having to update class.
Make your function this way.
function Query($str_sql, $arr_parameters = array()) {
$stmt = $this->conn->prepare($str_sql);
$stmt->execute($arr_parameters);
}
I am pretty sure that exception would be thrown
The only issue can be with catching exceptions, not throwing. And it could be caused by Namespace, not scope. To be certain, you can always prepend all PDO calls with a slash:
\PDO::FETCH_ASSOC
\PDOException
etc.

Custom PDO Class Fails Quietly

For some reason, this custom PDO class fails to write to the database. It simply quietly fails - no error message thrown. A very similar custom PDO class (ReadPDO) works wonderfully for reading from the database. The SQL statement generated works fine when it's queried to the DB through PHPMyAdmin. I've double-checked the user permissions, and everything seems in order.
I suspect I'm misunderstanding how something works. Any ideas?
// Creates a write-only PDO, using config settings from inc_default.php
class WritePDO extends PDO{
public function __construct(){
//Pull global DB settings
global $db;
global $write_host;
global $write_username;
global $write_password;
try{
parent::__construct("mysql:dbname={$db};host={$write_host}", $write_username, $write_password);
} catch (PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}
}
}
private function updatePlayer(){
$conn = new WritePDO();
$sql = "UPDATE {$this->hvz_db}
SET
hvz_bitten ='{$this->hvz_bitten}',
hvz_died ='{$this->hvz_died}',
hvz_feedCode ='{$this->hvz_feedCode}',
hvz_status ='{$this->hvz_status}',
hvz_feeds ='{$this->hvz_feeds}',
hvz_lastFed ='{$this->hvz_lastFed}',
hvz_ozOpt ='{$this->hvz_ozOpt}',
hvz_parent ='{$this->hvz_parent}'
WHERE users_id ={$this->id}";
$query = $conn->exec($sql);
}
The SQL it spits out is as follows:
UPDATE hvz_2011_spring SET hvz_bitten ='', hvz_died ='', hvz_feedCode ='NOMNOM', hvz_status ='Human', hvz_feeds ='0', hvz_lastFed ='', hvz_ozOpt ='0', hvz_parent ='' WHERE users_id =1
are you sure the sql is correct?
The exec doesn't send any error message.
Try doing var_dump($conn->errorInfo()); after $conn->exec($sql);
/Emil

Categories