PDO not working within function - php

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.

Related

Call to a member function query() on null PHP5.6

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.

mysqli queries not returning results inside function

I have several php functions which serve different purposes. Each of them is executing a specified mysqli query yet only the first query returns results.
Here is my code
function setAsNonWorkingProxy(){
GLOBAL $mysqli, $proxy;
$port = explode(":",$proxy)[1];
$proxy = explode(":",$proxy)[0];
if ($sql2 = $mysqli->prepare("UPDATE proxies SET failed=failed+1 WHERE ip=? AND port=?")) {
$sql2->bind_param("si",$proxy, $port);
$sql2->execute();
$sql2->close();
}
}
function markProxyAsUsed(){
GLOBAL $mysqli, $proxy;
$port = explode(":",$proxy)[1];
$proxy = explode(":",$proxy)[0];
if ($sql3 = $mysqli->prepare("UPDATE proxies SET tried=tried+1 WHERE ip=? AND port=?")) {
$sql3->bind_param("si",$proxy, $port);
$sql3->execute();
$sql3->close();
}
}
setAsNonWorkingProxy();
markProxyAsUsed();
When I do this, only the first function that is called, executes the query inside.
The second function is called and the query executed without any errors yet nothing happens. I am using UDPDATE queries inside both functions.
If I change the order of the functions:
markProxyAsUsed();
setAsNonWorkingProxy();
Again, only the first one works. Why is this happening?
The problem is that you are bringing the global scope variable in your function. Then using explode on the $proxy and the result is stored back into $proxy(remember thats the same global var) what happens is that the second function called is now working with the modified $proxy variable. It doesn't even matter if you call the same function two times, it will fail the second time.
function markProxyAsUsed(){
GLOBAL $mysqli, $proxy; //You are bringing global scope vars in here
// If $proxy is something like '222.222.222.222:8080' on your first call
// On the second call will be only '222.222.222.222' and your logic will be broken
$port = explode(":",$proxy)[1];
$proxy = explode(":",$proxy)[0]; //Here is where you are messing it
//Quickfix
$ip = explode(":", $proxy)[0]; // then use $ip in your query
//Proper fix would be to declare the function as so function markProxyAsUsed($proxy)
//and pass it when you call the function.
It happens because you edit the proxy variable inside your function. The first function you run changes the proxy variable from xxxx:yy to xxxx
The second time you execute the function your $port variable will be empty and the where clause in your sql statement will not find it.

PHP works outside function but wont work inside function

I'm trying to put the following code into a function as I need to use it quite a few times but with one variable changed ($subject) but it doesn't seem to be working. If I remove it from the function and run it, it works fine but as soon as it goes into the function and gets called it breaks so I'm not sure there is anything wrong with the code itself. I'm new to using PHP functions, but do I need to pass in everything or can it access variables outside of the function such as the $connect and $id variables which are defined above?
function count($subject){
$getCount = $connect->prepare('SELECT count(*) FROM entries WHERE uid = :id AND subject = :subject');
$getCount->execute(array(
':id' => $id,
':subject' => $subject
));
$rowCount = $getCount->fetchColumn();
return $rowCount;
}
echo count("English");
$connect is no longer accessible inside the function. A simple, but bad fix would be this:
function count($subject){
global $connect
A better fix would be for you to send in the $connect variable to the function:
function count($subject, $connect){
And change your function calls to
count("The subject", $connect)

PDO object not in scope of a function

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

How to put mysql inside a php function?

I have problem about putting mysql into a function showMsg(). The mysql is working fine if it is not wrapped by function showMsg(), but when I wrap it with function showMsg(), it gives error message "Warning: mysql_query(): supplied argument is not a valid". How to put mysql inside a php function? Below is my codes :
<?php
function showMsg(){
$query2 = "SELECT id, message, username, datetime FROM messageslive ORDER BY id DESC LIMIT 20";
$result2 = mysql_query($query2,$connection) or die (mysql_error());
confirm_query($result2);
$num = mysql_num_rows($result2);
while($msginfo = mysql_fetch_array($result2)){
echo $msginfo['message'];
echo $msginfo['username'];
}
}
<div>
<?php showMsg(); ?>
</div>
?>
Never use global.
Pass $connection into your function as an argument.
Logic and representation should be separated.
Read about MVC: here or here.
Global variables are evil, never use it. If someone suggests it - ignore all their answers.
You probably need:
global $connection;
(Inside the function, that is.)
See Variable Scope
As everyone mentioned, the issue has to do with variable scoping. Instead of add global $connection; you could consider a more OOP approach and consider:
A: passing the $connection variable into the function.
B: placing related functions in a class and pass the DB connection into the Class constructor.
for example:
class YourClass {
private $connection;
public function __construct($connection) {
$this->connection = $connection;
}
public function showMsg(){
$query2 = "SELECT id, message, username, datetime FROM messageslive ORDER BY id DESC LIMIT 20";
$result2 = mysql_query($query2,$this->connection) or die (mysql_error());
confirm_query($result2);
$num = mysql_num_rows($result2);
while($msginfo = mysql_fetch_array($result2)){
echo $msginfo['message'];
echo $msginfo['username'];
}
}
}
I don't have enough rep to comment. But I also like OZ_'s answer :)
$connection variable has no value assigned. The following code should solve your problem (add it at the beginning of the function):
global $connection;
But you should be aware of the fact, that using globals is not a good idea and you may want to:
(preferably) pass $connection variable within the parameter of the function, or
move $connection declaration from outside the function just into the function (if it does not cause additional problems), or
redeclare $connection variable within the function (again: if it will not cause additional problems),
Because variables are local to functions. You need to add this inside your function:
global $connection;
Simply put, functions ignore outside variables due to variable scope. You must let the declare the variable as being from the outside by using global or you can send $connection through a parameter.

Categories