0

I don't believe this is possible, and searching on Google didn't yield any results, but I thought it never hurts to ask.

I'm trying to implement Google Chart on my site via a PHP library. A library I found that I really like (googlechartphplib) has about 10 different class files for every type of chart. This means that in order to create a pie chart I must use $chart = new GooglePieChart(); whereas to create a QR Code I must use $chart = new GoogleQRCode();, etc.

However when I actually looked into using the API, I noticed that the type of chart is passed to the constructor (it is saved and then later passed to the API as part of the query string). For instance, the code to make a line graph isn't just $chart = new GoogleChart();, it's $chart = new GoogleChart('lc', 500, 200); (where lc defines the "line chart", 500 and 200 are dimensions)

This got me thinking: why can't I just read this first parameter to determine which type of chart to create? Have one universal constructor:

$piechart = new GoogleChart('pie');
$linechart = new GoogleChart('lc');
$qrcode = new GoogleChart('qr');
...

I can think of a way to do this using switch/case statements in all of my function calls. For example:

public function computeQuery() {
    switch( $this->type ) {
        case 'qr':
            /* QR code function */
            break;
        case 'pie':
            /* Pie chart function */
            break;
        case 'lc':
        default:
            /* line chart code */
            break;
    }

However this would involve re-writing all of the code already present (expedited slightly by my ability to copy/paste 90% of the code). Is there a way to simply choose which class the resulting object should be based on the constructor parameters? Example:

public function __construct($type, $x, $y) {
    $this->type = $type;
    switch( $type ) {
        case 'qr':
            return new GoogleQRCode($x, $y);
        case 'pie':
            return new GooglePieChart($x, $y);
        case 'lc':
        default:
            $this->width = $x;
            $this->height = $y;
    }
}

1 Answer 1

5

Not in the constructor, you can't.

That's one reason that Factories exist.

Sign up to request clarification or add additional context in comments.

4 Comments

Looks brilliant. I'll wait a while to see if anyone has other ideas, but I might be doing this. This does impose a new issue, though. Is there a good way to only include a particular class when the factory needs it? It seems like wasted memory to include 10 different class definitions if I'm usually only using one.
Nice. Works perfectly. Still going to wait on the off-chance someone has a more magical solution, but otherwise this works perfectly.
@LeviMorrison: That link has lived it's time. I shamelessly leave a backup in The “Missing” Patterns of the PHP Manual here in comment, I bet you prefer some other reference.
@hakre I picked a new link, for now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.