Calling Classes

Hi all,

This is a problem I’ve been struggling with for a little while, that is a little annoying as it seems to defeat the object (no pun intended).

For sake of argument, the classes are a and b.


class a{
  function e(){
    //Do stuff
  }
}

Then, that class is included, and a new instance called in an includes file:


inlcude_once 'a.class.php';
$a = new a();
include_once 'b.class.php';
$b = new b();

Class b, create below is also included and initialized.


class b{
  function f(){
    //Do some more stuff
  }
}

Then, if I want to do something like this:


class b{
  function f(){
    $a->e();
  }
}

It will fail, meaning class b has to become:


class b{
  function b(){
    global $a;
    $this->a = $a;
  }

  function f(){
    $this->a->e();
  }
}

Now, when I have lots of classes that require to call from another class, but do not extend the function, etc. how can the variable be available to all classes as what it is initialized as, otherwise I’m writing more code to bodge the classes when I may aswell just write some functions and be done with it (as they need globals too).

Please tell me if I’m missing the point!

Yep, I have my own anology for programming: baking. Everyone may be given the same recipe, and the same ingredients, and the same equipment, but none of the cakes will turn out the same.
I’m sure I’ll find my own way of working things out over time - this project has a tight turn around schedule so I may skimp on the OOP’iness of it all, and just begin with the basics (going back to baking it’s no good to try and make something incredibly difficult when you can’t make a sponge) - and then when I have the time, and no deadline I’ll create a project for myself just to try out all of these OOP techniques and build classes that can become a blueprint for everything (form validation, etc (another favourite of mine is where would you sanitize everything for a database? I am currently doing it just before it goes into the database - handled by the database logic as it’s a mysql_ function, but, in flow it’s probably better of when validating the form)).
I’ll go off and have a play and see what I can come up with - but cheers for the help everyone (and global variables are now being avoided with extreme caution the way I was currently using them!) - and the tough, confusing world of OOP is now making much more sense than it did around 48 hours ago where I had a whiteboard, a few boxes and names such as users, CrUD, auth and so forth scribbled in.

Thanks all.

:slight_smile: I love it when the words “make sense” creep into replies. Glad I can help.

Absolutely. This is an excellent and very logical way to set things up. The application logic items like users and authentication tokens, and orders, and bookings, and reservations, and action queues, and web pages, etc. etc. or whatever items you wind up with in your application hit the database through your data access class to get whatever data they need. Or you can use another class to hit the DB and then pass the data to the object. It just depends on what makes the most sense to you since you can code the application either way. I will note that a typical way to improve DB performance uses this technique when you need to return a lot of something. Let’s say you need to return a list of 1,000+ user objects for a function that sends the latest version of your email newsletter. Running 1,000 separate queries would be pretty wasteful. It’d be much more performance friendly (though much more memory intensive) to pull all 1,000 users into an array (that’s naturally wrapped into a class, like EmailQueue or something like that). Then you can iterate over the array to create each user and stick the user into the function that will send them the email newsletter. I will also note that in a case like this, I typically hide the mass of data in the DAL layer. That way the rest of my classes remain blissfully ignorant of whether this user was created individually from a login action or in bulk as part of a mass email. This is a case where what you don’t know (information hiding) literally cannot hurt you. If you go back and make any changes to the insides of those functions, none of your code cares unless you have to alter the public interface.

OK, this may just be me, but again, in an attempt to be more specific to your needs, I’ll tell you how “I” would do it, even if that steps on a lot of what other people think OOP is or is not. I don’t see these being operations that a User does, but things that happen TO a user. You may feel differently, but that’s how I would approach this and hopefully it will at least take you down a path that will let you figure out how you want to solve it (You can tell that I believe that programming is an incredibly creative and individual process, hence the importance of simplicity and self-documenting code in order to give someone else a fighting chance to work with your code :wink: )

Since I look at these as actions that happen or act on users, then they don’t go into a user class, rather the user class will be dependent on the code. So the way I handle authentication is to use an Authentication module. The Authentication module handles login, etc. and at the end you have one of two situations. Either you have successfully identified a user in your DB and created a user object, or you have not and the user is still anonymous. All my UI classes that have varying displays and access for members vs. anonymous users simply check for the presence of the User object to confirm whether they are logged in. So my Authentication module handles logins, usernames, passwords, etc. and it ends by creating the User class. For data access and CRUD operations, I would suggest something similar in the DAL. You’ll have an AppLogic class (in a small application with little code) or a more specific UserManagement class (in a large application with lots of code). Then you simply add new functions to the UserManagement class to take care of each action you want to cover. To create a new user, you would take the user’s information from a “Create User” form, sanitize and validate the data, and then populate the information in a user object with it. Then you would pass the user object to the createUser() function of the UserManagement class. This would take the relevant data and pass it to a DAL function (or maybe better, pass the user object and let the DAL function sort things out for itself). The DAL function(s) would then execute an INSERT to create a new user in the DB. You can do the same thing to UPDATE user information from a “Update User Info Form” or delete a user or whatever.

