3

I have a problem understand how class extension work..

I'm trying to extend a class to split functions in different files to have it more organized..

But i have problems accessing variables and function of the main class into child class.

That is whats i have:

Parent class: it is the uFlex Class v 0.88 I do not write it all, because it is long..

class uFlex {
    //Constants
    const version = 0.88;
    const salt = "";
    //End of constants\\\\
    /**
     * PDO / database credentials
     */
    var $db = array(
        "host" => '',
        "user" => '',
        "pass" => '',
        "name" => '',   //Database name
        "dsn" => '' //Alterntive PDO DSN string
    );

        function connect(){
        if(is_object($this->db)) return true;

        /* Connect to an ODBC database using driver invocation */
        $user = $this->db['user'];
        $pass = $this->db['pass'];
        $host = $this->db['host'];
        $name = $this->db['name'];
        $dsn = $this->db['dsn'];

        if(!$dsn){
            $dsn = "mysql:dbname={$name};host={$host}";
        }

        $this->report("Connecting to database...");

        try{
            $this->db = new PDO($dsn, $user, $pass);
            $this->report("Connected to database.");
        }catch(PDOException $e){
            $this->error("Failed to connect to database, [SQLSTATE] " . $e->getCode());
        }

        if(is_object($this->db)) return true;
        return false;
    }
}

Then:

<?php
class admin extends uFlex {

    function adm_getUsers(){
            if(!$this->connect()) return false;

            $sql= "SELECT * from users LIMIT 30";
            $st = $this->db->prepare($sql);
        $out = $st->execute();
            $row = $st->fetchAll(PDO::FETCH_ASSOC);
            return $row;    
    }

    function adm_getSingleUser($id){
            if(!$this->connect()) return false;
        if(is_numeric($id)){
            $sql= "SELECT * from users WHERE id = '$id'";
            }else{
            $sql= "SELECT * from users WHERE username = '$id'";
            }
            $st = $this->db->prepare($sql);
        $out = $st->execute();
            $row = $st->fetch(PDO::FETCH_ASSOC);
            return $row;
    }
}

?>

I intiialize them in a config file i include in every page:

$user = new uFlex(false);
$admin = new admin();

But when using $admin->adm_getUsers(); $row array it's empty.

Before to try to split the functions between 2 classes, i was using the same function on the main class, and was working.

It is the first time i try to extend a class.. i searched on google, and also readed some question here, but it is just too complicated for me to understand, since i'm still learning PHP.

4
  • 1
    Don't use inheritance to split functions in different files! Commented Feb 21, 2013 at 9:39
  • 1
    "SELECT * from users WHERE username = '$id'" is a security risk. Commented Feb 21, 2013 at 9:45
  • @Ghommey $id is being checked and escaped before passing it to the function. It is just a test function anyway. Commented Feb 21, 2013 at 9:51
  • Also you should think about a user named "1". Commented Feb 21, 2013 at 10:32

3 Answers 3

7

This is where inheritance is not really the best answer. Instead you can drop the inheritance and use composition instead. Pass your instance of uFlex through as a dependency of Admin as follows:

$user = new uFlex(false);
$admin = new Admin($user); // uFlex is being passed in

You will first need to update your PHP class as there are a couple of changes:

class Admin {

    // Added private variable that will hold the uFlex instance
    private $user;

    // Added a class constructor which will be called when we create a new Admin
    function __construct($user) { // Receives an instance of uFlex
        $this->user = $user;
    }

    function adm_getUsers(){
        if(!$this->user->connect()) return false; // Call connect on user
        $sql= "SELECT * from users LIMIT 30";
        $st = $this->user->db->prepare($sql); // Call prepare on db of user
        $out = $st->execute();
        $row = $st->fetchAll(PDO::FETCH_ASSOC);
        return $row;    
    }

    function adm_getSingleUser($id){
        if(!$this->user->connect()) return false; // Same here
        if(is_numeric($id)) {
            $sql= "SELECT * from users WHERE id = '$id'";
        } else {
            $sql= "SELECT * from users WHERE username = '$id'";
        }
        $st = $this->user->db->prepare($sql); // And here
        $out = $st->execute();
        $row = $st->fetch(PDO::FETCH_ASSOC);
        return $row;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

You should write $user = new admin() if you want to call adm_getUsers(). And you'll have to create _constuct() method in admin class, that will call parent::_construct($val).

Comments

0

When you extend a class you are actually accessing the properties and methods of the parent class NOT EXECUTING THEM. So if you want to access some data from some method in the parent class, you've got to execute that particular method in the parent class and then access it.

For ex:

<?php
class parent{

    public function adm_getUsers(){
        //your code to get users
    }
}

class child extends class parent{
    public $adm_getUsers = array();

    public function getUsers(){
        if(!isset($this->adm_getUsers)){
            $this->adm_getUsers = $this->adm_getUsers();
        }
        return $this->adm_getUsers;
    }
}

$childObj = new child();
$users = $childObj->getUsers();

3 Comments

If i do that, what's the point of divide it in two different classes? I do that just to split function in different files. So admin functions are all inside admin_functions.php, the same goes for users functions and so on.
You always divide two classes with similar functionality and this is where inheritance comes to the picture, so that you can keep your core functions in the parent class and the child classes override it according the different needs in different pages. Classes with different functionality should be kept different.
I do that just to declare functions in different files, for better organization. Using your method, all functions are declared on the main class, and that kill the point of have it divided. Did you understand?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.