Hi im using PDO to update some fields of a MySQL database. I've written a class called "bakeIT" which connects to a DB and updates some fields depending on the parameters of the method simple_update().
Somehow the first instantiation call to BakeIT()->simple_update() is working but not the second one? Why is that? I'm getting really crazy on that...
Edit:
I found out some errors:
string(85) "SQLSTATE[28000] [1045] Access denied for user
'ODBC'#'localhost' (using password: NO)" Fatal error: Call to a member
function prepare() on a non-object in
BakeIT.php
The table looks like the following:
class BakeIT {
function simple_update(
$tablename,
$fieldname,
$value,
$id,
$idname,
$token,
$tokenvalue){
$conn=$this->connect_db();
$sql= "UPDATE $tablename SET $fieldname=? WHERE $idname=? AND $token=?";
$q = $conn->prepare($sql);
$q->execute(array($value,$id,$tokenvalue));
$conn = null;}
}
//This as the first query works!
$saveanchor = new BakeIT();
$saveanchor->simple_update('navigation','anchor','whoo',5,'idnavigation','hash','3234');
//This as the second query not!
$savetitle = new BakeIT();
$savetitle->simple_update('navigation','linkname','kawoom',5,'idnavigation','hash','3234');
The field linkname doesn't exists.
To my comment about the security: So far I know the prepred statemend prevents an attacker to inject any bad values into the field content.
function example($value, $primarykey, $condition) {
$q = $conn->prepare("UPDATE table SET somefield=? WHERE $primarykey=?");
$q->execute(array($value,$condition));
}
It is not possible to manipulate the parameters $value and $condition but you can set $tableid to 1=1 -- which would override your compleate table.
E.g. example(12, 34, "1=1 --");that would execute this here:
UPDATE table SET somefield=12 WHERE 1=1 --=34
okay i got it! It's the require_once for the external db-access data. with only "require" the data.php (script with db-access variables) everything works fine...
Thanks for helping though!
Related
I have cerb2 https://github.com/wgm/cerb2, it is an old ticketing system, it might looks weird but I have a a lot of knowledgeable information burried that I want to exploit.
It is basically a PHP5/Mysql software with the mysql_connect() constructor
The main issues are queries that stay null at all times. The code base lays on Class definition and pseudo-variable $this to call a query method from another Class.
function CER_HASH_QUEUES(&$parent)
{
global $session;
global $queue_access; e();
$this->db = (new cer_Database())->getInstance();
$this->_parent = &$parent;
if(empty($queue_access))
$this->queue_access = new CER_QUEUE_ACCESS();
else
$this->queue_access = $queue_access;
$sql = "SELECT q.queue_id, q.queue_name FROM queue q ORDER BY q.queue_name";
$res = $this->_db->query($sql);
That last line ($res =… ) is stopping code execution with:
Fatal error: Call to a member function query() on null in
The Query method called from cer_Database.class looks like this ( https://raw.githubusercontent.com/wgm/cerb2/stable/cerberus-api/database/cer_Database.class.php )
function query($sqlString,$return_assoc=true)
{
$config_db = (new cerConfiguration())->getInstance();
if($return_assoc === true) $this->db->SetFetchMode(ADODB_FETCH_ASSOC);
else $this->db->SetFetchMode(ADODB_FETCH_NUM);
$res = $this->db->Execute($sqlString);
if($cfg->settings["debug_mode"]) {
$time_end = microtime();
$query_time = microtime_diff($time_end,$time_start) * 1000; // convert secs to millisecs
echo "<b>[CERBERUS QUERY]:</b> " . $sqlString . " (Ran: <b>" . sprintf("%0.3f",$query_time) . "ms</b>)<hr>";
}
return $res;
}
That last method depends on a second Class cerConfiguration() which relies on import_config_db() to construct the mysql connector.
I am unable to figure out how to pass successfully my sql request following the design pattern carried by the relevant software here.
The databases and the tables are OK on their sides, and the following php script is returning the sql query OK.
<?php
include('includes/third_party/adodb/adodb.inc.php');
$db = ADONewConnection('mysql');
$db->Connect("localhost", "user", "pass", "databasename");
$rs = $db->Execute('SELECT q.queue_id, q.queue_name FROM queue q ORDER BY q.queue_name');
print "<pre>";
print_r($rs->GetRows());
print "</pre>";
I guess without the object oriented design pattern understanding used by PHP I am going to struggle to resuscitate that old piece of software.
Any help, ideas very welcome.
Yours.
Fatal error: Call to a member function query() on null in
You are likely to find further issues in your investigation, but the problem you're asking for help with is relatively simple.
The database property in the class is defined early on in your code as $this->db, but you are then trying to access it as $this->_db. The underscore makes it a different variable name, and thus it doesn't exist. So it is null, hence why you are getting Call to a member function query() on null.
To fix it, make sure you're using the same name for it throughout the class.
I've come across with a problem. My framework was working just fine with PHP 5.3.0. I upgraded my PHP version to PHP 5.4.x and I started to have few issues with some parts of my framework.
After PHP version upgrade, PDO lastInsterId() always returns 0.
I have auto-increment field called id.
It is adding the data to database without any problems.
For some reason I keep getting 0 as last insert id.
Here is my code;
databaseobjects.php
public static function create () {
global $db;
$attributes = self::sanitize(static::$fields);
$sql = "INSERT INTO ".PREFIX.static::$table_name." (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUE (:";
$sql .= join(", :", array_keys($attributes));
$sql .= ")";
return ($db->crudQuery($sql, $attributes)) ? true : false;
}
public static function lastInsertID () {
global $db;
return $db->handler->lastInsertId();
}
database.php
public function crudQuery($sql, $data) {
$sth = $this->handler->prepare($sql);
return $sth->execute($data);
}
First create() method is called, then crudQuery() method is called.
As I mentioned before, I can add the data successfully to MySQL database.
Unfortunately when I call lastInsterID() method, it always returns 0.
I will be really glad if you can help me out with this problem before I will get the last ID with SQL Query (:
Other than a bug in php/PDO or your framework, there are two possibilities. Either lastInsertId() is called on a different MySQL connection than the insert, or you are generating the id in your application/framework and inserting it, rather than letting auto_increment generate it for you. Which column in the table is the primary key/auto_increment? Is that column included in $attributes in your create() function?
You can test PDO to make sure that part is working correctly with this code (in a new file):
// Replace the database connection information, username and password with your own.
$conn = new PDO('mysql:dbname=test;host=127.0.0.1', 'user', 'password');
$conn->exec('CREATE TABLE testIncrement ' .
'(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50))');
$sth = $conn->prepare('INSERT INTO testIncrement (name) VALUES (:name)');
$sth->execute([':name' => 'foo']);
var_dump($conn->lastInsertId());
$conn->exec('DROP TABLE testIncrement');
When I ran this script, the output was
string(1) "1"
After you commit a transaction PDO::lastInsertID() will return 0, so best to call this method before the transaction is committed.
The one other problem could be using $pdo->exec($sql) instead of $pdo->query($sql).
exec($sql) will return always 0 when you use $pdo->lastInsertId(). So use query() instead.
I got a 0 when the last insert statement failed due to a foreign key contraint. last_error was a string.
When no exception is thrown, lastInsertId returns 0. However, if lastInsertId is called before calling commit, the right id is returned.
http://php.net/manual/es/pdo.lastinsertid.php
In my class 'uzytkownikclass.php' i have a variable which is called '$handler'. That variable store connection with my MySQL database. Before, i created few methods that query database for data. Those functions are working fine. But i created a new method called 'hasRole' which check user role (Administator, moderator etc). But i have a error, PDO is new for me and i can not fix this alone.
Here is my code:
public function hasRole()
{
$email=$_SESSION['email_session'];
$stmt = $this->handler->prepare("SELECT COUNT(*) FROM users INNER JOIN rolausera ON users.id = idusera INNER JOIN rola ON idroli = rola.id WHERE email = :email AND rola.id = :rola");
$stmt->bindValue(':email',$email, PDO::PARAM_STR);
$stmt->bindValue(':rola',$rola, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll();
if($result[0]>0)
{
return TRUE;
}
else
{
return FALSE;
}
}
Here is an error:
Fatal error: Call to a member function prepare() on null in D:\Programy\XAMPP\htdocs\logic\uzytkownikclass.php on line 120
As i said before, i have working methods:
$stmt = $this->handler->prepare("SELECT id, login, email, haslo FROM users WHERE email=:email1 ");
$stmt->execute(array(':email1'=>$email1));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
and here is my connection method:
public $handler;
public function connection()
{
$this->handler = new PDO('mysql:host=localhost;dbname=blog', 'root', '',array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
if($this->handler==false)
{
echo 'Blad';
}
}
I tried to delete relation in query and use simple 'SELECT * FROM user' and i had same error.
Greetings.
The question is: did you call the connection() method before calling the hasRole(), or perhaps you closed the connection somewhere in your code? Anyway, I would check in all methods, that try to query the database, if the connection is established and call the connection() method if not. Php's is_null() function helps determining if a variable has been set. I would also check if $handle is false.
i think it's a problem with PHP 5.6 [Beta].
Check your active PHP version, if you have PHP 5.6 [Beta], change to 5.4.
I haved the same problem, a class for connection with PDO working fine, and without changes into the code, this error: Fatal error: Call to a member function prepare() on null in...
For experience, when i have these errors, i see into my PHP version. On my case the hosting changes the PHP version without advise :(
See: PHP bugs
I'm having a little trouble making something work with a PDO. I will explain as I provide the code.I'm not expecting an answer, but I'm hoping that somebody could provide an explication on what I'm doing wrong and how a correct solution would work like.
I'm working on a CMS and trying to implement a MVC pattern, hence the use of PDOs.
Here is the section of my index.php file where we have the PDO declaration:
<?php
include_once 'models/USER_mapper.php';
$USER_mapper = new USER_mapper( 'localhost', 'root', 'root', 'online_magazine' );
$user = new User();
$user->setIDUser("JohnnyBoy");
$USER_mapper->registerUser($user);
?>
In the USER_mapper I have the connect function which is called on creation of a new USER_mapper and I also have the registerUser() function which takes a User object as a parameter and it should insert into the DB the info from the User object that was used.
Below is the registerUser() function:
public function registerUser($userOBJ) {
try {
$q = $this->DBH->prepare ( "INSERT INTO online_magazine.USER_TABLE (id_user, permission) VALUES (:id_user, :permission)" );
$q->execute ( ( array ) $userOBJ );
$this->DBH->commit ();
echo "it works";
} catch ( Exception $e ) {
echo "it doesn't work";
echo $e->getMessage ();
}
}
The table into which I am inserting has two columns: ID_USER and PERMISSION. Permission's has a default value, which is why I only provide the ID_USER with the setter function and leave the permission blank.
What I'm trying to achieve is to insert data into a table using a User object that has the right values and passing the User object to USER_mapper which will recuperate the info and put it in the respective table.
I hope I have been clear enough to highlight my problem. Let me know if I should add more detail and where.
EDIT1: I forgot to mention that when I use the method above I get a php error that looks like this:
[22-Nov-2013 03:18:08 Europe/Berlin] PHP Fatal error: Uncaught exception 'PDOException' with message 'There is no active transaction' in directory
EDIT2: I found out how to do it using bindParam() as follows:
$id_user = $userObject->getIDUser ();
$this->DBH->beginTransaction ();
$stmt = $this->DBH->prepare ( "INSERT INTO online_magazine.USER_TABLE (id_user) VALUES (:id_user)" );
$stmt->bindParam ( ':id_user', $id_user, PDO::PARAM_STR );
$stmt->execute ();
$this->DBH->commit ();
Thank you all!!
I've come across with a problem. My framework was working just fine with PHP 5.3.0. I upgraded my PHP version to PHP 5.4.x and I started to have few issues with some parts of my framework.
After PHP version upgrade, PDO lastInsterId() always returns 0.
I have auto-increment field called id.
It is adding the data to database without any problems.
For some reason I keep getting 0 as last insert id.
Here is my code;
databaseobjects.php
public static function create () {
global $db;
$attributes = self::sanitize(static::$fields);
$sql = "INSERT INTO ".PREFIX.static::$table_name." (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUE (:";
$sql .= join(", :", array_keys($attributes));
$sql .= ")";
return ($db->crudQuery($sql, $attributes)) ? true : false;
}
public static function lastInsertID () {
global $db;
return $db->handler->lastInsertId();
}
database.php
public function crudQuery($sql, $data) {
$sth = $this->handler->prepare($sql);
return $sth->execute($data);
}
First create() method is called, then crudQuery() method is called.
As I mentioned before, I can add the data successfully to MySQL database.
Unfortunately when I call lastInsterID() method, it always returns 0.
I will be really glad if you can help me out with this problem before I will get the last ID with SQL Query (:
Other than a bug in php/PDO or your framework, there are two possibilities. Either lastInsertId() is called on a different MySQL connection than the insert, or you are generating the id in your application/framework and inserting it, rather than letting auto_increment generate it for you. Which column in the table is the primary key/auto_increment? Is that column included in $attributes in your create() function?
You can test PDO to make sure that part is working correctly with this code (in a new file):
// Replace the database connection information, username and password with your own.
$conn = new PDO('mysql:dbname=test;host=127.0.0.1', 'user', 'password');
$conn->exec('CREATE TABLE testIncrement ' .
'(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50))');
$sth = $conn->prepare('INSERT INTO testIncrement (name) VALUES (:name)');
$sth->execute([':name' => 'foo']);
var_dump($conn->lastInsertId());
$conn->exec('DROP TABLE testIncrement');
When I ran this script, the output was
string(1) "1"
After you commit a transaction PDO::lastInsertID() will return 0, so best to call this method before the transaction is committed.
The one other problem could be using $pdo->exec($sql) instead of $pdo->query($sql).
exec($sql) will return always 0 when you use $pdo->lastInsertId(). So use query() instead.
I got a 0 when the last insert statement failed due to a foreign key contraint. last_error was a string.
When no exception is thrown, lastInsertId returns 0. However, if lastInsertId is called before calling commit, the right id is returned.
http://php.net/manual/es/pdo.lastinsertid.php