chaiwei Posted April 23, 2009 Share Posted April 23, 2009 Hi, I am curious about why we need to use OOP. As I know OOP can use for : 1. code reusability 2. it is more safe I think. (private and public variable) -encapsulation Code reusability , instead of classes, why don't we use function, we just need to include() the function, the reuse it. encapsulation, But I can't see why we need to use the private variable in the script. If others ppl can hack into your script, of course they can hack into the class as well. I saw a lot of OOP method in my senior project. In one script it got so many class to search. and if got one small error, I need to look at all the class And I don't know whether it is right for All functions/systems to go for OOP. When is the suitable time to use OOP? Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted April 23, 2009 Share Posted April 23, 2009 Code reusability , instead of classes, why don't we use function, we just need to include() the function, the reuse it. It's called object oriented programming, not class oriented programming. Something tells me you do not know what OOP is. OOP is not procedural programming with classes instead of functions. encapsulation, But I can't see why we need to use the private variable in the script. If others ppl can hack into your script, of course they can hack into the class as well. It has nothing to do with security against hackers. The protection is against other code. You do not have variables in the global scope which may accidentally be overwritten by your own code or third party libraries. Also, by restricting access to an objects properties you control how they're used. I'd suggest you to read up on OOP. It really is quite a too large subject to explain in one topic. There are written several books on OOP after all. I understand your confusion though. A lot of people claim to be using OOP when in fact they are rather just using classes as a sort of namespace (like the people who create an enormous class called just database). Quote Link to comment Share on other sites More sharing options...
dbo Posted April 23, 2009 Share Posted April 23, 2009 Question: Is OOP better? Answer: Yes. Quote Link to comment Share on other sites More sharing options...
chaiwei Posted April 27, 2009 Author Share Posted April 27, 2009 Hi, Thanks for the guide. I am still confuse between class and objects. And is it everything can do on Object style? let say I want to do a simple math calculation. <? //page1.php function calculate($num1,$num2){ return $num1+$num2; } ?> <? //page2.php include 'page1.php'; //we should write this ? (which is the standard way) //include('page1.php'); //or this? $answer= calculate(1,1); ?> This is just the normal function right?IS this call procedural programming ? <? //page1.php class calculator{ private $total; private $int1; private $int2; function calculate($num1,$num2){ this->$int1 =$num1; this->$int2 =$num2; this->$total = (this->$int1 )+ (this->$int2); return this->$total; } } ?> <? //page2.php include 'page1.php'; $objcal= calculator(); $answer=$objcal->calculate(1,1); ?> this is object oriented programming or class oriented programming? Wouldn't this is too complex for us to do simple calculation job with OOP. I still can't get the benefit of OOP. So in my opinion I think method 1 is a lot easier and simple with just include the function. Please correct my mistake. Thanks. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted April 27, 2009 Share Posted April 27, 2009 Well, the problem with your example is that it's too simple. Something like adding two numbers probably would be better served by creating a simple function rather than an object. The entire point of OOP is to create a (relatively) simple interface that hides a more complex implementation underneath. Why is this important? If the interface remains the same, you can use a variety of different objects that implement that interface. Things become modular, and thus more reusable and flexible. Let's say you're creating a couple of sites, one for news, another for cooking recipes. Both need to render content to the screen, but need to do it in different ways. However, since you want your sites' structures to be uniform across the board, you don't want to have custom client/controller code for each one. The solution is to create objects to encapsulate the concept(s) that vary, in this case the news and recipes. Since everything should be uniform, you need to start with an abstract (non-instantiated) base class that the others derive from. So, something like: abstract class Content { protected $info; public function __construct($info = null) { $this->info = $info; } public function setInfo($info) { $this->info = $info; } protected abstract function render(); } Notice that the 'render' method is abstract. This informs PHP that the actual implementation of this method will be defined in the child classes. Let's define those now: class News extends Content { protected function render() { echo "<div style='font-weight: bold;'>$this->info</div>"; } } class Recipe extends Content { protected function render() { echo "<div style='color: blue;'>$this->info</div>"; } } Obviously, these examples are a bit canned, as more specific and complicated formatting should be applied, but it still illustrates my point. Let's create one more object that returns the correct child object to the system based on a value sent by a query string: class ContentFactory { public static function getContent($value) { if(strtolower($value) == "news") { return new News(); } else { return new Recipe(); } } } So, assuming we have a link in the form of www.example.com/info.php?contenttype=something we can get the right kind of object simply by writing: $contentType = $_GET['contenttype']; $contentObj = ContentFactory::getContent($contentType); $contentObj->setInfo("Hello World"); $contentObj->render(); Again, this example is a bit canned. The info should be retrieved from the database, and there should be error checking, but I believe the basic concepts are there. Hope this helps. Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted April 27, 2009 Share Posted April 27, 2009 I still can't get the benefit of OOP. So in my opinion I think method 1 is a lot easier and simple with just include the function. It's because you haven't used OOP in your example. You are just applying procedural principles to an object model, but that doesn't make it object oriented. You can't just "translate" line by line like you're doing. Also, the "class oriented programming" was just something I made up. It's not something that's generally understood. I used that term because all you've been doing thus far is wrap your functions in classes, but that's nothing more than emulating namespaces in a poor way. Many people seem to do that and then go on to call it OOP, but it's not OOP unless your code revolves around objects and their logical/natural interaction with each other. Quote Link to comment Share on other sites More sharing options...
Vermillion Posted May 1, 2009 Share Posted May 1, 2009 OOP is a painful concept to understand at first, but once you get it, you love it. You really do. I know I felt in love of it... Anyways, you can really do everything with it in a safe, quick, and to-the-point way. Consider what Daniel0 said: The protection is against other code. Imagine you, the person, are the object. You have a function to take your (my apologies for this example, lol) clothes off. You wouldn't want other people to take your clothes off, would you? . Quote Link to comment Share on other sites More sharing options...
chaiwei Posted May 1, 2009 Author Share Posted May 1, 2009 haha, yes absolutely. then OOP is it can define like pyramid hierarchy? example for a hrms system(human resource management system) : employee is a main object. employee got the attribute like name, basic salary, address,etc. and method example create new employee, delete employee, edit employee, display employee details. then employee got leave, OT , timesheet which inherit from employee class. employee can take leave, and work overtime and their own timesheet. then the payroll is calculate from the leave , ot , timesheet based on each employee. but I dono where should I place payroll inherit from what class. Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted May 1, 2009 Share Posted May 1, 2009 then employee got leave, OT , timesheet which inherit from employee class. employee can take leave, and work overtime and their own timesheet. Inheritance can be seen as an "is a" relationship. So unless your timesheet is an employee it shouldn't be a descendant. Like a poodle is a dog, but a dog isn't a poodle, and your poodle's collar isn't a poodle. You could think about OO inheritance as being sort of the same as the taxonomy used in biology for living organism, if that helps you. Sort of overall you have "life" and then within life you have domains, then kingdoms, etc. So a poodle shares all the common traits that dogs have, but it also has some specific traits that that dogs in general do not have. Your poodle, let's call it Fluffy, would be an instance of the object Poodle. Fluffy's collar wouldn't be an instance of Poodle, it isn't even a dog or even a living being. It's an entirely different thing, so it Poodle and Collar don't even share common ancestor classes. This type of relationship could be described as "has a", or more precisely aggregation. Fluffy also has a heart, among other things, but this wouldn't be aggregation, but rather composition. Let's try to explain it in PHP: abstract class Dog { protected $_name; protected $_collar; protected $_heart; public function __construct($name) { $this->_name = $name; $this->_heart = new Heart(); } public function getName() { return $this->_name; } public function setCollar(Collar $collar) { $this->_collar = $collar; return $this; } /** * Each kind of dog barks in a different manner, * so we might want to declare the bark() method * as abstract. */ abstract public function bark(); } class Poodle extends Dog { public function bark() { // implementation here... } // more poodle specific stuff here... } class Collar { // class members here } class Heart { // class members here } $fluffy = new Poodle('Fluffy'); $fluffy->setCollar(new Collar()); $fluffy->bark(); The difference between aggregation and composition is essentially that with aggregation, objects persist after their container object has been destroyed. Fluffy's collar doesn't somehow cease to exist just because Fluffy dies. If your company closes, your employees wouldn't immediately die. Conversely, if Fluffy dies then the heart would as well. employee is a main object. employee got the attribute like name, basic salary, address,etc. Yes, except I don't like the part where you call it "main object". The idea of attributes is correct though. and method example create new employee, delete employee, edit employee, display employee details. Yes and no. Creating an employee would equate to creating a new instance of the employee class (e.g. new Employee();). When you have an instance of a particular employee, editing it would perhaps be modifying its attributes somehow, and you could perhaps then have a save() method. Your employee class shouldn't have a method that would display details about it, but rather expose the data via an logical interface such that the information can be retrieved, but handled in various ways by other objects. I hope this clears up some of the stuff about OOP. At any rate, OOP is a far too big topic to cover in a topic on a forum, so what I would suggest you do is to get some good books (search the forums for recommendations). You are of course then very welcome to ask about any particular problems you might run into. Quote Link to comment Share on other sites More sharing options...
chaiwei Posted May 2, 2009 Author Share Posted May 2, 2009 Sorry I can't edit my post. Please help me to delete the previous post. <?php //employee.class.php abstract class employee{ protected $name; protected $type; protected $salary; protected $workingdays; public function __construct($name, $type = '', $salary = '', $workingdays = ''){ this->$name=$name; this->$type=$type; this->$salary=$salary; this->$workingdays=$workingdays; } public function get_name(){ return this->$name; } public function get_type(){ return this->$type; } public function get_salary(){ return this->$salary; } public function get_workingdays(){ return this->$workingdays; } public function save(){ $sql = "INSERT INTO employee(name,type,salary,workingdays) "; $sql .= "VALUES ('this->$name', 'this->$type' , 'this->$salary', 'this->$workingdays')"; mysql_query($sql); } abstract public function calc_payroll(); } class part_time extends employee{ private $netsalary; public function calc_payroll(){ $sql = "SELECT e.salary, p.rate, e.workingdays FROM parttime p,employee e "; $sql .= "WHERE p.emp_id = e.id AND e.name='$this->$name' "; //mysql query here this->$netsalary = $row['salary'] * $row['rate'] * $row['workingdays']; return $this->$netsalary; } } class permanent extends employee{ private $netsalary; public function calc_payroll(){ $sql = "SELECT salary FROM employee "; $sql .= "WHERE name='$this->$name' "; //mysql qury here this->$netsalary = $row['salary']; return $this->$netsalary; } } ?> <?php // -- page1.php include 'employee.class.php'; $john = new part_time('john', 'parttime', '5' ,'26'); john->save(); $maria = new permanent('maria' , 'permanent', '1400', '26'); $maria->save(); ?> <?php //page2.php include 'employee.class.php'; $john = new employee('john'); echo 'John salary was '.$john->calc_payroll(); $maria = new employee('maria'); echo 'Maria salary was '.$maria->calc_payroll(); ?> Please correct my mistake if I am go wrong with OOP way. Or got any improvement need to be done. Thanks a lot. Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted May 2, 2009 Share Posted May 2, 2009 There are some problems. First of all, you access a property like $this->name and not like this->$name. The latter is actually syntactically incorrect, so it wouldn't even parse. Secondly, you declared employee as abstract, but in page2.php you're trying to instantiate it. That's not allowed either. It also seems like many of the properties are not relevant for all of your classes. E.g. workingdays seems to be only applicable for parttime employees. In that case it should belong in that class. Here is an example of how you might do it: abstract class DomainObject { /** * Name of the table. * * @var string */ protected $_tableName; /** * Name of primary key. * * @var string */ protected $_pk; /** * Array of field names. * * @var array */ protected $_fields; /** * Array of changed fields. * * @var array */ protected $_dirty = array(); /** * Array of current data. * * @var array */ protected $_data = array(); private $_disableDirty = false; /** * Array of original data. * * @var array */ protected $_originalData = array(); public function __construct(array $data = array()) { if (!isset($this->_tableName)) { throw new RuntimeException('Table name is not set.'); } if (!isset($this->_fields) || count($this->_fields) == 0) { throw new RuntimeException('No fields are set.'); } if (!isset($this->_pk)) { throw new RuntimeException('Primary key is not set.'); } else if (!in_array($this->_pk, $this->_fields)) { throw new RuntimeException('Primary key is not in the field list.'); } $this->_disableDirty(true); foreach ($data as $field => $value) { $this->setValue($field, $value); } $this->_disableDirty(false); } /** * Saves dirty fields to database. */ public function save() { if (count($this->_dirty) == 0) { // nothing to do return; } $sql = 'UPDATE ' . $this->_tableName . ' SET '; $updates = array(); foreach ($this->_dirty as $fieldName) { $updates = $fieldName . " = '" . mysql_real_escape_string($this->_data[$fieldName]) . "'"; } $sql .= join(', ', $updates) . ' WHERE ' . $this->_pk . " = '" . mysql_real_escape_string($this->_data[$this->_pk]) . "';"; mysql_query($sql); $this->_dirty = array(); } public function setValue($field, $value) { if (!in_array($field, $this->_fields)) { throw new OutOfBoundsException("Invalid field '{$field}'."); } $this->_data[$field] = $value; if (!$this->_disableDirty && !in_array($field, $this->_dirty)) { $this->_dirty[] = $field; } return $this; } public function getValue($field) { if (!in_array($field, $this->_fields)) { throw new OutOfBoundsException("Invalid field '{$field}'."); } return $this->_data[$field]; } public function __get($name, $value) { $this->getValue($name, $value); } public function __set($name) { $this->setValue($name); } protected function _disableDirty($state = true) { $this->_disableDirty = (bool) $state; return $this; } } class Employee extends DomainObject { protected $_tableName = 'employees'; protected $_pk = 'employee_id'; protected $_fields = array( 'employee_id', 'name', 'salary', ); } $john = new Employee(array('employee_id' => 1234, 'name' => 'John Doe', 'salary' => 43)); $john->salary = 40; // sorry john $john->save(); You could then write some (perhaps static) methods that are responsible for fetching data so you don't have to pass it manually to the constructor. You might also want to have some way to get an instance of e.g. MySQLi or PDO (or your own wrapper around these). Please note that I didn't test any of that code. Quote Link to comment Share on other sites More sharing options...
Cardale Posted May 17, 2009 Share Posted May 17, 2009 Question: Is OOP better? Answer: Yes. Doesn't it depend on how big an application your designing? If your making a simple website for personal use to post some news and have your own little register account and you don't plan on doing anything modular like moving your website changing projects switching databases or having someone else mess with your code then why bother. It is much easier and faster to write your little program then delve into the world of OOP. In fact I think a lot of time people don't need to design all these classes because the fact is when I first started I had one file with all my functions in it and just used the functions how I needed them. This was in fact less complicated then writing classes and easier to manage. I am not saying you should do that because it was bad practice should probably break your functions up and use them at certain points when you need, but really making a file that has a list of related functions to pull information from the database in one file and shoot that info into a template file is simple enough and usually the fastest method with less overhead. Quote Link to comment 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.