2

I'm creating a website with structure like this:

class main { }

class mysql extends main { }

class user extends main { }

class etc extends main { }

The idea is for these classes to use functions from each other. This doesn't work. How can I call a function from mysql in user?

EDIT: All errors are similar to this one:

Fatal error: Call to undefined method user::function_in_mysql() in C:\foo.php on line 8

Martti Laine

Martti Laine
  • 12,655
  • 22
  • 68
  • 102
  • 3
    Do you know what classes are? Have you ever used them before? – Michael Myers Apr 05 '10 at 17:44
  • well, it should work as long mysql is first class to load... Can you write simple code? – confiq Apr 05 '10 at 17:44
  • Yea, I'm including files containing these classes, then I call them and use them. It gives me errors, when I try to call a function from mysql in user. – Martti Laine Apr 05 '10 at 17:46
  • 1
    It may be a good idea to let us see those errors... – smentek Apr 05 '10 at 17:51
  • What you're (seemingly) trying to achieve results in strong dependencies between the classes. One way or another at least one class will have a "is-a" relation, while you want (at best) a "has-a" relation. Since your example classes are `user` and `mysql` (having a self-tailored mysql class is yet another issue imo) even dependency injection might be too "strong". see http://en.wikipedia.org/wiki/Loose_coupling – VolkerK Apr 05 '10 at 17:56
  • @Martti check out my answer. I believe you're looking for something along the lines of dependency injection. – anomareh Apr 05 '10 at 17:56

4 Answers4

2

The idea is for these classes to use functions from each other.

That's not what you're doing: Inheritance goes only one way. mysql, user, and etc inherit mains abilities but not those of each other.

You could have mysql extend user extend etc so that at least mysql can call all the functions but that probably won't make sense, as I think they are not ancestors but siblings to each other, fulfilling a distinctly different function.

You would have to either define any shared methods in main - often the best way to go - or introduce the classes to each other so they're able to call each other's functions. You could, for example, add an instance of each needed class as parameters to the constructor:

$etc = new etc();
$mysql = new mysql($etc);

// mysql's constructor sets $this->etc 
// so that it can call etc's functions using $this->etc->function()

or, more complex, using the dependency injection or singleton patterns. I asked a related question some time ago about how to deal with this in PHP and got a lot of feedback, maybe it gives you some inspiration.

Community
  • 1
  • 1
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
1

To call a function from mysql inside of user you could create an mysql object inside of user and call the function.

<?php
// this is user.php
$var = new mysql(); // <--if it takes parameters in the constructor
$var->method();
...
?>

For a better answer could you provide more information, as in, what errors are you getting?

Anthony Forloney
  • 90,123
  • 14
  • 117
  • 115
1

That's not how extending a class works. All the functions that should exist in all classes should be part of main. Then functions that are specific to mysql go in that class. I'm guessing that the classes are not as closely linked in terms of inheritance as you think. If the user class needs to make calls through your mysql class, have a variable in the user class that holds a mysql object.

unholysampler
  • 17,141
  • 7
  • 47
  • 64
1

Having a class extend another makes the methods of the other (parent) available to it. So user extending main only makes the methods of main available to it. If other classes extend main it doesn't allow all of them to call each others methods. You could have user extend mysql and mysql's methods would then be available to user though I don't believe that fundamentally this is what you're looking for.

I think you're looking for something along the lines of dependency injection and not class inheritance.

For example if you wanted your user class to have access to your mysql class you pass it an instance of it in it's constructor.

class user {
    protected $_mysql;

    public function __construct(mysql $mysql) {
        $this->_mysql = $mysql;
    }

    public function myMethod() {
        $this->_mysql->myMysqlMethod();
    }
}

$mysql = new mysql();
$user = new user($mysql);

$user->myMethod();

Here's some good reading on dependency injection.

The Symphony link in particular is a pretty nice read on the overview of dependency injection and how to setup a dependency container.

anomareh
  • 5,294
  • 4
  • 25
  • 22