The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

It's time to take the OOP plunge

I've been focused on php for about 2 years now from an absolutely non-programming background. I think my procedural php is coming along ok, I have dealt with most typical functions of a php driven site... eg. user authentication, database integration, general security, file handling, emailing, image manipulation, and all those smaller things that make it all work.

But I have this feeling that something better is just around the corner, and at my stage that must be OOP. I don't exactly want to change direction I just want to do the same stuff better.

So I thought bugger it, I might as well take the plunge now and try OOP.

The project in mind is basically a directory website with email marketing laid over the top. Procedurally I can and have previously done similar stuff so the only major challenge is the change in technique.

Here's how I am thinking about approaching the project... allow me to wow you all with my caveman knowledge....

Code Layout:
Usually I have one or more functions files that contain all my common functions. Where a page requires something to happen, like retrieve a GET id or update a database row, I layout what I want to happen in a procedure at the top.
eg.

or basically any tangible element that will have associated behavior (functions).

File Structure:
I will hopefully find that the bulk of my functions.php will now be embedded in classes in classes.php.... this is essentially why OOP rocks because most of the code is all pointing to the same central engine room.

Number of Lines:
The major decrease should be a result of less repetition across various .php pages that do similar tasks. There should be less code embedded in the "webfront" pages and more going on in pure php pages.

Shift in Logic
My current logic is... "it makes sense to build heaps of functions because I often will repeat something and I can just call a function instead of re-writing the procedure."
For example one of the most recent functions was

In OOP, when I want to check if a record exists, not much will change except that I will have to work out how to make the function accessible inside a class (if it isn't automatically global). If I wanted to really push my luck I might make a SQL class and incorporate that... Functions are perhaps step one to code centralisation, classes are step 2.

For all you guys and girls who already have gone down this road, please add your comments and advice... if any of my above logic is flawed, please point it out so I may ingrain the right thinking while i'm still impressionable

One of the key differences between procedural and object oriented, is that objects encapsulate entities, while in a procedural approach, you separate functionality from data. A primary key id is an excellent example of the difference; With procedural code, you would have a function, which you invoke, passing the identity of the entity (the primary key) to the function. In an OO approach, the identity would be encapsulated within the object. So the above example is bad OO, because you pass the id to the post instance. A better solution is:

PHP Code:

...$id = (int)$_GET['id'];

// lets say i'm changing a blog post$object = new post($id);

switch ($action) { case 'delete':$object->deletePost(); break; }...

Now, your object instance represents a blog post. Try not to think in classes, but rather in object instances.

Thanks for that, surprisingly I do understand what you mean, the main point that this post object now has an identity, and can be used and reused (in this example for other potential switch cases like update or insert) without continually passing the $id.

Also if it's at all relevant in my approach to learning OOP, my planned usage will be focused on various web applications where I would like to have identical or near identical classes that are shared. The main benefit I see are -
a) I can now literally drag and drop a class into an application with little to no modification
b) When I learn new things I can update my complete web software base with relative ease

Well, since you have already worked with PHP in the procedural sense, if your serious about learning OOP, I highly recommend you get a copy of the book Head First Java. It is the best book for learning OOP inside and out.

All the books that I have found on PHP & OOP, just cover the very basics of OOP and php i.e. syntax, classes, constructors etc.

If you read the java book, you'll have no problems with all the concepts of object oriented programming which can be applied to PHP, Java, C++, Objective-C or whatever language you opt to use now and in the future. In addition, you will be be pretty much prepared for PHP 6.

Just to slightly get off topic, how similar are ASP.NET/JAVA/PHP OOP? It seems the OOP logic is basically the same in any language... are the syntax differences extreme or not?

PHP's object syntax is highly inspired by Java. You should be able to translate 1:1 between the two, except for a few esoteric constructs. ASP.NET is an umbrella of several languages, hereunder C#, which is also heavily inspired by Java.

Just to slightly get off topic, how similar are ASP.NET/JAVA/PHP OOP? It seems the OOP logic is basically the same in any language... are the syntax differences extreme or not?

Yeah, from my suggestion, I'm recommending that you learn the concepts of OOP then use any language such as PHP to implement those concepts. Most all languages are nearly identical when it comes down to basic syntax. for(), while(), next(), if(), <, >, true, false -- for instance are present across the board.

just ordered Head First Java... was a right pain to track down, none of the local bookstores I contacted had it in stock and I had to order online... too bad its now thursday, gotta wait till next week till it arrives.

