# My first somewhat meaningful class for length conversions

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
I've been a procedural PHPer for a while now and I don't know why it
has taken me so long to start the jump from procedural to OOP.  I have
a function that I would use for doing length conversions... feet to
meters, inches to centimeters,  etc... and I wanted to try and turn
that into a useful class just for some OOP practice, but I don't think
it was a very good start.  Maybe it was a bad function to begin
with... but I'm not seeing how this class is of any more use if any
than the function was on its own.  What are the advantages of turning
that into a class and how could I improve it to make it better?

#################################
## Original conv function
#################################
function conv(\$val, \$lenFrom, \$lenTo) {
switch (\$lenFrom) {
case 'm':
\$m  = \$val * 1;
\$cm = \$val * 100;
\$mm = \$val * 1000;
\$ft = \$val * 3.2808399;
\$in = \$val * 39.3700787;
break;
case 'cm':
\$m  = \$val * 0.01;
\$cm = \$val * 1;
\$mm = \$val * 10;
\$ft = \$val * 0.032808399;
\$in = \$val * 0.393700787;
break;
case 'mm':
\$m  = \$val * 0.001;
\$cm = \$val * 0.1;
\$mm = \$val * 1;
\$ft = \$val * 0.0032808399;
\$in = \$val * 0.0393700787;
break;
case 'ft':
\$m  = \$val * 0.3048;
\$cm = \$val * 30.48;
\$mm = \$val * 304.8;
\$ft = \$val * 1;
\$in = \$val * 12;
break;
case 'in':
\$m  = \$val * 0.0254;
\$cm = \$val * 2.54;
\$mm = \$val * 25.4;
\$ft = \$val * 0.0833333333;
\$in = \$val * 1;
break;
}

switch (\$lenTo) {
case 'm':
return \$m;
break;
case 'cm':
return \$cm;
break;
case 'mm':
return \$mm;
break;
case 'ft':
return \$ft;
break;
case 'in':
return \$in;
break;
}
}

// one foot... convert it to inches
echo conv(1, 'ft', 'in');  // returns 12

// 24 inches... convert it to feet
echo conv(24, 'in', 'ft');  // returns 2... well, after you round
it is 2

###################################
## My attempt at converting it into a class
###################################

class Conv {
var \$m;
var \$cm;
var \$mm;
var \$ft;
var \$in;

function conv(\$val, \$lenFrom, \$lenTo) {
switch (\$lenFrom) {
case 'm':
\$this->m  = \$val * 1;
\$this->cm = \$val * 100;
\$this->mm = \$val * 1000;
\$this->ft = \$val * 3.2808399;
\$this->in = \$val * 39.3700787;
break;
case 'cm':
\$this->m  = \$val * 0.01;
\$this->cm = \$val * 1;
\$this->mm = \$val * 10;
\$this->ft = \$val * 0.032808399;
\$this->in = \$val * 0.393700787;
break;
case 'mm':
\$this->m  = \$val * 0.001;
\$this->cm = \$val * 0.1;
\$this->mm = \$val * 1;
\$this->ft = \$val * 0.0032808399;
\$this->in = \$val * 0.0393700787;
break;
case 'ft':
\$this->m  = \$val * 0.3048;
\$this->cm = \$val * 30.48;
\$this->mm = \$val * 304.8;
\$this->ft = \$val * 1;
\$this->in = \$val * 12;
break;
case 'in':
\$this->m  = \$val * 0.0254;
\$this->cm = \$val * 2.54;
\$this->mm = \$val * 25.4;
\$this->ft = \$val * 0.0833333333;
\$this->in = \$val * 1;
break;
}

switch (\$lenTo) {
case 'm':
return \$this->m;
break;
case 'cm':
return \$this->cm;
break;
case 'mm':
return \$this->mm;
break;
case 'ft':
return \$this->ft;
break;
case 'in':
return \$this->in;
break;
}
}
}

\$conv = new Conv;

// one foot... convert it to inches
echo \$conv->conv(1, 'ft', 'in');  // returns 12

// 24 inches... convert it to feet
echo \$conv->conv(24, 'in', 'ft');  // returns 2... well after you
round it is 2

