OOP Calling one class from within another

I have a class for building forms and I want to upgrade it to handle Bootstrap. I’d like to use my current methods to build the Bootstrap elements, but I don’t want all of this new Bootstrap code cluttering up my current Forms class, so I’d like to put it into its own class in a separate file.

Below is a very simple example; obviously this doesn’t work and the code is wrong, however, from this you can hopefully see what I’m trying to accomplish.

<?php
class Forms {
    
    public function input_text($name) {
        return '<input type="text" name="'.$name.'">';
    }
}


class Bootstrap {
    
    public function bootstrap_input_text($name,$label) {
        $return  = '<div class="control-group">';
        $return .= '<label class="control-label" for="'.$name.'">'.$label.'</label>';
        $return .= '<div class="controls">';
        
        // use the input_text() method from the Forms class
        $return .= $this->Forms->input_text($name);
        
        $return .= '</div>';
        $return .= '</div>';
        return $return;
    }
}


$form = new Forms();

echo $form->input_text('name');
echo $form->bootstrap_input_text('email','Email');

The way you’re trying to do it is (almost) the decorator pattern. What you’d need to do is require an instance of Forms to be passed in to Bootstrap via the constructor, like this:


class Bootstrap {

    protected $forms;

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

    public function input_text($name, $label) {
        $return  = '<div class="control-group">';
        $return .= '<label class="control-label" for="'.$name.'">'.$label.'</label>';
        $return .= '<div class="controls">';

        // use the input_text() method from the Forms class
        $return .= $this->forms->input_text($name);

        $return .= '</div>';
        $return .= '</div>';
        return $return;
    }

}

$form = new Bootstrap(new Forms);
echo $form->input_text('email', 'Email');

Another approach would be to have Bootstrap inherit from Forms. If you kept the method names the same and made the $label parameter optional, you’d have a drop-in replacement:


class Bootstrap extends Forms {

    public function input_text($name, $label = null) {
        if (empty($label)) {
            $label = ucfirst($name);
        }
        $return  = '<div class="control-group">';
        $return .= '<label class="control-label" for="'.$name.'">'.$label.'</label>';
        $return .= '<div class="controls">';

        // use the input_text() method from the Forms class
        $return .= parent::input_text($name);

        $return .= '</div>';
        $return .= '</div>';
        return $return;
    }
}

$form = new Bootstrap();
echo $form->input_text('email', 'Email');

The method names remain identical, and you use the parent::method syntax to get the results from the original Forms methods.

Dude, your second example gave me a great idea to make this whole thing more flexible and with a ton less code to boot. You’re a genius! :slight_smile:

Thanks!

If a class has already been instantiated you can also get access to it from inside methods of another class by using:

global $class_object;

I’d advise against using globals, they are rarely (if ever) a good solution. In this situation you’d be creating a hidden dependency within the calling class.

Don’t use globals. Globals make code more difficult to maintain and less reusable. Look into dependency injection or a DIC (dependency injection container).

Thanks for the advice. I had been wondering about this myself. Can’t remember where I picked it up from but I have been using it in all my classes!

Just wanted to give you an update. I spoke with other people regarding this issue and they all told me to use the decorator pattern. So I looked into it, and messed around with it a little bit; it was total overkill for what I was doing, but the inheritance example you gave worked perfectly, so I’m incorporating that into my class.

Thanks again :slight_smile:

Keep in mind, that the decorator pattern is by far the best choice here. Inheritance can lead you into a very difficult path here as now your Bootstrap class is dependent on Forms. If anything in Forms is changed, it could have a detrimental affect on your class and it won’t be obvious. Inheritance only makes sense if you can complete this phrase: “X is a Y”, “Bootstrap is a Form”. Does that hold true? If it doesn’t, you should go with the dependency injection approach (the decorator pattern).

The problem that I had with the decorator pattern is that, unless i’m mistaken, i have to add every single method that could be used publicly in my Forms class to my Bootstrap class, which was a huge pain in the ass. I kept receiving errors that a method wasn’t available, and then after I added it to the Bootstrap class the error would stop. And wouldn’t every new decorator class need to have all of the methods added to it as well?

All i’m doing in the Bootstrap class is wrapping HTML around my form objects.

I definitely want to do this the right way, so I’m totally open to whatever anybody has to say. :slight_smile:

I think you should look into the magic method __call that would reduce what you need to build (if all methods utilize the same bootstrap surrounding html.
http://www.php.net/manual/en/language.oop5.overloading.php#object.call

You could effectively have 1 method in your Bootstrap, that takes the method to call for Forms and any additional arguments for that method.

Just want to show proof of concept using __call, I think you’ll like this

test.php

<?php
require_once('forms.class.php');
require_once('bootstrap.class.php');

$forms = new Forms();
$boot = new Bootstrap($forms);
echo $boot->input_text('textbox', 'Name');
echo $boot->input_hidden('hidden', 'Spam Detector');

bootstrap.class.php

<?php
class Bootstrap {
	private $forms;
	public function __construct($forms)
	{
		$this->forms = $forms;
	}

	public function __call($member, $arguments)
	{
		$return  = '<div class="control-group">';
		$return .= '<label class="control-label" for="'.$arguments[0].'">'.$arguments[1].'</label>';
		$return .= '<div class="controls">';

		$return .= $this->forms->$member($arguments[0]);

		$return .= '</div>';
		$return .= '</div>';
		return $return;
	}
}

forms.class.php

<?php
class Forms {
	public function input_text($name) {
		return '<input type="text" name="'.$name.'">';
	}
	public function input_hidden($name) {
		return '<input type="hidden" name="'.$name.'">';
	}
}

Generated HTML (formatting added for visual effect)


<div class="control-group">
  <label class="control-label" for="textbox">Name</label>
  <div class="controls">
    <input type="text" name="textbox">
  </div>
</div>
<div class="control-group">
  <label class="control-label" for="hidden">Spam Detector</label>
  <div class="controls">
    <input type="hidden" name="hidden">
  </div>
</div>

OK, that’s beautiful.

I was looking through various websites and watched a couple video tutorials on magic methods and couldn’t wrap my head around what you were proposing, so thank you for the supplied code! That really made a difference.

Yeah, this looks like the way to go, because I can see a whole bunch of classes for element wrappers. Really simple, easy to use and quickly extendable.

Thanks! :slight_smile:

Your welcome. If you run into any issues/questions as you implement it, feel free to ask them. I think you’ll find this process will work out very well.