so hopefully this book will give me the best possible foundations... then I will begin looking specifically at how to do it all in PHP.

just ordered Head First Java... was a right pain to track down, none of the local bookstores I contacted had it in stock and I had to order online... too bad its now thursday, gotta wait till next week till it arrives.

so hopefully this book will give me the best possible foundations... then I will begin looking specifically at how to do it all in PHP.

Well, sounds like you now have a plan. I find it takes me a long time to figure out "which way" to proceed when learning a new language or technology. I hope it works for you as well as it has me & good luck.

get, set and privacy

the point to getters and setters, is that you can change your mind later, without breaking anyone else's code!

Hide the data
it is that simple to go from an implementation that's just begging for bad data to one that protects your data and protects your right to modify your implementation later.

Therefore:

Make instance variables private
make getters and setters public

is this equally true for php? I remember a few weeks ago a class that had a bunch of get and set functions, and I thought it was ridiculous - but then, I hadn't read anything like the above quote either!

and this is a kindof similar question that I might as well throw in: obviously php is more flexible with variable types, it doesn't force (or even allow?) you to declare the variable type.... eg.

Code:

// java
int x = 3;

PHP Code:

// php $x = 3;

however, it seems to make sense to force the data type in a method, such as:

PHP Code:

function deleteRecord((int)$id) {

this generates a fatal error in php... is there actually a variation of this that would work (short of forcing the data type within the method?)? It seems to make sense to ensure you have an integer straight away rather than validating inside the method.

(1) Always use getters and setters. Classes are supposed to encapsulate something. With an interface.
(2) Never use private, protected or final. They don't actually do anything except add clutter.
(3) Never use type hints unless there is a genuine need for the code to know something about itself eg dependency injection. More java-esque verbosity which you can safely ignore.

however, it seems to make sense to force the data type in a method, such as:

PHP Code:

function deleteRecord((int)$id) {

The immediate problem with that would be; what happens if you pass a string that represents a number? Should it fail, or should there be a conversion? What about if you pass a float? Unlike objects, primitives are easily and regularily co-orced into different types, which makes type hinting with primitives very complex.

The other issue is, why limit deleteRecord to only take an int? Instead of trying to limit what types functions and methods can take, why not design them to take multiple types? In this case, an array of ids, or a record object? Duck typing is somthing that should be seen as a benefit, not a liability.

That's not at all what was suggesting, and I don't even know what you mean by "two problems". What I meant was something like:

PHP Code:

function deleteRecord($id) { if (!is_array($id)) $id = array($id);

foreach($id as $i) {// delete $i}

}

Yep, I know what you are suggesting, I've been tempted with doing the same as well. But, you have to resist temptation I think a function should never try to outsmart the programmer. It should be strict and not cleaver.

I would append the word "Array" to the $id to let the programmer know that he needs to pass an array, and also using code I would force him to pass an array. Then, it's up to him to do: array(1), or array(1, 2). Because another programmer may come along and will see: $id = 1 and in his mind $id is an int, and does not associate that variable with an array. Then he sees: $id = array() and he knows that there's something wrong. So you are forcing the programmer to think, and that's when the function outsmart the programmer.

PHP automatically converts between int, float and string. That's not a problem -- that's a feature.

Yes, I see that as a feature as well. I was referring to the example above. For example:

If you don't force the parameter to be an array, you'll have to add extra complexity to the function. And since a value of an array can be of any type, you'll need to check the values one by one. So in this case, PHP doesn't convert the parameter $idArray automatically nor the values of the array.

But I think you were trying to make a point about something else, and I agree with you, no doubt about that.

Yep, I know what you are suggesting, I've been tempted with doing the same as well. But, you have to resist temptation I think a function should never try to outsmart the programmer. It should be strict and not cleaver.

It's not a question of trying to outsmart the programmer, it's a question of being more accommodating, and therefore more useful. It's a form of polymorphism, the ducktyping equivalent of the method overloading offered by statically typed OO languages.

The _getOption() method accepts mixed parameters, so you can pass a NULL value or an array. And then everything gets converted to an array? Then the _resize() methods accepts mixed parameters for both arguments, and almost everything in this class accepts mixed parameters...

The _getOption() method accepts mixed parameters, so you can pass a NULL value or an array. And then everything gets converted to an array? Then the _resize() methods accepts mixed parameters for both arguments, and almost everything in this class accepts mixed parameters...