Jump to content

Discuss - should classes ever call existing objects?


deadonarrival

Recommended Posts

I'm about to break rule #1 of forums by posting an "I read" with no URL, but I can't find it for the life of me.

 

Anyway, I was reading an article which was of the opinion that a class/method should never call any function outside of its own class. Ie no method/variable other than $this->variable/method(); (or if outside of object "mode" SELF::method()/$variable) should ever be called.

 

I thought it was stupid at first (I have calls to a DB object and ERROR:: static functions in my code which I use regularly... then I think to my work in other languages, and realise that often in PHP we don't BREAK THINGS DOWN enough.

 

The first thing I was taught in college when I started programming, was to break a problem down, then break it down again, then again, until you can't any more... and it works. In my last ever visual basic project, for example (and I'm going back now), I must have had dozens of functions, and scripts that actually do things.

 

In PHP I think we tend to try to do too much within one function, and it means we have to start referring to other things. Eg I made a function login(), then realised that it should really be several functions of checkUsername() checkPassword() checkActivated() setAuth(). And that checkPassword should be broken down into encrypt and then a comparison.

 

So my login.php script goes from

<?php
if(isset($dologin))
{
  $auth->login();
}
?>

 

to the aforementioned functions, and a script of

<?php
if(isset($dologin))
{
  $userinfo = $db->fetch_assoc("SELECT `password`,`activated` FROM `login` WHERE `username`='$var->cleanusername'");
  login($userinfo);
}
?>

Et voila no call to $db object in my $auth class, and I don't need to access $var either. It's a little more work to set up the functions, but some (such as checkUsername) can be used again... eg in a register script instead of checking for a username, I can use !checkUsername to make sure it doesn't already exist, the several functions can be used again if necessary.

 

I'm sure some people do code like this, but it seems to be something we're moving more and more away from in PHP, possibly because more and more people are coming to PHP from a photoshop+html background rather than an education involving programming from the ground up.

 

One thing I was told always stuck with me.

"If a procedure or function has more than 10 lines,  you can probably split it up and re-use some of it later"

 

Thoughts/opinions/shoot-downs?

 

(Apologies if this should be somewhere else, I'm not really asking for OOP help, but I don't know anywhere that would be more relevant - please move if I'm wrong :D)

~Audi

Link to comment
Share on other sites

I agree and used to do this a lot. I'm a new comer to OOP thinking so I was trying to cram all the functionality I need into one class. Then I sat back and after a couple complete rewrites, I found that the more I broke up the responsibilities in the code, the more everything flowed and the easier it was to organize and change the code.

Link to comment
Share on other sites

Yeah, another thing I thought is that we try to make everything belong to an object or class.

 

Why should my "authorisation" object try to decide whether a user is logging in or registering? It's taken me a while to realise that using OOP doesn't mean your entire script has to be part of an object or class, just that the objects do (shock horror!). Once I've started using some code back outside functions, it's become so much easier.

 

Just a few switch statements and function calls, and it's easier to see program flow aswell. 10 functions calling each other means I'm hopping about between functions like a madman, but

 

$userInfo = $db->query("get the users password+activated status");

$auth->checkUsername($user);

$pass = $auth->encrypt($pass);

$auth->checkPassword($pass,$userinfo);

$auth->authoriseUser();

 

With a few thrown exceptions, tells you exactly what order things are being run, in what order. Even just

$userInfo = $db->query("get the users password+activated status");

$auth->login($user,$pass,$userinfo);

 

with login containing the above 4 function calls, cuts out all the messing about with having to access other classes. I no longer have to try to get at $db from inside $auth, but all the functionality I needed is there.

Link to comment
Share on other sites

Mmm... not convinced.

It's a nice set of methods, and logic, but to be honest I think you're going to find it difficult to work with things like DataObjects, i.e. how would you change a users password?

 

Normally I would expect this:

$user->changePassword("new password here");

 

But by what you're implying you would do something like this:

$password = $db->query("update table <table> set password = '$newpass'");
$auth->changePassword($password);

 

The above method is taking the functional logic outside of the class (i.e. the update/insert), when really the class should be dealing with it. Let me know how you solve this problem. I'm more than willing to find great new ways to do things :D

Link to comment
Share on other sites

$info = $db->query("SELECT `password` FROM `user` WHERE `username`='$username'");

if($auth->checkpass($info))

{

//Password and old password match

}

$password = $db->query("update table <table> set password = '$newpass'");

 

I see auth as being functions to check the user is logged in, not update the database. Why should my authorisation access a database? Surely my database object is the one that does that - that's why it's the database object?

 

Auth is a bunch of functions to check things, db is a bunch of functions to change a database.

 

I actually think that accessing the database from within authorisation is wrong, since authorisation has nothing to do with the database... it's not what that object should be doing.

 

I might be looking at it completely the wrong way - I guess the auth isn't accessing the database, it's just telling the db to - but I'm trying to work out how to do it all without extending every class when it shouldn't be extended, or using a huge number of singletons, or having to pass objects as variables to functions.

 

Link to comment
Share on other sites

That's so stupid to include queries in any place but an encapsulated object.

 

Your client code should NOT CARE where the data comes from, so it can easily be switched out in case requirements change, the implementation changes, whatever. Testing a single instance of an object INSTEAD of the entire client is so key when you re-visit an app(or portion of an app) you haven't worked on in a while.

 

You can program however you'd like, but NO THANK YOU. If you never have to maintain or change your software, then god bless you and congrats.

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

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.