Calling a public function from another function - php

I have a database class with several PDO functions inside (db.inc.php). I'm trying to call this function from another function:
// Query method
public function query($query) {
$this->stmt = $this->dbh->prepare($query);
}
In my global PHP file I have instantiated the database using:
// Instantiate database
$database = new database();
However when trying to call this function from another function inside of a different PHP file (user.inc.php):
function confirmAccount($key,$id) {
// Check key and id against entry in database
$database->query('SELECT * FROM users WHERE id = :id');
}
I get the following error:
Fatal error: Call to a member function query() on a non-object in /home/studevne/public_html/includes/user.inc.php on line 10
All of my PHP files are included in the global PHP file as so:
include_once 'includes/db.inc.php';
include_once 'includes/echo.inc.php';
include_once 'includes/tools.inc.php';
include_once 'includes/user.inc.php';
I'm guessing its something to do with the scope of the database class and its functions howevver I'm a little confused on how to solve this. Any help is greatly appreciated.

You need to pass $database into the function, else it's out of scope. You can either pass it in as a parameter:
function confirmAccount($key,$id,$database) {
// Check key and id against entry in database
$database->query('SELECT * FROM users WHERE id = :id');
}
Or as a global:
function confirmAccount($key,$id) {
global $database;
// Check key and id against entry in database
$database->query('SELECT * FROM users WHERE id = :id');
}
globals are generally frowned upon, as they make it very easy to write messy code.

Related

PHP OOP, undefined property. How can I get this to work?

