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.
Related
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 am relatively new to PHP OOP and i know that there are numerous questions here on SO, but none of them seam to be pointing me in the right direction. I have created the class user, and I am calling this in another file.
I am trying to get the method 'reset' to call up 'connect', connect to the mysql db and then query it and set various properties to the row contents.
I am receiving no errors but for some reason it is not feeding the properties any data from the database.
I have tried placing the mySQL connect in the reset method, just to see if the variables cannot be passed between methods. But still no joy.
Can anyone point me in the right direction?
class user(){
public function reset(){
$this->connect();
$sql ='SELECT * FROM users WHERE user_id="'.$user_id.'"' ;
$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result))
{
$this->user_name=$row['dtype'];
$this->user_id=$row['user_id'];
$this->atype=$row['atype'];
$this->user_email=$row['user_email'];
$this->group1=$row['group1'];
$this->group2=$row['group2'];
$this->group3=$row['group3'];
$this->group4=$row['group4'];
$this->group5=$row['group5'];
$this->group6=$row['group6'];
}
// Test that these properties are actually being echoed on initial file... it is
// $this->user_name = "john";
// $this->user_email = "john#gmail.com";
// $this->dtype = "d";
// $this->atype = "f";
}
public function connect(){
//GLOBALS DEFINED IN INDEX.PHP
if ($db_open !== true){
$con=mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
// Check connection
if (mysqli_connect_errno())
{
$debug_system .= 'Error on user.php: ' . mysqli_connect_error().'<br\/>';
} else {
$db_open = true;
$debug_system .= 'user.php: user details grab successful. <br\/>';
}
}
}
}
If you are relatively new to PHP OOP, it is strongly recommended not to mess with awful mysqli API but learn quite sensible PDO first, and only then, making yourself familiar with either OOP and prepared statements, you may turn to mysqli.
Nevertheless, there shouldn't be no function connect() in the class user. You have to have a distinct db handling class, which instance have to be passed in constructor of user class
The problem lies in this line:
$sql ='SELECT * FROM users WHERE user_id="'.$user_id.'"' ;
At no point do you actually define $user_id. Presumably you actually mean $this->user_id.
$sql ='SELECT * FROM users WHERE user_id="'.$this->user_id.'"' ;
Better still would be to make full use of parameterized queries, which might look like this:
$sql ='SELECT * FROM users WHERE user_id=?' ;
You would then prepare the statement and bind the user ID, then execute the query:
$stmt = mysqli_prepare($sql);
mysqli_stmt_bind_param($stmt, $this->user_id);
mysqli_stmt_execute($stmt);
And then fetch the results:
while($row = mysqli_stmt_fetch($result))
As you can see, there is a whole load more to modern MySQL libraries. I'd advise you to do more research into how MySQLi and parameterized queries work (and perhaps PDO as well: it's a superior library) before you use them further. It will be worth the effort.
OK, I see some similar questions to mine, but their examples all use PHP classes...mine does not. Maybe that's the problem? I shouldn't need classes because my site is exceedingly simple at this point in time.
Anyway, I'm trying to use PDO to connect to a MySQL db. I connect to the db fine in a file called config.php, and include this file in index.php with require_once().
I can successfully query the db from another file called process.php, but the problem is within a function within that file; it seems my DBO object is out of scope within that function.
Here are the relevant code snippets:
index.php
require_once('./lib/config.php');
config.php
// tested and connects fine
$pdo = new PDO('mysql:host=' . $hostname . ';dbname=' . $dbname, $username, $password, array(
PDO::ATTR_PERSISTENT => true
));
process.php
<?php
...
// can call $pdo fine in this file outside of functions
...
function authenticate($u, $p) {
// can't call $pdo in here, error says $pdo is non-object
$que = $pdo->query('select user_id, user_pass from users where user_name = \'' . $u . '\' limit 1');
...
}
?>
By the way, I'm using PDO because I was having similar trouble with mysqli, and am trying to get away from mysql, which is apparently depreciated and discouraged.
EDIT: I should have clarified first based on the number of responses I got on this matter: I did try to pass $pdo in as a param to the function, with no luck or change in the error message.
SOLUTION: OK, apparently the problem was that I needed to add require_once('config.php') in my process.php file as well. Not sure why (wouldn't it already be included when index.php was run first?). Then I was able to successfully pass $pdo in as a param to my function, and voila.
That's pretty basic PHP stuff. Variables inside functions are local variables unless you use the global keyword to load them. I suppose you want this:
function authenticate(PDO $pdo, $u, $p) {
$que = $pdo->query('select user_id, user_pass from users where user_name = \'' . $u . '\' limit 1');
//...
}
Edit: If PHP claims that $pdo is not an object, it's not an object, so it doesn't really matter how it's passed to the function. Inspect the variable right before you call authenticate():
var_dump($pdo);
Without the relevant code there's no way to say why. (Assuming it's true that new PDO succeeds.)
You need to pass the PDO object as a parameter to the authenticate() function:
function authenticate(PDO $pdo, $u, $p) {
// ..as in the question..
}
Oh and you should be using a place holder for that username in the query, not string concatenation which is prone to SQL injection attacks.
because $pdo has been declared outside of the function authenticate it isn't available inside it. You need to either pass $pdo in
function authenticate($u, $p, $pdo) {
$que = $pdo->query('...');
}
or declare it as global inside the function to be able to access it
function authenticate($u, $p) {
global $pdo;
$que = $pdo->query('...');
}
I am having a problem when trying to access some functions in my mysql class. The function I have to connect to my database is as follows:
function connect_DB() {
$this->connection = mysql_connect($this->dbURL, $this->dbUser, $this->dbPass) or trigger_error('Connection failed: ' . mysql_error($connection), E_USER_ERROR);
$this->db = mysql_select_db($this->dbName, $this->connection) or trigger_error('Database selection failed: ' . mysql_error($db), E_USER_ERROR);
}
And I create my mysql object using this:
$dbConf = new StoreConfDB();
$dbConf->connect_DB();
Now I have a function that is supposed to grab all of the column names from a specified table. Code:
function get_db_columns($table) {
global $dbConf;
print_r($dbConf->get_db());
$result = $dbConf->query_DB_resource('SELECT * FROM ' . $table);
for($i = 0; $i < mysql_num_fields($result); $i++) {
$meta = mysql_fetch_field($result, $i);
$fields[] = $meta->name;
}
mysql_free_result($result);
return $fields;
}
But I am getting errors, such as:
Warning: mysql_query(): 5 is not a valid MySQL-Link resource
And if I try to remove the connection argument from the mysql_query call I get this:
Notice: Could not run query: No database selected in ...
Now I am running a debugger and have pinpointed what the problem is (I think). When the class works, the connection variable is set to: resource id='5' type='mysql link'
But when it calls the query function in the mysql class from inside the get_db_columns() function the connection variable is: resource id='5' type='Unknown'
So somehow the connection variable gets messed up even though both of the connection variables should be the same thing? (from $dbConf)? I've tested this function in 2 different places, it works in one and not the other! Please help!
#footy:
A print_r on $dbConf returns:
StoreConfDB Object ( [dbURL] => localhost [dbUser] => root [dbPass] => [dbName] => db1 [connection] => Resource id #5 [db] => 1 )
The query_DB_resource function:
function query_DB_resource($query) {
$sql_query = mysql_query($query) or trigger_error('Could not run query: '. mysql_error());
return $sql_query;
}
I noticed a couple of issues:
You have mysql_error($connection) and mysql_error($db). Those aren't valid parameters. You should be using $this->connection in both cases. That will give you better error output.
Normally, it doesn't terribly matter if you pass in a connection resource to mysql_query, but in this case you may want to: mysql_query($query, $this->connection). While I can't say that that is a guaranteed fix, it is likely to help.
Oh, and BTW -- every time someone uses global God kills a kitten. It's true. He told me. Either that or I had some bad nachos. (Yes, I'm a zealot on this issue. It's a good thing. trust me)
Regardless, if you need a variable inside of a function either pass it in, or make a property of a new class (make the StoreConfDB a Singleton? Make it accessible by factory method? You have a number of choices) -- avoiding global as a habit removes something nasty called unexpected side effects.
I am trying to make a function to pull a page's content from a MySQL table using a PDO Prepare statement. My code works just fine outside of the function I defined, but no matter what I do it will not work within the function - I receive the following error:
Fatal error: Call to a member function prepare() on a non-object in /home/tappess1/public_html/pages/stations.php on line 6
Here is my PHP:
function getPageContent($page) {
$st = $db->prepare("SELECT * FROM content WHERE title LIKE ?");
$st->execute(array($page));
$pageContent = $st->fetch();
$text = wordwrap($pageContent['content'], 100, "\n");
$tabs = 4;
$text = str_repeat(chr(9), $tabs) . str_replace(chr(10), chr(10) . str_repeat(chr(9), $tabs), $text);
echo $text;
}
and then
<?php getPageContent(Main);?>
I have even tried using a query instead of prepare statement, simply calling getPageContent() and I receive the same error.
Thanks!
You are trying to access the variable $db which is outside your function's scope.
Either re-initialize your database within the function $db = new PDO...., or - probably better and easier in your case - import the global variable:
function getPageContent($page) {
global $db;
Where and how to best store the global database object is subject of a lot of discussion. If you want to get into it, here is one place to start (there are many others on SO, too). But if you're just getting into PHP, I'd say using the global variable is fine.
The variable $db is not known within your function.