Jump to content

Help writing a unit converter


stevengreen22

Recommended Posts

Hey all,

 

I'm trying to write a fairly intensive unit converter.  I only want to use PHP to achieve it.  There's tons of online material for a JS version but that won't do :)

 

I'd also like to use classes as well to help organise things (and it's what I know).

 

The problem is...I don't really know where to start.

 

I'm intending on having a form of course where a user can select a unit type and how many of that unit.  The output will then display all the other units for that measurement.  

So length for example : 1 cm would output 10 mm; metres, yards etc etc

 

For my other forms I've used POST to get the details but I found an example online that uses method="$_SERVER['PHP_SELF']" instead

 

could someone be kind enough to guide me in the right direction please?

 

Many thanks

Link to comment
Share on other sites

I'm not sure if you've given quite enough information to do *much* helping. :)

 

A "unit" will be an object, then? Sounds good. And you could have a generic "Unit" class and have subclasses for inch, centimeter, yard, pound, kilogram, etc.

 

What methods would they have? Would each have a "to_other" ("to_inch", "to_yard", "to_kilogram", etc.)?

 

As for method="PHP_SELF" ... that's simply using the same script as both the initial form and the data handler:

if (!$_POST) {
   show_the_form();
} else {
   //handler code goes here
}
HTH, Edited by dalecosp
Link to comment
Share on other sites

<?php
interface FactorRepositoryInterface {
const HOUR = 'hour';
const MINUTE = 'minute';
const CELSIUS = 'celsius';
const FAHRENHEIT = 'fahrenheit';

public function getFactor($fromUnit, $toUnit);
}

class FactorRepository implements FactorRepositoryInterface {
private $factors = array();

private function loadFactorTable() {
$this->addFactor(self::HOUR, self::MINUTE, 60);
$this->addFactor(self::MINUTE, self::HOUR, 1/60);
$this->addFactor(self::CELSIUS, self::FAHRENHEIT, function($value) { return $value * 1.8 + 32; });
$this->addFactor(self::FAHRENHEIT, self::CELSIUS, function($value) { return ($value - 32) / 1.8; });
}

public function addFactor($from, $to, $callable) {
if (!is_callable($callable)) {
$factor = $callable;
$callable = function($value) use ($factor) {
return $value * $factor;
};
}
$this->factors[$from] = array($to => $callable);
}

public function getFactor($fromUnit, $toUnit) {
$this->loadFactorTable();

if (!isset($this->factors[$fromUnit], $this->factors[$fromUnit][$toUnit])) {
throw new RuntimeException('Unknown unit specified');
}

return new Factor($this->factors[$fromUnit][$toUnit]);
}
}

interface FactorInterface {
public function getFactor();
public function multiply($value);
}

class Factor implements FactorInterface {
private $callable;

public function __construct(callable $callable) {
$this->callable = $callable;
}

public function getFactor() {
return $this->multiply(1);
}

public function multiply($value) {
$func = $this->callable;
return $func($value);
}
}

class UnitConverter {
private $factorLookup;

public function __construct(FactorRepositoryInterface $factorLookup) {
$this->factorLookup = $factorLookup;
}

public function convert($value, $fromUnit, $toUnit) {
return $this->factorLookup->getFactor($fromUnit, $toUnit)->multiply($value);
}
}

$uc = new UnitConverter(new FactorRepository);
echo $uc->convert(100, FactorRepository::CELSIUS, FactorRepository::FAHRENHEIT);
The callable covers the case where you need the value to get the factor (eg celsius to fahrenheit). Edited by ignace
Link to comment
Share on other sites

Wow, thanks guys, I wasn't expecting so much and the above class is pretty awesome :)

 

I went back to basics so to speak to try and understand the problem a bit better.  There are many different types of units that will need to be converted so I was working on a select boxes that auto populated depending on the previous choice.  This then menat leaning or attempting to learn jquery and js in part to try and understand those functions needed.  I'll then piece this all together.  Hopefully:)

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.