tags:

views:

82

answers:

4

I might be missing something here, I'm not sure. A Google search didn't really help either.

What I'm wanting to do is call the databaseServer class and use its methods within my userControl class. Here is my lib_class.php file:

<?php

include('definitions.php');

class databaseServer {

    var $con;
    var $db;
    var $close;
    var $qry;
    var $sql;

    function connect($host,$user,$pw,$db) {
        $this->con = mysql_connect($host,$user,$pw);
        if (!$this->con) {
            die('Could not connect: ' . mysql_error());
            }
        else {
            echo "Database Connected";
            }
        $this->selectDb($db);
        }

    function selectDb($database) {
        $this->db = mysql_select_db($database,$this->con);
        if (!$this->db) {
            echo "Could not Select database";
            }
        else {
            echo "Database Selected";
            }
        }

    function disconnect() {
        $this->close = mysql_close($this->con);
        if ($this->close) {
            echo "Disconnected";
            }
        }

    function query($test) {
        if (!mysql_query($test)) {
            die("Error: " . mysql_error());
            }
        }

} // databaseServer

class cookie {

    var $expireTime;

    function set($name,$value,$expiry) {
        $this->expireTime = time()+60*60*24*$expiry;
        setcookie($name,$value,$expireTime);
        }

    function delete($name) {
        setcookie($name,"",time()-3600);
        }

    function check($name) {
        if (isset($_COOKIE["$name"]))
            echo "Cookie Set";
        else
            echo "Cookie failed";
        }

} //cookie

class userControl {

    public function __construct(databaseServer $server) {
        $this->server = new databaseServer();
    }

    function createUser($uname,$pword) {

        $this->server->connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
        $result = $this->server->query("SELECT * FROM user_list WHERE uname='" . $this->server->real_escape_string($uname) . "'");
        if ($this->result->num_rows() === 0) {

            if ($this->server->query("INSERT INTO user_list (uname, pword) 
            VALUES ('" . $this->server->real_escape_string($uname) . "','" . $this->server->real_escape_string($pword) . "')") {
                echo "User Added Successfully!";
            }
            else {
                echo "Error Adding User!";
            }
        }

        else {
            echo "User Already Exists!";
        }

    } // createUser

} // userControl

?>

However, this isn't working and I can't see why. My databaseServer and cookie classes work fine when I omit the userControl class from the file, so I know the error must be in that class somewhere. OOP is something I'm trying to learn and I keep stumbling.

The echoes in the databaseServer class are there only for me to test it. I am implementing the classes in an index.php file as follows:

<?php

include('definitions.php');
include('class_lib.php');

$bmazed = new databaseServer();

$bmazed->connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);

$sql = "INSERT INTO blah
VALUES ('testing 92')";

$bmazed->query($sql);

$bmazed->disconnect();

// $control = new userControl();

// $uname = "Test1";
// $pword = "test1";

// $control->createUser($uname,$pword);

echo "<br />";
echo "<br />";

?>

Lines have been commented out for testing purposes, so I don't have to keep re-writing code.

I really have no idea where the problem lies, I've checked syntax and everything seems fine.

+5  A: 

You cannot assign class or instance properties that depend on runtime information when you declare the classes. See the chapter on Class Properties in the PHP Manual.

Change the class to read:

class userControl
{
    protected $_server;

    public function __construct ()
    {
        $this->_server = new databaseServer();
    }
}

Also, to access class/instance members, you have to to use the $this keyword, e.g.

$this->_server->connect();

On a sidenote, while composition is fine, aggregation is better. It helps your code staying maintainable and loosely coupled, which means it will be much easier to replace components, for instance when writing UnitTests. So consider changing the constructor to use Dependency Injection.

Gordon
Or even better would be to use dependency injection to put the database server into the class `public funciton __construct(DatabaseServer $server) { $this->_server = $server; }`
ircmaxell
I disagree with your use of underscores as variable prefixes, given that your example is clearly PHP5 code.
Alan
@Alan I am using [ZF's coding standard](http://stackoverflow.com/questions/1798916/why-does-the-zend-framework-prepend-an-underscore-here/1799034#1799034) but feel free to disagree with this convention. On a sidenote, [PEAR's coding conventions require the underscore for private properties, but no longer for protected properties when using PHP5.](http://pear.php.net/manual/en/standards.naming.php)
Gordon
@ircmaxell: good call. DI is definitely the right thing to do here.
ladenedge
+1  A: 

Initialize $server in the constructor:

class userControl {

 private $server;

 function __construct() {
  $this->server = new databaseServer();
 }

 function createUser($uname,$pword) {
  $this->server->connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
  $result = $this->server->query("SELECT * FROM user_list WHERE uname='" . $this->server->real_escape_string($uname) . "'");
  if ($this->result->num_rows() === 0) {

   if ($this->server->query("INSERT INTO user_list (uname, pword) VALUES ( '" . $this->server->real_escape_string($uname) . "','" . $this->server->real_escape_string($pword) . "')") {
    echo "User added Succesfully";
    }
   else {
    echo "Error Adding User";
    }

  else {
   echo "User already exists";
   }
 }

}
Edward Mazur
except in the createUser method you should be referencing $this->server instead of $server
Mark Baker
@Mark Thanks, fixed!
Edward Mazur
`$server` needs a keyword. Either `var` or a visibility modifier.
Gordon
+1  A: 

For one, $server won't be accessible from within createUser() because it's in a different scope. PHP scope works a bit differently than one would expect from a C-style language.

Try either passing the $server to createUser(), or initializing the server in createUser(), in which case you should probably have a getServer() function so that you're not initializing it needlessly.

The third option is by far the worst, which is doing "global $server" at the top, inside the function. But it's very bad practice. You have been warned.

Last but not least, you should probably look for COUNT(*) than * in the SQL query, because otherwise you're selecting all the users. :)

If you want further information on PHP's scope, see here (highly recommended): http://php.net/manual/en/language.variables.scope.php

Hope it helps!

Helgi Hrafn Gunnarsson
A: 

The syntactical stuff certainly was a problem. But even more fundamentally wrong with my code was the fact that the databaseServer->query method doesn't return a value. Making it return a value fixed the problem.

I think, sometimes, it's not possible to see the wood for the trees. :)

Saladin Akara