A newbie question regarding php classes

Mark Brady
Mark Brady used Ask the Experts™
on
I consider myself an advanced php developer and have been developing large commercial websites for the last 3 years, all without learning PHP's "classes". So far, I have gotten away with writing nice neat code all very well notated and used functions and lots of "includes".

Recently, I decided to dive into learning about OOP (object orientated programming). Although I have much to learn I am getting the hang of it after doing a few easy tutorials. I am however confused by a couple of things. If someone could help make these clearer I would be very happy.

Consider the following class.

<?php
class Bike {
var $Make;
var $Model;
var $Size;
var $Year;
function __construct($Make,$Model,$Size,$Year){  
$this->Make = $Make;
$this->Model = $Model;
$this->Size = $Size;
$this->Year = $Year;  
}
function get_make() {
return $this->Make;
}
function get_model(){
return $this->Model;
}
function get_size(){
return $this->Size;
}
function get_year(){
return $this->Year;
}
// end of class
}
?>

// I have made this file as small as possible so please ignore the non notation and indents.

In one tutorial, It stated to NEVER access the classes objects directly. Consider this.

<?php
include("bike.class"); // the class I created above
$bike = new Bike("Yamaha","FJ1200","1200cc","2010");
print $bike->Make." ".$bike->Model." ".$bike->Size." ".$bike->Year;
?>

Now why is it bad practice to access the classes objects or variables directly?
$size = $bike->Size;

As opposed to

$size = $bike->get_size();

This line would be shorter to both type, and for the server to read
print $bike->Make." ".$bike->Model." ".$bike->Size." ".$bike->Year;

Than this line

print $bike->get_make()." ".$bike->get_model()." ".$bike->get_size()." ".$bike->get_year();

So if it it much quicker and cleaner looking is it really bad practice to use it like that?

Another question is, if I remove the vars from the class code above (var $Make ...etc) the code still runs fine. So if the code still works without declaring the variables, why do we need to declare them at the top of our class file?

Finally, why is this class so much better than just including a file with a bunch of functions in it?

Any help would be appreciated and also if you know of good class tutorials please post them. Thanks in advance.


Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Mohamed AbowardaSenior Software Engineer

Commented:
You need to take instance from the class to access it using "->", otherwise you will have to create static class and static variables and methods to access it directly using "::" (i.e: myClass::staticVarName).
Most Valuable Expert 2011
Top Expert 2016

Commented:
Wow, this is a lot of questions!  Much of it is stylistic, as you may have concluded already.  When you create classes that in turn instantiate objects and you expect these to be used by others in programming, "encapsulation" is an important concept.  Your example here uses a constructor to assign the variables and uses either "getter" or direct reference to retrieve the variables.  Does that description of the example offer any hints of the reasoning behind the concept of encapsulation?  

It's not a simple concept but the results become apparent when the designs include large amounts of code and there are a lot of variables.  With little examples the "overhead" of OOP seems significant.  In practice the overhead disappears and the advantages come into focus.
Mark BradyPrincipal Data Engineer

Author

Commented:
Thanks to both of you for your replies. I don't follow what you are saying Medo3337. My question really is

1: Why is it unsafe to access a classes variable directly, rather than accessing it through a classes method/function ? ie: $name = $myclass->Name; as opposed to $name = $myclass->get_name();

Ray, what are you talking about "encapsulation"? What has that to do with my question? Sorry but I'm not following you and usually I follow you well! I do understand your final paragraph however.
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

Juan OcasioApplication Developer

Commented:
It's just good programming practice to make your variable inaccess from the outside.  Take for example:

<?php
$MyBike = new Bike("Ford","Explorer","4 door","1996");
echo $MyBike->get_model();
$MyBike->Model = "Expedition" ;
echo $MyBike->get_model();
?>

This will of course echo out

ExplorerExpedition, right?  However  what if later in your code you continue to modify the variable and other variables outside of the class without using the setters and getters?  Eventually your code would be practically unreadable and you won't be able to follow the logic.

Ray's referral to encapsulation has everything to do with the question, because the idea behind oop is just that:  restricting access to some of the classes components, namely the variables, and the only allowing for that access through the use of methods.
Mark BradyPrincipal Data Engineer

Author

Commented:
Hi jocasio123:

So what you are saying is if I was NOT going to modify the classes variables then accessing them directly without using the "getters" or functions inside the class would be ok but it is better coding practice to always use the setters and getters? That makes sense. Is that what "encapsulation" is all about encapsulating items inside a class?
Juan OcasioApplication Developer
Commented:
Encapulation is the the idea of associating all methods and variables related to a 'thing' together and restricting the access to those methods and variables.  It is just common (and good practice) not to allow your variable to be modified or retreived directly.  Even if you are not modifying the variables, you should always use getters.  Think of it this way:  suppose you have a variable where the data should never change.  Sure I can access it by saying