OK, OOP is so huge and has been around so long that it now means almost anything to almost everyone. This is why it’s so easy for two people to bash it (for completely different reasons) and two people to argue with them that it’s the greatest thing since sliced bread (while talking about completely incompatible techniques). So I won’t make any sweeping statements, I’m just saying… here’s how I would do it.

You have a master class that creates both object a and object b. In general, I like this structure and use it in my own code. Yet, clearly it is causing you some problems in this case, and without seeing code samples, I can’t be really specific (though that’s probably not necessary since this is a relatively high level design question).

There’s a guiding principle that i use in cases like this, a piece of old programmer’s wisdom that still works miracles to simplify the code you’re writing. When you write a function, it will reference lower level functions (unless it’s a really low level implementation function that’s got it’s hands in the mud and is doing all the dirty work itself). This should be a master-slave relationship. The function you’re writing is the master, it decides which functions should be called to get the work done and decide when they should be called. It should also decide the parameter values which are passed into the functions to make them work. However, you’ll note that this is all “thinking” / supervisory kinds of tasks. The job of implementing the details and getting the work done is not even considered… that is the job of the slave functions. Those functions will know nothing about the supervisory items, they’ll just take the parameters and do the job they do, either directly (by getting dirty) or by acting as masters to other even lower level slave functions. So every function in your application (almost) is a slave to whatever function calls it, and a master to the functions which it calls.

Using this idea, you have two ways to go. One, class a (the data access class) and b (the user class) may be sibling classes in the master function. One class may produce some kind of output which is then used as the input of the other class (which is passed in as a parameter). Two, one class may depend on the other class. In that case, you would not use them in parallel in the same function. You would find on class referenced inside the functions and data of the other class, ie you’d compose one class with the other.

Let’s look at a real world example. Let’s say this is creating dynamic XHTML for a website which users can personalize. In that case you might call some machinery to read the user’s cookie; then you can pass that information to class a, the database class. Class a uses the info in the cookie (the parameter passed to it) to identify the correct user in the DB and from this information you create the user class. In this case class b is the output of a function in class a - a retrieveUser() function which accepts a sessionID and returns a user, object b. You can then pass the entire user class (or parts of it’s data) to a UI function which grabs the items it needs in order to output the personalized webpage for the user. Note that this is a typical, but mixed case. The data access class depends on the user class, at least for the retrieveUser() function, because it makes use of the user class in its own code. However, in the master function you have instances of both the data access class and the user class where they are effectively siblings (though the user class is the output of the data access class).

Another possibility is that we are writing code to process input from an “update user information” page. In this case, we run the machinery described above to determine the user and create the user object from the sessionID. Next we’d like to validate some of the code (like adding a couple of hidden form fields like inputOriginalName and inputOriginalEmail) to make sure that the information from the Request object is kosher and not someone trying to hack the system, or the product of a botched HTTP request. You also want to take ALL the user input and individually sanitize/validate everything to make sure it’s safe to work with. Then the user class can package up the data which needs to be saved to the DB. You might simply modify the user class by rewriting it’s properties with the new user input values (after it’s validated anyway). Or the user class might create class c, which contains the values to be changed. Either one of these data packages is then passed as a parameter into a function in the data access class, let’s call it updateUserInfo(). The data access function (most likely) calls lower level slave functions which hit the database and (again, most likely) execute an UPDATE nonquery against the appropriate userID to save the updated user information.

Hopefully, this is less theorhetical and more helpful in terms of seeing how the different classes can depend on, and even act on one another in ways that are healthy but which balance the desire to eliminate unnecessary dependencies with the desire to use dependence to get work done, typically by calling a class (composition) to have it do lower level work for you.

In your example class b is totally dependent upon class a.

It cannot do anything without it.

You could elect to have made that dependency more obvious, by passing an a in as a argument when it started up.


class b {
function __construct ( a $a ){
$this->a= $a;
}

b is still just as dependent upon a, but now

a) it is documented
b) it will throw a very descriptive error

but more importantly, perhaps for you, you can pass any kind of class to b as long as it is derived from an a.

:slight_smile: This can be a little tricky, if you’re “looking at the problem from the side”. OOP is almost more of a mindset, and once you “get it” you’ll wonder how it ever seemed complicated or confusing.

Here’s what you’re doing well. You’re starting to break down items into sensible classes, i.e. concepts that are in your head which you want to program against and using the class structure to model them in code. This is excellent because it means that when you go looking for something you’re much more likely to be able to find it because your code really does mirror the way you really do think about the solution.

Another thing that’s great is I can see you giving that global variable the stink eye from here. Absolutely. Granted there are some cases where you may have to use a global variable, but they are slippery and its easy to write code (especially under modification) that ties into the global variable and does something unexpected that destroys code dependent on the global variable. These are especially nasty kinds of errors, because the common thread in the error is the global variable which is usually about the interplay of two pieces of code in radically different portions of the program that have no other seeming relation. Especially since you’ll be tracking down an error in one location and likely be unaware of the second piece of code. This is why developers don’t like global variables. I’ll use judicious class variables, but I’ll live with some pretty interesting gyrations to work around using a global.

