Search code examples
phpoopinheritanceabstract-classabstraction

Using abstract classes in php to get and post HTTPData and demonstrate how it works


I am currently learning the basics in PHP programming and I am having trouble getting my head wrapped around abstract classes. I have a program with 3 classes, not including an index.php to demonstrate that it works, that will demonstrate an abstract class getting inherited by two other ones. The first class called HTTPData is an abstract class with only one abstract method, which is getKey($key). The two other classes, called HTTPGetData and HTTPPostData, are extending the HTTPData class and both have the same getKey($key) method, just not abstract. I can't hardcode the contents of $key, so I can't hardcode $_GET["name"] to get it to work properly, and I also can't echo inside any of the classes either. Despite this, I know that $_GET and $_POST are super global variables used to capture HTTP user data, and can be accessed by passing a key like $_GET["username"].. Which I feel is what should be returned. I guess my question is.. How do I do this and not echo out any statements at all, and how would you implement it? Here is the UML diagram that I made.

This is the code that I have thus far: HTTPData.php:

<?php

abstract class HTTPData {

   abstract public function getKey($key);
}
?>

HTTPGetData.php:

<?php

class HTTPGetData extends HTTPData {

public function __construct() {

}

public function getKey() {
   return $this->key;
  }
 }
?>

HTTPPostData:

<?php

class HTTPPostData extends HTTPData{

public function __construct() {

}

public function getKey() {
   return $this->key;
  }


}
?>

index.php:

<?php


 if( isset($_GET['key'])) {
 /*How would I not echo this?*/
}


?>

I know this is not much, but I am seriously having difficulty grasping this in PHP... And any help would be appreciated. My books are just not teaching $_GET and $_POST with abstraction to where I could handle a problem like this. Thank you for your time, and I apologize if this is an easy question that would be dumb to not know the answer to...


Solution

  • You can extract $_GET or $_POST as a dependency to be able to test your classes outside server context:

    abstract class HTTPData
    {
        private $data;
    
        public function __construct(array $data)
        {
            $this->data = $data;
        }
    
        public function getKey($key)
        {
            return $this->data[$key] ?? null;
        }
    }
    

    Then your concrete classes will just inherit this abstract class:

    final class HTTPGetData extends HTTPData
    {
    
    }
    
    final class HTTPPostData extends HTTPData
    {
    
    }
    

    Finally, you can test your classes providing $_GET and $_POST yourself:

    $_GET = ['foo' => 'bar'];
    $_POST = ['baz' => 'quux'];
    
    $httpGetData = new HTTPGetData($_GET);
    $httpPostData = new HTTPPostData($_POST);
    
    assert($httpGetData->getKey('foo') === 'bar');
    assert($httpGetData->getKey('baz') === null);
    
    assert($httpPostData->getKey('baz') === 'quux');
    assert($httpPostData->getKey('foo') === null);
    

    Here is the demo.

    The sane question will be: but why I need the two classes, that share same functionality and differ only in name? To answer this question, we have to look at the concept of dependency injection (DI). With such tool as DI, you can resolve dependencies automatically (well almost). So, when your other class will need an object of either HTTPGetData or HTTPGetData (can be type hinted or configured), the DI container will instantiate the correct class with the correct params array and pass it through.