Jump to content

Database abstraction layer not passing variables.


maddog39

Recommended Posts

Hello all,

I am coding a custom DBAL for my site and I am having tons of issues making it pass this one global clas variable, for some reason it keeps getting erased from memory after the first function. I have posted a section of my class that has so far been giving me the most problems.

[code=php:0]
class db {
var $db;
var $db_type;
    var $sql;

    function init($dbhost, $dbtype, $dbuser, $dbpass, $dbname) {
        if (!isset($dbhost)) {
            echo "database::init(): No database host set.";
            exit();
        }
elseif (!isset($dbtype)) {
echo "database::init(): No database type set.";
exit();
}
        elseif (!isset($dbuser)) {
            echo "database::init(): No database username set.";
            exit();
        }
        elseif (!isset($dbpass)) {
            echo "database::init(): No database password set.";
            exit();
        }
        elseif (!isset($dbname)) {
            echo "database::init(): No database name set.";
            exit();
        }
switch ($dbtype) {
case "mysql":
$mysql_connect = @mysql_connect($dbhost, $dbuser, $dbpass);
$mysql_select_db = @mysql_select_db($dbname);
if ((!$mysql_connect) || (!$mysql_select_db)) {
echo "database::init(): Database Error:<br>" . mysql_error();
exit();
}
$this->db_type = $dbtype;
break;
case "postgresql":
$this->db = @pg_connect("host={$dbhost} dbname={$dbname} user={$dbuser} pass={$dbpass}");
if (!$this->db) {
echo "database::init(): Database Error:<br>" . pg_last_error($this->db);
exit();
}
$this->db_type = $dbtype;
break;
case "sqlite":
$this->db = @sqlite_open($dbname);
if (!$this->db) {
echo "database::init(): Database Error:<br>" . sqlite_error_string(sqlite_last_error($this->db));
exit();
}
$this->db_type = $dbtype;
break;
default:
echo "database::init(): No database type set.";
exit();
break;
}
    }
    function query($sql) {
        if (!isset($sql)) {
            echo "database::query(): No SQL code set.";
            exit();
        }
elseif (!isset($this->db_type)) {
echo "database::query(): No database type set.";
exit();
}
        if (is_array($sql)) {
            foreach ($sql as $key => $value) {
switch ($this->type) {
case "mysql":
$this->sql['$key'] = mysql_query($value);
if (!$this->sql['$key']) {
echo "database::query(): Database Error:<br>" . mysql_error();
exit();
}
return $this->sql['$key'];
break;
case "postgresql":
$this->sql['$key'] = pg_query($this->db, $value);
if (!$this->sql['$key']) {
echo "database::query(): Database Error:<br>" . pg_result_error($this->db);
exit();
}
return $this->sql['$key'];
break;
case "sqlite":
$this->sql['$key'] = sqlite_query($this->db, $value);
if (!$this->sql['$key']) {
echo "database::query(): Database Error:<br>" . sqlite_error_string(sqlite_last_error($this->db));
exit();
}
return $this->sql['$key'];
break;
}
            }
        } else {
            switch ($this->db_type) {
case "mysql":
$this->sql = mysql_query($sql);
if (!$this->sql) {
echo "database::query(): Database Error:<br>" . mysql_error();
exit();
}
return $this->sql;
break;
case "postgresql":
$this->sql = pg_query($this->db, $sql);
if (!$this->sql) {
echo "database::query(): Database Error:<br>" . pg_result_error($this->db);
exit();
}
return $this->sql;
break;
case "sqlite":
$this->sql = sqlite_query($this->db, $sql);
if (!$this->sql) {
echo "database::query(): Database Error:<br>" . sqlite_error_string(sqlite_last_error($this->db));
exit();
}
return $this->sql;
break;
}
        }
    }
[/code]
When I call function init(), its supposed to connect to the database according to which database system I am using from the $dbtype parameter. Then I take $dbtype and put it into the global class variable $this->db_type, and this is the part that just doesn't make ANY sense. When I go and call the function query(), I get an error message from my error checking system in each function that says, no database type was set, and I do some tests like try to echo each variable and stuff. $this->db_type works in init() but it seems to be cleared when used in query() and there isnt any data in the variable when I try to use it in another function. Now, I dont know but this problem most likely also applies to all the other functions in my class. Can someone PLEASE help!?

Thanks alot!
-maddog39
Link to comment
Share on other sites

Do you happen to be calling query() with an array? because the line under the foreach in query() has:

switch ($this->type) {

when it should be:

switch ($this->db_type) {


Also, you need to take out the single quote from:

$this->sql['$key']

and just use:

$this->sql[$key]

Link to comment
Share on other sites

I have tested this class without multi-db type support and it didnt work originally when I used

$this->sql[$key]

So I added the single quotes. Nice catch on that bug though but I am not running queries in an array in this case. The error the class is returning is:

database::query(): No database type found.

So, the db_type variable isnt being passed, I even tried echoing it in both init() and query() and it works in init() but it seems the variable is cleared in query() because there's no data in it?
Link to comment
Share on other sites

Please show us the code on how you're instantiating and calling init() and query().

If you use single quotes with a variable name in it, then it will not be recognized as a variable but taken literally. Example:

$key = '200';

echo 'var value: $key';  // displays: var value: $key
echo "var value: $key";  // displays: var value: 200

That's why I mentioned you can use $this->sql[$key], or use $this->sql["$key"].

See this section of the manual for more info:
http://us3.php.net/manual/en/language.types.string.php#language.types.string.parsing

FYI - isset() will return false when variable is set with a value but happens to be NULL.
Link to comment
Share on other sites

Okay, $this->sql is an array though, so I think that differs from if your use it in echo as you showed me. But I can't confirm that so ill try it both ways once I get the db_type problem fixed. Also I use isset() because the variable needs to be set and have a meaningful value, meaning, cant be null. Here is the code from my tempalting system that I believe is the one having problems with query() because its the first thing that needs to access the database on my index.

[code=php:0]
class template extends db {
var $tpl_tid;
var $tpl_name;
var $tpl_htmlcode;
var $tpl_cleancode;
var $tpl_variables;

function init($theme_name) {
if (!isset($theme_name)) {
echo "template::init(): No theme name specified.";
exit();
}
$this->tpl_name = $theme_name;
}
function getdata($handle) {
if (!isset($handle)) {
echo "template::getdata(): No handle was specified.";
exit();
}
elseif (!isset($this->tpl_name)) {
echo "template::getdata(): No theme name specified.";
exit();
}
$query = $this->db->query("SELECT * FROM {$config['dbprefix']}templates WHERE title='$handle' AND theme='{$this->tpl_name}' LIMIT 1");
$data = $this->fetch_array($query);
$this->tpl_tid = $data['tid'];
$this->tpl_htmlcode[$handle] = $data['code'];
    }
[/code]
Link to comment
Share on other sites

Well, there is an included file called global.php which has initilizes all major application data, for example stuff from the config file. The way I am execing this is from index.php, and this is how the file structure looks.

index.php
config.php
Folder: includes
---- global.php
---- class_database.php
---- class_template.php

Excerpt from global.php

[code=php:0]
include_once("./config.php");

// Get and include core files
$includes = array(
"class_database",
"class_core",
"class_template",
"class_theme",
"class_paginate"
);
foreach ($includes as $file_name) {
  $file = $config['includes_path'] . $file_name . ".php";
  if (file_exists($file)) {
    include_once($file);
} else {
  echo "File not found.<br>";
}
}

$db->init($config['dbhost'], $config['dbtype'], $config['dbuser'], $config['dbpass'], $config['dbname']);
$template->init("default");
[/code]
Link to comment
Share on other sites

There are a few things that are wrong or could be done better. I suggest you read and learn more on PHP OOP approaches.

Some things for you to look at, think about, or answer for yourself:

Where is either the db or template class being instantiated and assigned to $db?

Why am I extending a template class based on a database class?

What happens if I extend a class and I use the same method name as in the parent (i.e. init method)?

Is it a good idea to put all database types into one class, or can I do it in another more efficient way? hint: one class per database type, and have a database connection factory.


Link to comment
Share on other sites

Well, what I'm trying to do is have other classes be able to use the database class, for sole reason of having the ability to use different database engines and dynamically use different functions accordingly. Now when I try to use the functions in the database class normally without extending I get an error saying, "non-existant object query() in ........" thats when I discovered I could probably use extends to fix that. Thats where I'm stuck.
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.