PDA

View Full Version : I'm too obsessed with OO, is it good or what?!


ConfusedOfLife
05-20-2003, 02:43 PM
Hi, I feel that I'm going crazy. I'm trying to write everything as a class and I don't care for simplicity! I know that it's bad, but it seems that I hate functions and I can't work with them anymore! You know, I think we can not do much things with classes in a php script, coz the glue part of the program (the part that should take the $_POST vars and do the header stuff and ...) makes a great part of the whole script, but I'm still trying to write as OO as possible.

For example for a simple image upload program, that needs to get an image and a description from the client and put it in a db, I wrote 2 classes, that one of them inherits from the another. Here are my 2 classes:


class status_admin_utils
{
$returned_messages = array(
"method_1" => array(
"success" => array(),
"failure" => array()
),
"method_2" => array(
"success" => array(),
"failure" => array()
)
.
.
.
.
function status_admin_utils( $some_arguments )
{
# Some assignments
}

function read_db()
{
# reads the db

# put all the success/failure messages inside the $returned_messages["read_db"] array,
# that I can output output to the user (if I want) after running the method
}

function write_db()
{
# write into db

# put all the success/failure messages inside the $returned_messages["write_db"] array,
# that I can output to the user (if I want) after running the method
}

function manage_uploaded_images( $images, $descriptions, $dir_to_upload )
{
# copy the images into $dir_to_upload and then write their address/description
# into the db.

# put all the success/failure messages inside the $returned_messages["manage_uploaded_images"] array,
# that I can output to the user (if I want) after running the method
}

function delete_records( $records_ids )
{
# Perform the same thing, and puts the relative messages in $returned_messages array.
}

}


Ok, you might say that it's ok till now, but the problem is that I need to show the contents of the db to the users too. I t means that I have to write all the records to the browser and put a check box for each record. After the user checked some of the checkboxes and pressed the delete button for example, I have to get the id of those records ( that are the values of the checkboxes) and then delete them. So, I'm trying to do this with classes! I mean I show the contents of my db to the client by means of a class and I make all those checkboxes and their values by a class, then when the page is loaded, I check if $_POST vars is full, if yes, it means I should parse it and call the appropriate method. How do I do that? See:


class status_admin_manage extends status_admin_utils
{
function status_admin_manage($tableName)
{
# This is the name of my database table.
$this->tableName = $tableName;
}

function show_selectable_records($action_page)
{
?>
<form action="<?=$action_page?>" method="POST">
<input name="to_be_used_by" value="<?=$this->tableName?>">

.
.
.
.
<input type="submit" name="to_be_used_for" value="delete"><br />
<input type="submit" name="to_be_used_for" value="edit">
</form>
<?
}
}


So, now in the action page (where my form sends its data, it might be the current page too), I check for $_POST["to_be_used_by"], if it has the name of my database table, I instantiate an object of the previous class, then I check for $_POST["to_be_used_for"], so, for example if it is "delete", I call the delete_records method of my class. Writing like this, allows me to have multiple classes in one page, and I can always call the right class->method. So, what is your idea? Is it good or bad? I'm almost doing everything inside of my class, and I think I reached a kind of style for myself! If I write all my classes like this, then I'll be able to work with them even if 100 years passes! I don't need to read the glue part of the program to find out what variable I should use or what method I should call!

Thanks for your comments,
bijan

mordred
05-20-2003, 04:06 PM
If I write all my classes like this, then I'll be able to work with them even if 100 years passes!


I don't think so...
Your approach reminds me very much of my first OOP steps in PHP. Essentially, you are just programming procedural in one big class with a lot of methods, which pass enormous lists of parameters between them. Where's the OO beside that you put all your methods in two classes? There's a good rule of thumb: If your method/class name is something like util..., manage..., organize..., handle..., it's not good OO design. Why? Because the purpose of the class/method is not immediately visible. One of the great strength of OO is to componentize and decouple functionality to enable later modification and reuse.

I know it's extremely hard to see the different objects involved, but that's a skill that can't grasped at once but has to develop constantly and slowly. I'm still in the process though.

As an example, you could make an Image object. This image object contains all info associated with it: Size, Type, Name, Url, et. - also Id. And it could have some methods, like move(), save(), load(), delete(). Delete() would both physically delete the file and the records in the database. Compare that to your delete_records() method now - what if you want to accomodate a setup that stores image info in XML files? Either you live with a wrong methodname or you rename the method in your whole application, that would be errorprone and tedious. Not so if you've abstracted the way the how image information is stored in one delete() method.
Other classes could be FileUpload which creates the Image object, and a Database object. You also need some kind of Collection object that stores the uploaded files/managed images, and that could be passed to an Writer object which generates the HTML forms to interact with the user. These are just some rough sketches from the top of my mind, perhaps they provide some inspiration for you.

From my own experience, I can only advise you to spend a long enough time with the design of your objects rather than instantly hacking along. It will pay of in the long run. Also, think about the interface of your class - which methods do you design as public and which as private? Do you want to directly set the object's properties or employ getter/setter methods etc.

ConfusedOfLife
05-20-2003, 10:37 PM
Thank you mordred! I think I'm gettimg some points! But you said I have to have an image object, do you mean for each image I have an object? Better to say for each uploaded file I copy it into the db and the specified directory, then I create an object for it that I can move/edit/copy it, right? And then I need a Collection object to get all the db info and put it in an array or something that I can print it out, huh?

Well, first of all, how do you wana create those classes? Each class needs to have the db name/ username and password and it means that you have to pass them all to each object. Also how do you wana make your displaying object, the object that makes the forms and stuff? Doesn't class mean that you should be able to have 100 objects of the same class in one place (page) and they all run by each other? So, if you wana use fixed names for your checkboxes, radiobuttons, how would you recognize them later? Your page can only contain one object of that class and you don't need to use classes anymore.

Thanks for your help, what you say is really new to me!

mordred
05-21-2003, 12:34 AM
Hm, these are quite a lot of questions, anyway...

But you said I have to have an image object, do you mean for each image I have an object? Better to say for each uploaded file I copy it into the db and the specified directory, then I create an object for it that I can move/edit/copy it, right?´


Yes, each image could be represented by it's own object. An image in the real world is also an object, don't you think so? That does of course mean that there is only one class that describes the Image object. It should be quite general in its behaviour and properties.
I thought order of the process a little bit differently than you did:

1. Instantiate object by passing parameters to constructor (e.g. filename) depending on the uploaded files.
2. call move(dirname) to copy the file into the specified directory
3. call save() to store the relevant data of this image object in the database


And then I need a Collection object to get all the db info and put it in an array or something that I can print it out, huh?


That's not what I meant - see it like this: Your single Image object does not know of any other Image objects. You may need some kind of container that holds a number of image objects and invokes the methods. This could be the standard PHP array, they are relatively powerful. To abstract this container into a Collection object was only suggestion, not a requirement.


Well, first of all, how do you wana create those classes? Each class needs to have the db name/ username and password and it means that you have to pass them all to each object.


Not at all. You could abstract the interface to your database by creating your own Database object that handles connection and queires to your db. Only this class needs to know the user settings. From within your Image object, you need only a reference to your Database object to call it's methods that handle the queries. That enables you also to (theoretically) switch databases later by only exchanging the Database object.


Also how do you wana make your displaying object, the object that makes the forms and stuff? Doesn't class mean that you should be able to have 100 objects of the same class in one place (page) and they all run by each other?


I don't understand entirely what you mean... you could have 100, 1000 or just 2 Image objects active in your code, no problem here. Only the container that holds them would need to do something useful with them.


So, if you wana use fixed names for your checkboxes, radiobuttons, how would you recognize them later? Your page can only contain one object of that class and you don't need to use classes anymore.


Why not use variable names the for checkboxes? Say if you have instantiated an Image object and saved it to the database. You get a unique ID back and save that as the image's id by invoking the method setId(). Then you have a Output object. This object's purpose is solely to produce presentational markup (HTML) with information about those images you want to administrate. So you devise a method named generateFormFields() and pass an Image object, your code might look like this:

$str .= '<input type="checkbox" name="imageId' . $imageObj->getId() . '" value="delete" />';
$str .= 'Image name: ' . $imageObj->getName();
$str. = ', size: ' . $imageObj->getSize();

There's not really a need to hardwire the form field names into your code, let them be generated dynamically depending on the properties of the Image object.

Note: This is by all means not the only true path to pursue. It's just the kind of approach I would go around to design the application, and only quickly thought about. If it helps, my current task at work is to build an stock image database for a photograph agency, and steps comparable to what I wrote helped a lot to split the codebase up into reusable components. YMMV

ConfusedOfLife
05-22-2003, 09:24 AM
Thank you mordred, you put lots of time for me and I hope I can appreciate it by writing a real good class. You know, you totally changed my idea of a class. I'm much used to JS programming and in there, I always try to write things that I can easily instantiate and I don't need to write a glue for it. It's the reason that I told you doesn't a class mean that you should be able to instantiate it as many times as you want in one page. If you look at my code, you see that I can millions of it in just one page, because basically it has no glue! But now I understand that an object means a SEPERATE object, not something that does everything itself. If you use it in my way, then you are just making a bigger container, basically a bigger function that contains lots of other functions! The JS structure is totally different and when I write things, I deal with mathematics, but in here, we mostly have to work with sent/received data, that makes the glue part of program really big.

Ok, I try to work on it and I send a copy of my class scheme in here that you see I was a good student! But you know, when you don't have much time and you should prepare stuff for the company, it's not important for them (the customer + the boss) how you write, they just want it to work! So, just a simple question: Do you think that OO programming in PHP is good? I mean is it worth it? Because basically whatever we write is just used once in one page, it's not like JS that you make a menu class for example, then you make lots of menus with that class in one page. In here, you only get your data in the page you are, and work on it. There is no possiblity that you get other data from other pages or you can send several forms to one page! So, do you think that it's worth it? Putting all that time to seperate things, and then what? Is it really that re-usuable?

Thanks for your kind helps,
bijan

Weirdan
05-22-2003, 11:58 AM
2ConfusedOfLife

Because basically whatever we write is just used once in one page, it's not like JS that you make a menu class for example, then you make lots of menus with that class in one page.

Whatever you write, you mean ;). When you programming for the years you often see that tasks are repeating... After third or forth repeatition you implement this task as a couple of classes and then never repeat this work again. Later you coming to idea of "Design Patterns" (http://hillside.net/patterns/books/index.htm#Gamma)...

ConfusedOfLife
05-22-2003, 12:11 PM
Thanks for that link, it looks cool! Well, lemme be frank, after some month of programming in JS, I just got the idea of OO and now I'm really easier with OO in JS, better to say I can't write a function, or put it in another way, I hate to write functions! I make my classes and they work fine. It's not that I wana write a class, I don't think about it, it itself comes out. But in PHP, it's different! It seems that I couldn't get the idea of classes in here and the environment is so hostile in comparision with JS! So, as you said Weirdan, I think it's better that I start writing normal code for now (since I didn't write much things in PHP) and whenever I felt I need it, then of course I know how to write it! It's kinda my policy in life, don't do something because you have to do it (I know I have to do it one day!), just do what you want till you feel that you need that thing! Well, I'll use your books too, they look so promising.