###############################################################

Well... I guess I can see ONE benefit.

When converting the 24 inches into feet above:
echo \$conv->conv(24, 'in', 'ft');

I can go back and get millimeters for the 24 inches:
echo \$conv->mm;  // returns 609.6

or centimeters for the 24 inches:
echo \$conv->cm;  // returns 60.96

etc... without having to resend the '24' inches to the conv method in
the Conv class each time as long as the inches value doesn't change.
So essentially I can send the 24 inches once, and I've got the
converted numbers for feet, meters, centimeters and millimeters at my
disposal without having to send the 24 inches again each time.

What other benefits are there other than that though?

I'm totally green when it comes to OOP so you can totally rip that
class and tell me how you would improve it if you've got the time and
would like to share.

Thanks guys!

IBB

## Re: My first somewhat meaningful class for length conversions

oh.i.love.spam@gmail.com escribió:

improvement you could add to your code is arrays. Hardcoding data in the
middle of your scripts tends to be hard to maintain.

(*) I hope you don't believe all those folks who claim that PHP will
suck until it becomes a copy of Java. Object-oriented and procedural
programming are just two approaches to choose from when face to an
specific need.

--
-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programación web: http://bits.demogracia.com
-- Mi web de humor al baño María: http://www.demogracia.com
--

## Re: My first somewhat meaningful class for length conversions

oh.i.love.spam@gmail.com wrote:

Essentially, not a lot of advantage for the way you have it.

Back to basics.  Variables have states - they remember things.  \$i is a
typical variable - by itself it doesn't "do" anything.

Functions have behavior - they do things.   printf() is a function - it
does stuff, but once the function call is complete, there's nothing left
from that function.

Variables don't do anything on their own (no behavior), and functions
don't remember things (typically, at least).

Objects have both state and behavior.  They remember things like
variables, but can do things.  The class defines the objects state and
behavior, and the object is an implementation of the class.  mysqli is a
typical database object is a typical example - it can open a connection
to the database and perform operations on the database like functions,
but also remembers the database connection and other information like a
variable.

In your case, you're probably doing a lot of unnecessary conversions -
do you need every unit every time?  But that doesn't mean it's not a
candidate for an object.

What I would do if I were making this an object is have functions such
as set_m(), set_cm(), set_ft(), etc.  Store the value in a private
variable in whatever unit you want.  Then have the equivalent get_m(),
get_cm(), get_ft(), etc. functions to retrieve the information in the

And variables are part of your implementation - they should almost
always be private, occasionally protected but very seldom public.
Anything public can never be changed without potentially affecting an
unknown amount of other code - which is what OO is supposed to help limit.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================

## Re: My first somewhat meaningful class for length conversions

Good info guys... thanks!  I've no idea when to make something public
or private or static or protected.  I need to find a good book/
resource on just OOP in general and theory I think.  I've got a couple
of general beginner tuts that I'm sure will get me to a point... they
give a lot of the "how" but not necessarily the "why".

Any good resources you would recommend?

Thanks again!

IBB

## Re: My first somewhat meaningful class for length conversions

oh.i.love.spam@gmail.com wrote:

General:

PHP specific:

--
Rik Wasmus
...spamrun finished

## Re: My first somewhat meaningful class for length conversions

oh.i.love.spam@gmail.com schreef:

Hi,

Many Java programmers had the opinion that *ALL* variables in your class
(which are called 'members' then) should be private. In the case you
want the user of that object to change them, expose a getter/setter
method for it.
But you'll easily find others who disagree and say all the getter/setter
methods are a pain and unneeded noise brought to you by the Code Mafia.
Why make a member private if you expose it again with a getter/setter
method?
What I want to say is you'll find a lot of differing opinions on the
'why' and 'how'.

Best thing to do for you is simply learn how things work in OOP, and
And test a lot.
Simply make a class, with public vars, and private vars.
Can you access them?
Then expose the private var via a getter/setter. Do you like that, or do
you think it is codenoise?

