Update: I edited the code below for the class to correct an error that came up when I ran it (needed "new" to create the object). With that correction, the code runs and correctly generates the HTML. But since I'm new to OOP, I'd still like to know if I've taken the right approach.
2nd update: I address a concern about the efficiency of this technique in the addendum below. I also corrected the order of the anchor name and querystring in the URL, which are handled correctly by hLink().
I have a function that generates HTML for hyperlinks. It's arguments may be string literals or variables read from the database. An example call to this function looks like:
hLink('http://example.com', 'website', 'section', 'input=0', '_blank');
which returns:
'<a HRef="http://example.com?input=0#section" target="_blank">website</a>'
The first argument is required, and the remaining four have defaults.
I'm looking at replacing this function with a method defined in a class, so the function calls would be replaced with calls to that method acting on a call to the class constructor. I'm new to object-oriented programming, so I'd like to know if I'm doing this right, or even if I should be doing this at all.
The class I've come up with is:
class link
{private $sURL;
private $sText = '';
private $sLocn = '';
private $sQuery = '';
private $sWindow = '';
public function __construct($sURL)
{$this->sURL = $sURL;}
public function sText($sText) {$this->sText = $sText; return $this;}
public function sLocn($sLocn) {$this->sLocn = $sLocn; return $this;}
public function sQuery($sQuery) {$this->sQuery = $sQuery; return $this;}
public function sWindow($sWindow) {$this->sWindow = $sWindow; return $this;}
public function hLink()
{...}
}
where the body of method hLink() is the same as the body of the original function hLink().
With this class, the equivalent of the above function call would be:
(new link('http://example.com'))->sText('website')->sLocn('section')->sQuery('input=0')->sWindow('_blank')->hLink()
which is intended to generate the same string as before:
'<a HRef="http://example.com?input=0#section" target="_blank">website</a>'
How does this look? Am I on the right track?
Addendum
It troubled me that the above technique creates a new object for each link on the page, and that object does nothing after it is used once to create the HTML for the link. It's a small object and there won't be more than a few hundred of them on a page, so it won't be a big memory burden, but it still seems wasteful and inefficient. I have an idea for addressing this:
The code for this is as follows: (Pardon my formatting. I know it's unconventional, but I find this easier to read.)
<?php declare(strict_types = 1);
$oLink = new link;
class link
{private $sURL;
private $sText;
private $sAnchor;
private $sQuery;
private $sWindow;
public function clear()
{$this->sURL = '';
$this->sText = '';
$this->sAnchor = '';
$this->sQuery = '';
$this->sWindow = '';
return $this;
}
public function URL(string $sURL) {$this->sURL = $sURL; return $this;}
public function text(string $sText) {$this->sText = $sText; return $this;}
public function anchor(string $sAnchor) {$this->sAnchor = $sAnchor; return $this;}
public function query(string $sQuery) {$this->sQuery = $sQuery; return $this;}
public function window(string $sWindow) {$this->sWindow = $sWindow; return $this;}
public function hLink()
{return('<a HRef="' . $this->sURL .
($this->sQuery == '' ? '' : '?' . $this->sQuery) .
($this->sAnchor == '' ? '' : '#' . $this->sAnchor) .
'"' . ($this->sWindow == '' ? '' : ' target="' . $this->sWindow . '"') .
'>' . $this->sText. '</a>');
}
}
echo('Link to ' . $oLink->clear()->URL('http://example.com')->text('website')->anchor('section')->query('input=0')->window('_blank')->hLink() . ' in text');
I've tested the above code as a freestanding script, and it does output the intended:
Link to <a HRef="http://example.com?input=0#section" target="_blank">website</a> in text
So is this a better way? Now there's only one object that gets reused each time another link is needed on the page. Is this the best way to generate HTML for hyperlinks embedded in text in PHP?
If the s
prefix is meant to indicate it's a string variable, you may want to know that since PHP/7 you can declare scalar arguments type and, in all all versions, docblocks are standard tool that decent IDEs acknowledge.
The code format is also fairly unusual. In the end, trying to make your code compact to make better use of screen space does not really pay off: it's harder on the eyes (trust me, you'll get older) and nobody else is doing it so you can't use your editor's code format features without investing a lot of time reconfiguring it.
Other than that, I don't see anything intrinsically wrong.
Here's a quick example of basically your same code with type hints, docblocks and PSR-2:
class Link
{
/**
* @var string
*/
private $url;
/**
* @var string
*/
private $text = '';
/**
* @param string $url
*/
public function __construct(string $url)
{
$this->url = $url;
}
/**
* @param string $text
* @return Link
*/
public function text(string $text): Link
{
$this->text = $text;
return $this;
}
}