How to use interface gracefully

Posted by Sphen001 on Tue, 25 Jun 2019 23:36:00 +0200

Well, 6.1 is just over. We're not babies anymore. Come on, an interface article.

In the process of programming, we should learn how to use interfaces to change our lives and greatly improve our self-ability.
Interface is not a new feature, but it's very important. Here's a small example of interface.

Imagine a class of DocumentStore that collects text from different resources. html can be read from remote url s, resources can also be read, and terminal command output can be collected.

Define the DocumentStore class

class DocumentStore{
    protected $data = [];
    
    public function addDocument(Documenttable $document){
        $key = $document->getId();
        $value = $document->getContent();
        $this->data[key] = $value;        
    }
    
    public function getDocuments(){
        return $this->data;
    }
    
}

Since the parameters of the addDocument() method can only be instances of the class of Documenttable, what about defining the class of DocumentStore? In fact, Document is not a class, but an interface.

Define Documenttable

interface Documenttable{
    public function getId();
    public function getContent(); 
   
}

This interface defines the table name, and any object implementing the Documenttable interface must provide an open getId() method and an open getContent() method.

But what's the use of doing that? The advantage of doing this is that we can define separate classes to obtain stability, and we can use very different methods. Here is an implementation that uses curl to retrieve html from a remote url.

Define the HtmlDocument class

class HtmlDocument extends Documenttable{

    protected $url;

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

    public function getId(){
        return $this->url;
    }

    public function getContent(){
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,$this->url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,3);
        curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
        curl_setopt($ch,CURLOPT_MAXREDIRS,3);
        curl_close($ch);
        return $thml;
    }
}

The next method is to get stream resources.

class StreamDocument extends Documenttable{
    protected $resource;
    protected $buffer;

    public function __construct($resource,$buffer = 4096)
    {
        $this->resource=$resource;
        $this->buffer=$buffer;
    }

    public function getId(){

        return 'resource-' .(int)$this->resource;
    }

    public function getContent(){
        $streamContent = '';
        rewind($this->resource);
        while (feof($this->resource) === false){
            $streamContent .= fread($this->resource,$this->buffer);
        }
        return $streamContent;
    }
}

The next class is to get the execution result of the terminal command line.

class CommandOutDocument extends Documenttable{
    protected $command;
    public function __construct($command)
    {
        $this->command=$command;
    }
    
    public function getId(){
        return $this->command;
    }

    public function getContent(){
        return shell_exec($this->command);
    }

}

Let's demonstrate how to implement the DocumentStore class with the help of the above three classes.


$documentStore = new DocumentStore();

//Add html documents
$htmlDoc = new HtmlDocument('https:// www.i360.me');

$documentStore->addDocument($htmlDoc);

//Adding Stream Documents

$streamDOC = new StreamDocument(fopen('stream.txt','rb'));

$documentStore->addDocument($streamDOC);

//Add Terminal Command Document

$cmdDoc = new CommandOutDocument('cat /etc/hosts');

$documentStore->addDocument($command);

print_r($documentStore->getDocuments());die;

The three classes of HtmlDocument, StreamDocument and CommandOutDocument have nothing in common here, but implement the same interface.

Topics: PHP Programming curl