Okay so I'm basically trying to improve with PHP OOP, however I'm not too sure how I should do this. Could someone please point out the issue?
The code returns the following errors:
Notice: Undefined property: registration::$userExist
Fatal error: Call to a member function fetch() on a non-object
The class:
class registration extends connect{
public function userExist(){
global $dsn;
$userExist = $this->dsn->prepare("
SELECT * FROM accounts
WHERE username= :username
");
$userExist->bindParam(':username', $username);
$userExist->execute();
$rows = $this->userExist->fetch(PDO::FETCH_NUM);
return $rows;
}
How I'm trying to use the class on a page:
$conn = new connect();
$registration = new registration();
$rows = $registration->userExist();
if($rows < 1){
// do something
The error says that it cannit find variable $userExist, this is because on the last line you are looking for variable "$userExist" inside "$this" while you defined it as a normal variables a few lines above it.
To fix the problem, drop the this-> part of the line that gives the error so it pick up the variable from the local scope
$rows = $userExist->fetch(PDO::FETCH_NUM);
EDIT
You said in comments that variable $username was properly defined before you called the method userExists(). However, in php variables won't be copied over to inside of the function code block when they are called. To pass variables you need to add an argument to the function.
public function userExist($username){
...
$rows = $userExist->fetch(PDO::FETCH_NUM);
....
}
And you need to use it like:
....
$rows = $registration->userExist($username);
....
You don't need $this->userExist
class registration extends connect{
public function userExist(){
global $dsn;
$this->dsn = $dsn; // assign global $dsn to $this->dsn
$userExist = $this->dsn->prepare("SELECT * FROM `accounts` WHERE `username`= :username");
$userExist->bindParam(':username', $username);
$userExist->execute();
$rows = $userExist->fetch(PDO::FETCH_NUM);
return $rows;
}
This happens because you don't have a property userExist in the class registration.
Just change
$rows = $this->userExist->fetch(PDO::FETCH_NUM);
for
$rows = $userExist->fetch(PDO::FETCH_NUM);

php access db class from inside a function

My database class works perfectly and I call it like this $db = new Database('user', 'pass', 'db', 'host');. I top of my script I am defining this database, but later in the script I am trying to use the connection inside a function, but it seems to that the $db is not global, so my function can't access it. I have the possibility to create a new database class connection inside every function in my script, but I really would like to access the $db as a global access point.
Here is some code:
require_once('database_class.php');
$db = new Database('user', 'pass', 'db', 'host');
// I can reach the $db here and make the $db->PDO->'statement'();
function userExists($user) {
$bool = false;
// But in here I can't access $db...
$query = $db->PDO->query('SELECT * FROM login WHERE username = "$user"');
$result = $query->fetch();
if ($result) {
// User exists
$bool = true;
}
return $bool;
}
Put global $db at the beginning of the function like so:
function userExists($user) {
global $db;
// Rest of code here
Variables within functions only exist locally by default in PHP. To use a variable declared outside of a function which is not passed as an argument (e.g $user) you need to use a global variable as shown above.
You could probably just modify your functions to take the $db var as an argument. e.g. :
function userExists($user, $db) {
...
}
Objects are passed by reference by default (see here) so you won't be inadvertently making copies of the $db object with each call.
I use classes for connections and queries too. But it would help that you define already in your class the variables needed for connection, so you don't have to repeat them in every page of code.
and maybe this? use the db as an argument.
function userExists($user, $db) { //codecodecode }

Can I pass a variable into a function?

I'm trying to refactor some code but I'm kinda confused. I define my database connection like so:
try{
global $conn;
$conn = new PDO("mysql:host=$host",$root,$pw); [...]
Now I'd like a function for retrieving table rows but it needs $conn. Is there any way in which I can pass $conn into this function? I tried to set it as a default value but that doesn't work:
function get($table,$conn=$conn,$limit=10){ [...]
I then tried the use keyword but I think it's only available for anonymous functions:
function get($table,$limit=10)use($conn){
$query = $conn->query(" [...]
How do other people do this? Am I missing something obvious here?
function get($table, $limit=10)
As you already wrote in your question, this function header is incomplete. The function itself can not do what it needs to do without having $conn.
As this is a function in the global namespace, the most straight forward thing could be to use a global variable:
function conn_get($table, $limit=10) {
global $conn;
I also name-spaced the function to make the relation clear. The problem with this are two things:
global functions are expensive to maintain
global variables are expensive to maintain
So what you normally do in that case is to wrap this into a class:
class Conn
{
private $conn;
public function __construct(PDO $conn) {
$this->conn = $conn;
}
public function get($table, $limit=10) {
$query = $this->conn->query("[...]");
...
}
}
You then pass around a Conn object which can be used:
$pdo = new PDO("mysql:host=$host", $root, $pw);
$conn = new Conn($pdo);
And then:
$conn->get('ColorTable', 200);
The private variable takes over the role of the global variable with the benefit that every method inside the same object can access it. So everything now is in it's own space and contrary to the global space, will not go into each others way that fast. This is easy (easier) to change and maintain over time.
When you call the function i.e:
$table_rows = get($table, $conn);
You are passing local variables inside the function scope.
However you can't define a not-static variable as default: $conn=$conn will throw a fatal error.
In PHP, use is the way to go for anonymous / lambda-functions but not for ordinary functions.
If you have the database connection flying around in global scope, you can either pass it as a normal variable to your functions like so:
function get(PDO $conn, $table,$limit=10) {
$query = $conn->query(" [...]
}
Other than that (bad practice!) is to get the global $conn variable into the function like so:
function get($table,$limit=10) {
$query = $GLOBALS['conn']->query(" [...]
}
However, an object oriented approach is recommended! You might want to inject the Database Class via dependency injection into the classes, where you need it.
the most simple thing you can do is to create a function that will return you the $conn variable
function conn (){
$conn = NULL;
...some database connection setup etc...
return $conn;
}
and call it to other functions that you need to use it
function getDb(){
conn()->query(" [...]");
}
the conn() function will be available to all your functions on your PHP script.
but if you plan to make a more complex web application I recommend you to use a PHP framework or make a PHP class and apply OOP principles that would handle the database connection for you.

problem in variables scope in PHP

I wrote this code
require('Database.class.php');
function get_info (){
$db = new Database($config['server'], $config['user'], $config['pass'], $config['database'], $config['tablePrefix']);
$db->connect();
$sql = $db->query('SELECT * FROM ja_cat');
while ($options = $db->fetch_array($sql)) {
$cat[].=" ".$options['title'];
}
$db->close();
return $cat;
then I get this Mysql error
Mysql Error : No database selected .
but when I put the require instruction inside the function it's work fine
My guess is Database.class.php creates some variables that are probably global in scope that it relies upon. If you require it inside the function and it works, that supports that theory. Is that your class? Can you change it? Can you post it?
Basically $config needs a global qualifier inside the function.
Make this the first line IN your get_info() function:
global $config;
Also, you may want to define $db outside of the function at the start of the code and then close the connection at the end, instead of having to re-connect multiple times.
You have to import the global variable $config into the scope of the function:
function get_info() {
global $config;
}

Converting mysql to mysqli - how to get superglobal connection object?

I am trying to convert code from mysql to mysqli.
The code uses a single mysql_connect in a file which is included by every other file.
mysql_connect returns a MySQL link identifier that is a superglobal so you can rely on having a database connection available in any of your own functions.
It looks like with mysqli_connect this is not the case, the object returned isn't global.
Does this mean I have to add : global $mysqli; at the top of every function, or is there an way of making it a superglobal?
Relying on the fact that PHP will use the last opened connection resource if you don't specify one, is probably not a very good idea.
What happens if your application changes and you need two connections, or the connection is not there?
So it seems you need to do some refactoring anyway.
Here's a solution similar to Karsten's that always returns the same mysqli object.
class DB {
private static $mysqli;
private function __construct(){} //no instantiation
static function cxn() {
if( !self::$mysqli ) {
self::$mysqli = new mysqli(...);
}
return self::$mysqli;
}
}
//use
DB::cxn()->prepare(....
I usually make a function:
$mysqli = new mysqli(...);
function prepare($query) {
global $mysqli;
$stmt = $msqyli->prepare($query);
if ($mysqli->error()) {
// do something
}
return $stmt;
}
function doStuff() {
$stmt = prepare("SELECT id, name, description FROM blah");
// and so on
}
and then call that. That being said, I've since abandoned mysqli as being too bug-ridden to be considered usable. Shame really.
A very simple way to do this would be with a fixed database class, just to hold the mysqli connection object:
class Database {
public static $connection;
}
Database::$connection = new mysqli(HOST, USERNAME, PASSWORD, DATABASE);
Then you can access it in the normal ways:
$sql = 'SELECT * FROM table';
$result = Database::$connection->query($sql);
$result = mysqli_query(Database::$connection, $sql);
echo 'Server info ' . mysqli_get_server_info(Database::$connection);
To introduce some oop to you and solve your problem, you could use a class like this:
class MyDatabase
{
private static $_connection;
public static function connect()
{
$mysqli = new mysqli(...);
self::$_connection = $mysqli;
}
public static function getConnection()
{
return self::$_connection;
}
}
In your database-connection file you would load this class and execute MyDatabase::connect(); once.
To get the $mysqli-connection anywhere in your script, just call MyDatabase::getConnection();.

Categories