Also, I can see you’re starting to get the idea of dependency. Dependency is a two edged sword. A lot that’s written about dependency talks about it as if it’s an unmitigated evil; that’s because it’s such a common problem. What you should realize is that there’s a good reason it’s a common problem, dependency gets things done, dependency is where the rubber meets the road and your code does work. You’re even doing things in what I consider the best practice way in this sense. Rather than subclassing object a or b to the other, you’re trying to use the functionality of one class for the benefit of the other (i.e. you’re composing them) Composition is much more flexible than inheritance. That’s definitely the way you want to depend on another class if at all possible. (That’s right, you heard it, I’m an OOP programmer who will only use inheritance if you put a gun to head. Composition is so much more logical and flexible that in most cases you use that instead. I actually don’t have any production code that uses inheritance at the moment, though I have stuff in beta that may bring it back again. Regardless, inheritance is definitely a rare technique in my code.).

The downside is that depending on a class reduces your flexibility compared to if you don’t depend on it. Depending on a class means that if there is a change in the public interface of the class, you have to rewrite not only that class, but modify every place in your entire code base that calls that class. Therefore, if you don’t HAVE to depend on a class don’t. If you can rewrite your functionality to eliminate a dependency, that rocks, do it. However, if you NEED to depend on a class to get work done, then you do it. For example, it’s much more important to encapsulate code into a utility function which is called all over your application than to “remove the dependency” by having the code repeated in all those spots. That’s jumping from the frying pan into the fire. The bad part of dependency is frequently that major changes to a class (i.e. changes that affect the public interface) require you make modifications throughout your code. On the other hand, using good encapsulation to promote code reuse means that the inside of the function is hidden away from the rest of the program. Instead of having the same block of code copied throughout your program, it’s only in one place; so while you program may depend heavily on it any changes that DON’T affect the public interface are now hidden away in that one location (i.e. you only need to make a change in one place instead of multiple locations).

All these are generally good OOP and fairly unimpeachable. These are also things that hopefully you’ll continue to do, they definitely represent good programming practices and those should continue to stand you in good stead. I will separate out my more individual remarks which more directly bear on your question; however, I find the biggest problem when asking for advice is figuring out what you’re doing right and shouldn’t mess with. That’s the most important part.

Hi…

Avoid globals.

Suppose you run a bit of code and it screws up?

If the code is like this…


function do_stuff() {
    $a = blah;
    $b = blah;
    return blah;
}

…then no problem. All your troubles are in those three lines of code.

If your code is like this…


function do_stuff() {
    $a = blah();
    $b = more_blah($a);
    return tedious_amounts_of_blah($b);
}

…then your problem is manageable. You make sure the three enclosed functions are behaving normally and that they interact correctly (I’ve omitted all the variable passing to make it look simple). You’ll figure out the problem pretty quick, as the bug footprint is limited to do_stuff() and it subfunctions. You can test each sub function separately just by passing the correct velue. You can divide and conquer.

Here’s something slightly more problematic…


class A {
    private $shared;

    function do_stuff() {
        $a = $this->blah();
        $b = $this->more_blah($a);
        return $this->tedious_amounts_of_blah($b);
    }
}

This adds the complication that the three methods can talk to each other via $this->shared. Not only do you have to check the parameters, but for testing you also have to set up each sub method before you call it. Still manageable, but more complicated. At least the declaration of $shared tells you it’s there.

Oh dear…


global $shared;

function do_stuff() {
    $a = blah();
    $b = more_blah($a);
    return tedious_amounts_of_blah($b);
}

Oh dear, now you’ve really gone and broken it :eek:. If the three subfunctions are using $shared, then is the bug caused by the code, or by $shared? If I want to test a subfunction, how do I know that the previous one hasn’t changed $shared? If $shared is set to the wrong value when it entered the code, who changed it? Now the bug footprint is the whole codebase. You’re only hope of figuring it out is reading the (now spaghetti) code and using grep to track down possible uses (a highly skilled and time consuming task).

At least I gave a big hint that $shared was a possible entanglement. Often you don’t even get this as a clue :(.

yours, Marcus

Hi…

Avoid globals.

Suppose you run a bit of code and it screws up?

Hmm, both of those replies seem to make sense - they certainly help my way of thinking. So, as every class (give or take) is going to require access to the database class, every class is going to need to have access to this - where as on things like users going into bookings I can pass in the requirements when I call the class from the action page - makes sense and is completely logical. One final problem I am having in this whole OOP thing when splitting the users up is the way users are handled. Obviously they (users) can be added, edited or deleted. But - I also have to handle user authentication. Is it worth having two, authentication and users, one and adding both methods or making a users class to do authentication and one class for a general ‘CrUD’ method? So far that is about the only place I have failed to split up my application.

Thanks for your continued guidance.

Hmm, it just doesn’t make sense to me. I have to do the same thing in a function that isn’t in a class by calling it a global.
Dependency, in code, yes, structurally, they aren’t - unless I am writing classes the wrong way. a for instance is a database class, whilst b is a user class. So b only needs a to run queries. Similarly, there is going to be a class for bookings - a user needs to be found / passed into the function, and it needs to write to the database / edit etc.
Am I splitting up my objects wrongly, or am I missing the point about the dependency?