The Little Guy Posted December 15, 2009 Share Posted December 15, 2009 Anyone have any suggestions on how to set up php classes? I have three at the moment, but I don't know if they are set up well. I am making a question and answer site, ask a question, and it will return an answer. So the user types in a question, then I need it to choose the proper class to use according to the question. Right now, I have it so when they type their question it goes through a class called "Parser" which takes the query and decides what the person is talking about, after that it runs a class that is closest to that query. For example if the person types: "how many feet are in a mile?" It decides that it is a math question, and creates a "Math" class. Next, in the "Math" class it parses it even more and looks at that and sees that there is feet and miles, so this question is about distance comparison. so it then creates a third class called "Distance" which then calculates all types of distances. Finally the returned result is: "5280 feet = 1 mile" I am not really sure if this is a good approach, I would like to easily be able to modify the classes to do other things, such as instead of "Math" do "Language" or "Shopping" etc. I would also like to be able to easily access values from the class that created the current class, but I am not sure how to do that... Does anyone have a good or better approach to this? I am kind of stumped, and fairly new to PHP's OOP Thanks!!! Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/ Share on other sites More sharing options...
mikesta707 Posted December 15, 2009 Share Posted December 15, 2009 How is the class hierarchy set up? Does this "Distance" class inherit from the math class? do all classes inherit from a Question or whatever class? But yeah, I would say you have a good set up Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977421 Share on other sites More sharing options...
The Little Guy Posted December 15, 2009 Author Share Posted December 15, 2009 Nothing extends anything else... I am not really sure how I would set this up if I were to extend classes... Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977433 Share on other sites More sharing options...
mikesta707 Posted December 15, 2009 Share Posted December 15, 2009 well I would imagine all these difference classes do similar things? so they probably have similar attributes/methods? If not than disregard the above Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977434 Share on other sites More sharing options...
The Little Guy Posted December 15, 2009 Author Share Posted December 15, 2009 I would like my Distance class to extend my Math class, but from the amount of OOP I know I don't see the point, maybe you can help me out... Here is the whole Math class: <?php class Math{ public $query = ""; public $result; public $distance; public $special = array(); public $valid = FALSE; public function __construct($string = "", $dist){ $this->query = $string; $this->distance = $dist; $this->result = $this->parse(); } public function parse(){ // Distance if(preg_match("~(".implode("|", $this->distance).")~", $this->query)){ $distance = new Distance($this->query, $this->distance); if(!$distance->valid){ $this->valid = FALSE; return FALSE; } $this->info = $distance->info; $this->special = $distance->special(); $this->valid = TRUE; return $distance->final; } return FALSE; } } ?> I think the main problem, is that I can't just call the distance class based on the query, I have to call the math class, then decide which type of math class I need to use (distance, weight, adding, subtraction, etc.). I feel I am making this harder than it needs to be... I'm kinda confused right now... Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977442 Share on other sites More sharing options...
mikesta707 Posted December 15, 2009 Share Posted December 15, 2009 If all the math class does is decide which of 4 classes to create, why not create a function in the parsing class to do that? That seems like something a parsing function would do. But yeah, about the other classes (distance, and what not) When I was talking about inheriting functions, these would be a good example. Im assuming, since they all answer some sort of math based question, that they have some similar attributes and methods. you could have them all extend one class. That way, since they are all basically the same type, so you can pass them into functions that use type hinting easier. for example, assume the base class was called MathHandler, and we use that to derive our other more specific classes from it public function foo(MathHandler $math){ then you could pass any of the different classes into that function, and take advantage of polymorphism (if you wanted to). But this is just a suggestion, you could do it a few different ways. However, I think inheritance would make sense here Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977448 Share on other sites More sharing options...
The Little Guy Posted December 15, 2009 Author Share Posted December 15, 2009 I don't under stand, when I create the Math class I need to create a Distance class, but in the distance class I don't need the Math classes' methods or properties any more, but I would like to set some properties that are in the calling class (Class that created the Distance class) from the distance class. This way I could use that property later on... Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977457 Share on other sites More sharing options...
optikalefx Posted December 15, 2009 Share Posted December 15, 2009 Yea from the sound of it mikesta707 has it right. Your math class is just a intermediate class. Seems to me like your parser should take care of that. Like when you call the operator they decide where to connect you. If all your math class does is choose a type of math, then you are wasting code. Your parser class should then have levels and sub levels. By the way whatever your making seems awesome! You should somehow try to harness the internet instead of hard coding these functions though, you can't account for everything. Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977511 Share on other sites More sharing options...
The Little Guy Posted December 15, 2009 Author Share Posted December 15, 2009 Your parser class should then have levels and sub levels. What are levels and sub levels? Oh, how am I waisting code can you explain? Thanks! Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977512 Share on other sites More sharing options...
The Little Guy Posted December 15, 2009 Author Share Posted December 15, 2009 How am I waisting code? Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977961 Share on other sites More sharing options...
mikesta707 Posted December 15, 2009 Share Posted December 15, 2009 Well you aren't really wasting code. I was just saying that what the Math class does is basically one method that can (and perhaps should) be handled by the parsing class. Since all the math class does is create another class based on some regex, You can just get rid of that class all together and use the parser class to create one of the distance/whatever classes. Now for the inheritance topic, just look at your math question classes, like distance or whatever. Compare them all, and see if they all have certain attributes/methods that are the same (perhaps basic attributes, accessors, mutators, etc.) If they have a set of attributes and methods that are pretty much the same, you can put those things into a Base class, and derive all the other classes from it. There are many advantages to use inheritance here, and it will make your code easier (in my opinion) to update and add stuff. if you want to add certain functionality to all the math question classes, instead of adding it one at a time you can add it to the base class and viola. Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-977973 Share on other sites More sharing options...
The Little Guy Posted December 16, 2009 Author Share Posted December 16, 2009 I am going to have more in that math class, such as: - Distance - Weight - Time - Speed - Basic Math - etc... Here is a basic overview of how I was planning on making my class structure - Parser - Math - Distance - Weight - Time - Speed - BasicMath - Language - Dictionary - Thesaurus - Reviews - Product - Business For some reason I am not able to get my head to see this properly sorry... Parser.php <?php class Parser{ public $distances; private $query; public function __construct($query, $pageType = 'default'){ include 'helper/arrays.php'; $this->distances = $distances; $this->query = $query; $categoryResult = $this->bestCategory(); $this->spellCheck(); $this->parse($categoryResult); } public function bestCategory(){ $q = mysql_real_escape_string($this->query); $sql = mysql_query(" SELECT * FROM `phrases` p LEFT JOIN `categories` c ON (p.category = c.id) WHERE '$q' REGEXP p.phrase")or die(mysql_error()); return mysql_fetch_array($sql); mysql_free_result($sql); } public function spellCheck(){ $str = preg_replace("~\.|\?|/!~", "", $_GET['q']); $words = explode(" ", $str); $pspell_link = pspell_new("en"); $errors = 0; $errorStr = ""; foreach($words as $word){ if(!pspell_check($pspell_link, $word)){ $suggestions = pspell_suggest($pspell_link, $word); $errorStr .= "<b>".$suggestions[0]."</b> "; $errors++; }else{ $errorStr .= $word." "; } } if($errors > 0){ echo '<span style="font-weight:bolder;font-size:18px;">Did you mean:</span> <a href="?q='.strip_tags($errorStr).'">'.$errorStr.'</a>'; } } public function parse($row){ if($row['category'] == 'Math'){ $math = new Math($_GET['q'], $this->distances); if($math->valid){ $total = $math->result; $info = $math->info; echo "<h1>".$total."</h1>"; if(!is_null($info)){ echo "<h2>Additional Information:</h2>".$info; } } } if($row['category'] == 'Language'){ echo "<h1>Definitions for {$_GET['q']}</h1>"; } } } ?> Math.php <?php class Math{ public $query = ""; public $result; public $distance; public $special = array(); public $valid = FALSE; public function __construct($string = "", $dist){ $this->query = $string; $this->distance = $dist; $this->result = $this->parse(); } public function parse(){ // Distance if(preg_match("~(".implode("|", $this->distance).")~", $this->query)){ $distance = new Distance($this->query, $this->distance); if(!$distance->valid){ $this->valid = FALSE; return FALSE; } $this->info = $distance->info; $this->special = $distance->special(); $this->valid = TRUE; return $distance->final; } return FALSE; } } ?> Distance.php <?php class Distance{ public $query = ""; // Define the constants const inch = 1; const foot = 12; const yard = 36; const pixel = 72; const mile = 63360; const kilometer = 39370.0787; const lightyear = 3.72461748E+17; // Define the public properties public $final; public $info = null; public $distances; public $valid = TRUE; // Define the private properties private $metric = array("kilometer"); private $special = array(); public function __construct($string = "", $dist){ $this->query = preg_replace("~,~", "", $string); $this->distances = $dist; $this->final = $this->parse(); } public function special(){ return $this->special; } public function parse(){ // Find and create an array of the distances found in the string preg_match_all("~".implode("|", $this->distances)."~", $this->query, $matches); $arrQ = explode(" ", $this->query); $in = array_search("in", $arrQ) + 1; // if the following character isn't a number set count to 1 if(is_numeric($arrQ[$in])){ $count = $arrQ[$in]; }else{ $count = 1; } $v = array(array(), array()); if(!isset($matches[0][0]) || !isset($matches[0][1])){ $this->valid = FALSE; return FALSE; } // First value settings // Distance type (mile, foot, inch, etc) saved as number from array 0 is samllest distance // Metric or standard Found in private metric array $v[0][0] = array_search($matches[0][0], $this->distances); $v[0][1] = (in_array($matches[0][0], $this->metric))?'metric':'standard'; // Second value settings $v[1][0] = array_search($matches[0][1], $this->distances); $v[1][1] = (in_array($matches[0][1], $this->metric))?'metric':'standard'; // Remove spaces $matches[0][0] = str_replace(" ", "", $matches[0][0]); $matches[0][1] = str_replace(" ", "", $matches[0][1]); // Set special items $this->special[0] = $matches[0][0]; $this->special[1] = $matches[0][1]; // Change feet to foot for eval and variable reasons if($matches[0][0] == 'feet'){ $matches[0][0] = 'foot'; } if($matches[0][1] == 'feet'){ $matches[0][1] = 'foot'; } // If value 0 is smaller than value 1 that means they are caulating a small number to a larger number // that is why the distance array needs to be set up from smallest to largest if($v[0][0] < $v[1][0]){ // This holds the calculations for two standard distances if($v[0][1] == 'standard' && $v[1][1] == 'standard'){ $str = '$value = (self::'.$matches[0][1].' * $count) * self::'.$matches[0][0].';'; } // Run the string as code eval($str); // since all values are defaulted to inch, some values need to be caluclated further if($matches[0][0] == "foot" && $matches[0][1] == "mile"){ // convert the inches into feet to get feet in x miles $value = ($value / 12) / 12; } if($matches[0][0] == "yard" && $matches[0][1] == "mile"){ // convert the inches into yards to get yards in x miles $value = ($value / 36) / 36; } if($matches[0][0] == "mile" && $matches[0][1] == "lightyear"){ // convert the inches into yards to get yards in x miles $value = ($value / 63360) / 63360; } }else{ $str = '$value = (self::'.$matches[0][1].' * $count) / self::'.$matches[0][0].';'; eval($str); } // save any additional information if($matches[0][0] == "inch" || $matches[0][1] == "inch"){ $this->info .= ' <dl> <dt>Inches</dt> <dd>The distance from your finger tip to your first joint is about an inch.</dd> </dl>'; } if($matches[0][0] == "foot" || $matches[0][1] == "foot"){ $this->info .= ' <dl> <dt>Feet</dt> <dd>A foot is 12 inches, which is average size of male human wearing a shoe.</dd> </dl>'; } if($matches[0][0] == "pixel" || $matches[0][1] == "pixel"){ $this->info .= ' <dl> <dt>Pixels</dt> <dd>The average computer displays 72 pixels per inch, so are caluclations were bassed on 72 pixels in an inch.</dd> </dl>'; } if($matches[0][0] == "lightyear" || $matches[0][1] == "lightyear"){ $this->info .= ' <dl> <dt>Light year</dt> <dd> Light travels at about 669,600,000 miles per hour, are calculations were based on inches in a lightyear. <ul> <li>A lightyear is a measurement of how fast light travels in one year.</li> <li>It takes 8 minutes for light to reach earth from the sun.</li> <li>The sun is on average 93 million miles away from the earth.</li> </ul> </dd> </dl>'; } $opt1 = ""; $opt2 = ""; if($value > 1 || $value < 1){ switch($matches[0][0]){ case "pixel":$opt1="pixels";break; case "inch":$opt1="inches";break; case "foot":$opt1="feet";break; case "lightyear":$opt1="light years";break; case "mile":$opt1="miles";break; } }else{ switch($matches[0][0]){ case "pixel":$opt1="pixel";break; case "inch":$opt1="inch";break; case "foot":$opt1="foot";break; case "lightyear":$opt1="light year";break; case "mile":$opt1="mile";break; } } if($count < 1 || $count > 1){ switch($matches[0][1]){ case "pixel":$opt2="pixeles";break; case "inch":$opt2="inches";break; case "foot":$opt2="feet";break; case "lightyear":$opt2="light years";break; case "mile":$opt2="miles";break; } }else{ switch($matches[0][1]){ case "pixel":$opt2="pixel";break; case "inch":$opt2="inch";break; case "foot":$opt2="foot";break; case "lightyear":$opt2="light year";break; case "mile":$opt2="mile";break; } } // return the final value return "$value $opt1 = $count $opt2"; } } ?> I think what I may do, is change the categories in the database from "Math" and "Language" to "Distance", "Weight", "Speed" etc. I think that way I then wouldn't have to deal with creating a math class, just extending it.... Quote Link to comment https://forums.phpfreaks.com/topic/185161-oop-organization/#findComment-978211 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.