Jump to content

Archived

This topic is now archived and is closed to further replies.

maddog39

Database abstraction layer not passing variables.

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

Share this post


Link to post
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]

Share this post


Link to post
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?

Share this post


Link to post
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.

Share this post


Link to post
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]

Share this post


Link to post
Share on other sites
In the recent code posted I don't see where you're instantiating the db class and calling the init() method.

All I see is you trying to call query() and of course $this->db_type will be null (because of my above comment).

Share this post


Link to post
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]

Share this post


Link to post
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.


Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

×

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.