What are the benefits of OO as opposed to procedural?

Discussion in 'PHP' started by scottlpool2003, Oct 8, 2012.

  1. #1
    I just can't get my head around it. The tutorials I've looked at don't help me understand the benefits vs procedural.

    I get that everything is stored in one location so it's easier to maintain, but my procedural code all uses includes so it seems fairly simple to me.

    I think most of the tutorials are showing the wrong things to people who have used procedures for years such as:

    <?php  
    class MyClass  
    {  
        public $prop1 = "I'm a class property!";  
    }  
    $obj = new MyClass;  
    var_dump($obj);  
    ?>  
    PHP:
    That would take me far longer than writing:

    <?php echo "I'm a class property";?>
    PHP:
    Would we really store text on-page in real life... Would we not pull that from a database? Reason I ask is because if the website is static, is there really need for classes?

    What would be the natural things to store in a class? If someone could help explain in layman's terms to help me make the transition from procedural to object orientated that would be great.
     
    scottlpool2003, Oct 8, 2012 IP
  2. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #2
    Your example is exactly when NOT to use objects -- and there are a LOT of cases where objects are the wrong choice; In fact, there seems to be this sick trend of throwing objects at EVERYTHING for no good reason lately. Objects have more overhead and a significant performance impact...

    BUT, they exist for a reason. The advantages are simple: scope, and polymorphism.

    Scope is easy to explain -- you can declare values inside it as PRIVATE so that they are not accessible to anything but that one object instance and definition -- or PROTECTED meaning only the object or it's descendants can use it. This is important when dealing with values that should NOT have global scope or be accessible in any way from outside the object, like the handle to your database connection, the database connection info, etc, etc... At least, that's the case if you bother practicing multi-layer security instead of one-ring asshattery like the average turdpress developer craps out. (SQL UN/PW/HOST as DEFINES?!? REALLY!?!?!). Done properly, this can mean that just because a code elevation happens, it's not like they can do anything with it.

    The smaller namespace and values isolated to the object also means less chance of namespace conflicts between mis-matched code from multiple sources.

    Polymorphism is a bit harder to explain, but let's use the example of a CMS that has a single defining index.php which calls multiple sub-modules.

    You could hard code the startup code for each module, the call for each module's functionality, or let it's procedures exist in global space... or, you could make a prototype for the module, pass the database to the module and keep it's scope private, then expand that object with common calls so that you can add them and execute them very simply. Remember, in 'well written' code includes should only contain functions/objects/methods and MAYBE one call -- not filled to the brim directly executable code.

    this is paraphrasing how my CMS works -- the Paladin is served by his mount, attended to by many squires.

    
    class squire {
    	private $mount;
    	public $name='';
    	
    	public function __construct($name) {
    		$this->name=$name;
    	}
    	
    	public function setup($mount) {
    		$this->mount=$mount;
    	}
    	
    	public function getResult() {
    		return false;
    	}
    	
    }
    
    class paladin {
    	private
    		$squires=array();
    		$setupData=array();
    		$results=array();
    	
    	public function __construct() {
    		require_once('settings.php');
    		/*
    			dbsettings() should throw if not called from index.php -- This
    			prevents any other code from pulling the database info.
    		*/
    		$mount=new mount(dbSettings());
    		$squireList=glob('squires/*.squire.php');
    		foreach ($squireList as $squireFile) {
    			require('squires/*'.$squireFile);
    			$thisSquire=end($squires);
    			$setupData[$thisSquire->name]=$thisSquire->setup($mount);
    		}
    		/*
    			modules may be co-dependent, so you have to set them all up
    			THEN you can call their result sets
    		*/
    		foreach ($squires as $squire) $results[$squire->name]=$squire->getResult();
    		template_header($setupData);
    		template_body($setupData,$results);
    		template_footer();
    	}
    }
    
    Code (markup):
    Which is the framework -- which you then extend the squire object... An example would be pulling up a blog post, where you'd want the blog info, possibly before you'd need the post information for some other module to make use of... then the post itself.

    blogPage.php
    
    class blogPage extends squire {
    	
    	public function setup($mount) {
    		parent::setup($mount);
    		$statement=$this->mount->namedQuery('getBlogInfo');
    		$statement->exec(array(
    			'id' => $actions[1]
    		));
    		return $statement->fetch();
    	end;
    	
    	public function getResults() {
    		$statement=$this->mount->namedQuery('getBlogPost');
    		$statement->exec(array(
    			'id' => $actions[2]
    		));
    		return $statement->fetch();
    	}
    		
    }
    
    $squires[]=new blogPage('blogPage');
    
    Code (markup):
    Called directly all it would do is put a empty object in global space -- called by the index.php it's now a functional module.

    Mind you, the above oversimplifies and it ain't quite right, but for purposes here it will have to do... It's missing the bits to only run the getResults for the current page -- setup() should pull information that's needed on all pages, getResults() should pull up the current page

    Restricting element scope for security reasons, easily extending the functionality of existing code, working with data as relational sets using things like pointer based lists -- these are the reasons to use objects.

    Just don't throw them at EVERY problem like a lot of people seem to.
     
    deathshadow, Oct 8, 2012 IP
  3. scottlpool2003

    scottlpool2003 Well-Known Member

    Messages:
    1,708
    Likes Received:
    49
    Best Answers:
    9
    Trophy Points:
    150
    #3
    Thanks deathshadow

    So this bit:

    		template_header($setupData);
    		
    		template_footer();
    PHP:
    Essentially is pulling a default header and footer as these will not change other than attributes such as title, metatags and such.

    But this bit:

    template_body($setupData,$results);
    PHP:
    Is where all the action is. That's pulling the info from the paladin class. If I'm reading correctly, could paladin contain an insert/update/delete class and admin-side could contain a simple function such as $this->insert(tablename); or something similar?
     
    scottlpool2003, Oct 8, 2012 IP