ConfusedOfLife
07-03-2003, 02:02 PM
Now after 2 month that I'm back, I wana thank you mordred for your help. I did use your desing in my script and it really worked! Now that I look at my previous approach myself, I see how funny it was! Making a big thing that can not move, and you have to push it all the time isn't surely what OO mean. I really appereciate your help and I just wana announce that your efforts has paied off and now I (your student!) have a better look at OO.

Currently I'm using this classes for a simple data upload page:


Db Class: That holds all the info (username, password) about the db, and some methods like select( $fields, $conditions, $clauses ) , update( $fieldName, $oldContent, $newContent ) and so on!
Collect Class: That collects what I want from the database (of course by the help of the db class) and has some methods like getAllData, getAllDates and ...
Output Class: That outputs the data and also makes the insert/update forms.
Recieve Class: That receives the uploaded data and checks for my defined constraints and of course issues warnings, error messages in case of any problem.
Entity Class: Finally the object that is actually the real data, I can save it, collect it or delete it! This class has some methods like save, delete and update.


You helped me a lot, and it's really kind of ya. Now I understand that not only a scripter should know about the syntax, but the structures are very important too. Now I'm looking for some books and tutorials about this, because I feel that now I'm kind of addicted to your method! It means I really can not think of a web page without Collect, Db, Output and Receive objects! I know that it's just the beginning, but I wana find my own way!

Cheers,
bijan

whackaxe
07-03-2003, 05:16 PM
personnaly i can't see the point in OOP in php. could somone give me an example of where i would have to (or would be very much better off) use OOP?

mordred
07-03-2003, 06:59 PM
The reasons to use OOP in PHP are the same as for using OOP in other languages. Hint: Think about maintainability, modularity, namespaces.

firepages
07-04-2003, 02:16 AM
Originally posted by mordred
The reasons to use OOP in PHP are the same as for using OOP in other languages. Hint: Think about maintainability, modularity, namespaces.

... best remove namespaces from that list since php5 seems to have dropped them for now :(

mordred
07-04-2003, 10:33 AM
Yep, what a pity...
but I meant "namespace" in a rather general way, to minimize scope for functions, variables etc.

whackaxe
07-04-2003, 11:50 AM
what exactly is name space? php5 seems to be more concentrating on OOP than any of the previous releases and not much else. i still hope they'll build in some of the better extensions (and get the socket bugs fixed!)