echo $MyBike->Model;

What what stops me ffrom modifying the data???  Nothing.  Even if you never wanted to modify it I can also do this:

$MyBike->Model = "Expedition";

Of course this is a very simplistic example, but the idea is that you want full control of what and when you data can be modified.

HTH
Commented:
Hi sir,

First of all, all your questions can be answered by this, "for better organization of codes", which is the purpose of implementing Object Oriented Programming.

1.) why is it bad practice to access the classes objects or variables directly?
 - implementing this restriction will make sure your class data is being well-maintained and at least in the programmers side it will remove the worry about the inconsistency of the class data since all the data access pass through class methods.

2.) if I remove the vars from the class code above (var $Make ...etc) the code still runs fine. So if the code still works without declaring the variables, why do we need to declare them at the top of our class file?
- yes, you may not declare the property/variable but for the default value purposes you need of course to declare it. Also, as i've said for "code organization's sake" this is very important especially in a team development.

3.) why is this class so much better than just including a file with a bunch of functions in it?
- again, for better "organization" of functions or methods, you should group related functions and assign it to a certain class.

That's why this encapulation concept is being invented so that all your codes will have a structure. Structured means organized.

Of course you have the choice to ignore these good practices but one thing's for sure, when your application gets bigger and bigger and more codes to maintain, you will be having a hard time dealing with it.

Hope that helps... Have a good day...
Top Expert 2004
Commented:
I'll contribute my $.02 as well. More perspectives may help you understand better, and if at any time the terminology becomes confusing, let me know.

Like the other experts before me, I'll talk a little about encapsulation. This broad idea includes the use of getter and setter methods to change the state of private instance variables. Of course, some private variables should not have a getter or a setter. Maybe those variables are completely internal, or maybe you only want them set once through the constructor and never changed. Those will be your design decisions.

But some variables have both a getter and a setter that do nothing extra (especially in beginning OOP tutorials). For those variables, why should we not make them public? Actually, we can! Sometimes we don't want the bulky notation of a getter and setter. For example, in Java, the Point class has two public fields x and y. It makes sense because p.x and p.y look much cleaner than any method call, and the x and y values literally need no setters to maintain constraints.

However, in most cases, we do want the insurance of a getter and setter. This is especially true when working on a large project, a team project, or a library. Many times we will want to validate what the user attempts to set. Perhaps it should be a positive number, an existing file, or whatever. Perhaps we want to log invalid attempts to set our variable. Even if we don't do it now, we may want to do it later. Forcing people to use the setter from the start means we can build this in later without breaking already existing code.

There are two main arguments against this philosophy. The first argument is that there is a performance cost from calling getter and setter methods. This is unavoidable, an example of the trade off between extendable, safe code versus absolute speed. Like Ray has said earlier, we most often prefer the former. The second argument is that it produces ugly and verbose code. This is an issue that some programming languages are addressing. For example, C# uses the syntax of properties, which are implicit getter and setter methods. PHP 5 itself provides magic getter and setter methods, although I do not think it is or is intended to be a good solution to this issue. Your mileage will vary.

I have merely reiterated what others have said. Getter and setter methods are for programmer peace of mind, and a way to place constraints on how other people (including future you) use your code.

Next, we might wonder why people suggest defining instance variables at the top of a class with var or, in PHP 5, the access modifiers private, protected, and public. Code works just fine without it (PHP is a very dynamic language), and we may even be consistent in setting everything dynamically in the constructor. Here are some reasons why you want to define your variables at the top anyway even though it is not necessary:

It produces more readable code, in the sense that years down the line you will know exactly what instance variables you are using from looking at the top of your file.
PHP will display a warning if you use an undeclared instance variable, which you can see and/or log by using error_reporting().
In PHP 5, an undeclared instance variable automatically has access modifier public, which often is not what you want.
Many PHP programmers are also people who program in languages like Java or C++, for which declaring variables is both necessary and convention. They may be more comfortable with that style of OOP.

Finally, we come to the question of why a class is so much better than a bunch of files. Like others have said, it's for better organization. This is easy to see. An object can carry its fields and methods with it as it is passed around in the program. Suppose we were not programming with classes. Then what would we use to group "fields" together? We could use an array in PHP (in a programming language like C, we could use a struct). But arrays then do not come with the features of getters, setters, and so forth.