A rule of thumb I used (in Java) for choosing between private or public
and offer a getter/setter) that are of direct interest to the coder
using my class.
For example: A class that fetches some article and related info from a
database.
The variable for setting the ID is public, then calling the
fetch-routine would get that article.
But the variables I use for database connection, errorhandling, looping
over resultsets, etc is all private. Why would the user of my class care

Static and protected are completely different concepts.

Best thing to do is buy a good book. :-)
Since I don't know which PHP books are covering OOP well, I won't give
(I always found www.php.net sufficient, but I knew OOP already.)

Or get a general idea from wikipedia:
http://en.wikipedia.org/wiki/Object-oriented_programming
That article contains a lot of usefull links, and will touch a lot OOP
jargon.

If you feel really brave, you can dive into some PEAR classes and see
what they are doing.

Just my 2 cent.
Good luck.

Regards,
Erwin Moller

## Re: My first somewhat meaningful class for length conversions

Erwin Moller wrote:

There is a reason that's very important for this: tracing & validating
and listeners. While I don't make everything private, most of them are,
certainly if I need to validate them (throw exceptions on errors), and
the ability to deploy listeners to trace certain problems (add observer
to object, an change report where which change came from etc.). Not
needed for small projects, but for bigger ones with a lot of interaction
it's not only wise, it saves a terrible amount of time while bughunting.

possible, altering isn't. If not working with getters & setters, and you
need a read-only variable, the only other option is to use a method
rather then a variable, in which case you might as well code a getter
(and possible exception throwing setter).
--
Rik Wasmus
...spamrun finished

## Re: My first somewhat meaningful class for length conversions

oh.i.love.spam@gmail.com wrote:

I tend to make almost all of my variables private, with get and set
functions for them.  The set function returns true or false, depending
on the validation of the parameter.

Now maybe every variable doesn't need validation *now*, but who knows in
the future?  Making the value private allows for expansion when things
change.

The whole idea of OO is to separate the interface.  The interface is
what's publicly available, typically public methods(functions).  The
implementation includes the private/protected variables and the code in
the methods.  Once you've published the class, you can't change the
interface (except to add to it) without potentially breaking code.  But
you can change the implementation as much as you want, as long as the
interface performs the same functions (as seen externally) and returns
the same value(s).

It's a little harder to code and very slightly slower, but much more
manageable in the long run.

A floating point number could be considered a good example of an object.
Internally, it is stored as base and mantissa.  But you don't access
that information; rather you perform operations such as add, subtract,
print, etc. on it.  If you change to another processor which uses a
different method of storing the number (i.e. a mainframe with a real
binary coded decimal feature), your code doesn't change.  And neither do
the results (except for rounding errors).

An example I did not too long ago.  Customer needed a small program to
keep track of a few names/addresses (a couple of dozen).  Unfortunately,
the (free) server they were on didn't have MySQL available, and the
needs were minimal - mainly be able to update and display the
information.  So I implemented it as a CSV file using a database class.

Later, when they changed to a real hosting company with MySQL, I changed
the database object to use MySQL.  The class had to be rewritten (not
that much, really), but the rest of the code didn't change at all.  And
I could change the database class to use PostGresSQL, SQL Server or any
of a number of different methods.  The rest of the code on the web site,
no matter how much it was, didn't change.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================

## Re: My first somewhat meaningful class for length conversions

.oO(oh.i.love.spam@gmail.com)

As already mentioned you should store such values in an array, which
would also make it much easier to add new units.

Additionally you can improve the entire algorithm by first converting
the \$from unit to meters, then in a second step to the \$to unit. This
way you don't have to hard-code all possible conversions, but can do
both calculations with a single simple lookup array, e.g.

function conv(\$val, \$from, \$to) {
\$factors = array(
'km' => 1000,
'm' => 1,
'ft' => 0.3048,
'dm' => 0.1,
'in' => 0.0254,
'cm' => 0.01,
'mm' => 0.001
);
return isset(\$factors[\$from]) && isset(\$factors[\$to])
? \$val * \$factors[\$from] / \$factors[\$to]
: NULL;
}

Turning this single function into a class doesn't make much sense
IMHO, but it could be part of a more generic conversion class for
example, also supporting weights and such.

Micha