Another important organization feature of classes is allowing duplicate names for common methods. Suppose we were programming in a non-OOP language like C. Let's say we have defined a queue and a stack as structs (grouped fields). We would like to initialize these, so we write the functions queue_init() and stack_init(). Both queue and stack have a notion of pop and push. We would then write queue_pop() and stack_pop() as well as queue_push() and stack_push(). With more structs, we need more functions, with more names. Classes provide a simple form of name organization which is very helpful for large programs. Sometimes classes are not enough to organize names. Java provides the notion of packages to organize classes. Other languages, including PHP, provide the notion of namespaces to organize a group of names (including class names).

In the end, classes also provide a great form of logical organization. I find it easier to understand code when I can break a project into classes that do this and classes that are responsible for that. It's no longer a big program with functions grouped together only by common names (enforced only by programmer discipline). It is a logical division of responsibility (something only possible by classes because they can contain simultaneously (read: encapsulate) data in the form of fields and behavior in form of methods that operate on those fields.
Most Valuable Expert 2011
Top Expert 2016
Commented:
I think Zyloch said it pretty well.

"Encapsulation" is the process of storing code and data inside a logical capsule.  That capsule is the object that is created from your class definition.  Consider what we had to deal with in non-OOP PHP.  You had a code definition that usually contained some main stream of code and also contained some function definitions.  The main variable scope was not available to the functions and the functions' variable scopes were not available to each other or to the main scope.  You could pass information from the main scope into the functions via calling arguments and you could pass information from the functions back into the main scope with return().  If you wanted to share information between the main scope and the internal workings of the  functions, you had $GLOBALS (an array) and the global declaration that changed the way variables were perceived - in the entire script.

Now let's imagine that you and I are collaborating on a project.  We are many hours apart in different timezones and each of us needs to work independently.  This happens in a lot of open-source collaborations.  Let's say you decide to use $name for a variable in one of your functions, and I decide to use $name in one of my functions.  So far, so good - the function definition encapsulates the $name variables separately.  But now let's say I decide I really need access to $name in the main code stream, so I add global $name to my functions.  I just broke the encapsulation and in the process, I also broke your code.

This page has links to a lot of good reading material.
http://us3.php.net/manual/en/language.oop5.php
greetings elvin66, ,
I believe you are trying to find truth in some over stated generalizations, that are commonly given about object oriented organization in Classes, in some of the many tutorials on the web.
In my view there are no inherent advantages to either object oriented or function oriented coding styles, EXCEPT for the advantages felt by the person using the code of that style. Meaning, that placing function code into a Class does not make it better code. In your example there are no functions, and absolutely no "dependencies" on any of your class variables, so (in my view)  the code block in your example can have no real way to evaluate your statement of -
"Now why is it bad practice to access the classes objects or variables directly?"

it is not a matter of bad practice, but if your class code will not function correctly if you change the $this->Model variable with an "outside of the class" call to -
$bike->Model = 'this incorrect string input will cause an exception or error';

however there are times I allow direct access to class variables (as a public variable), if it makes no difference if the class will continue to function, no matter what the user places in it.

in your example code there are just a few lines, for me I really do not consider using a class until there are several hundred lines of code or more, and I feel that grouping some of the code together in a class or two will help me in my mental analysis and the way I think to place and look for code that is used, as in code for database (look in the database class), code for images (look in the image class) or code for REST responce (look in the REST class).

but if you personally, do not feel any advantage to OO or function code , then for you there is no advantage, no matter what the tutorial says.
Most Valuable Expert 2011
Top Expert 2016

Commented:
placing function code into a Class does not make it better code

Amen, Slick812!
Mark BradyPrincipal Data Engineer

Author

Commented:
I want to thank you ALL very much. Your explanations (all of them) have given me a very clear picture of the advantages of OOP. I went from writing very long scripts to placing lots of my code in functions and including large blocks of code when/if needed and that really tidied up my code and made debugging so much easier and faster. Always on the lookout for knowledge I was considering if I should make the effort to learn OOP and now I have read your explanations on the various aspects of OOP, I have decided to jump in feet first!.

I only wish I had learned OOP before a huge project I have just finished for a big client. Debugging that one takes a big chunk of my day. Once I am comfortable with writing classes/constructors and getters/setters I will use it with the next project I get. Thank you all so much. Once again, I knew I could rely on my friends at EE. I have help many many people (like most of you have) on EE and don't ask to many questions myself but I have just spent my 3 days vacation time reading tutorials on OOP with PHP and I must say I was little more than none the wiser. I had many questions as the tuts I read were poorly written in my opinion.

This thread has changed that and I would recommend any newbie to OOP to read this to gain insite.
Thank you thank you thank you. Everyone deserves the points but I'll split them. Have a great day/night from New Zealand!
Mark BradyPrincipal Data Engineer

Author

Commented:
I'm am very happy to now be able to move into OOP with
PHP and expand my knowledge of this wonderful language. EE is by far the best place to learn and we NEVER EVER stop learning.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial