Link to home
Start Free TrialLog in
Avatar of bdichiara
bdichiaraFlag for United States of America

asked on

Extending a Class and use variables from parent class

I am very new to writing classes and I would like to know how to extend a class so that variables in the parent class are available in the child class. I read up on this at php.net but i get a Warning. Am I doing it wrong? I'm trying to write a Forms class and I want to store all the elements in an array inside the parent class.
class xhtmlForm {
	function xhtmlForm($form_id, $form_name=NULL, $method=NULL, $action=NULL, $submitCode=NULL) {
		$this->form_id = $form_id;
		$this->form_name = ($form_name) ? $form_name : $this->form_id;
		if(isset($method)){
			$this->method = $method;
		}
		$this->action = (isset($action)) ? $action : $_SERVER['REQUEST_URI'];
		$this->submitAction = $submitCode;
	}
}
 
class formElement extends xhtmlForm {
	function formElement() {
		parent::xhtmlForm($this->form_id);
	}
}

Open in new window

Avatar of Beverley Portlock
Beverley Portlock
Flag of United Kingdom of Great Britain and Northern Ireland image

In the example you have given you lack class variables. Each class contains only a function and variables inside the function are "protected". In the example you have given, you have not initialised the parameter you are passing so nothing will work. I would expect  to see something more like




class xhtmlForm {
        function xhtmlForm($form_id, $form_name=NULL, $method=NULL, $action=NULL, $submitCode=NULL) {
                $this->form_id = $form_id;
                $this->form_name = ($form_name) ? $form_name : $this->form_id;
                if(isset($method)){
                        $this->method = $method;
                }
                $this->action = (isset($action)) ? $action : $_SERVER['REQUEST_URI'];
                $this->submitAction = $submitCode;
        }
}
 
class formElement extends xhtmlForm {
        function formElement( $varFormId  ) {
                parent::xhtmlForm($varFormId);
        }
}
 
 
......
 
$f = new formElement( array( ...some values .... ) );

Open in new window

Grr!!! Pressed SUBMIT too soon.... Class variables added below
class xhtmlForm {
 
        protected $form_id;
        protected $form_name;
        protected $method;
        protected $action;
 
        function xhtmlForm($form_id, $form_name=NULL, $method=NULL, $action=NULL, $submitCode=NULL) {
                $this->form_id = $form_id;
                $this->form_name = ($form_name) ? $form_name : $this->form_id;
                if(isset($method)){
                        $this->method = $method;
                }
                $this->action = (isset($action)) ? $action : $_SERVER['REQUEST_URI'];
                $this->submitAction = $submitCode;
        }
 
}
 
class formElement extends xhtmlForm {
        function formElement( $varFormId  ) {
                parent::xhtmlForm($varFormId);
        }
}
 
 
......
 
$f = new formElement( array( ...some values .... ) );

Open in new window

Avatar of bdichiara

ASKER

Sorry, I do have the variables setup in my code, here it is again:
class xhtmlForm {
	var $form_id;
	var $form_name;
	var $method = "post";
	var $action;
	var $fields = array();
	var $submitAction;
	
	function xhtmlForm($form_id, $form_name=NULL, $method=NULL, $action=NULL, $submitCode=NULL) {
		$this->form_id = $form_id;
		$this->form_name = ($form_name) ? $form_name : $this->form_id;
		if(isset($method)){
			$this->method = $method;
		}
		$this->action = (isset($action)) ? $action : $_SERVER['REQUEST_URI'];
		$this->submitAction = $submitCode;
	}
}
 
 
class formElement extends xhtmlForm {
	var $field_id, $field_name, $tag;
 
	function formElement() {
		parent::xhtmlForm($this->form_id);
	}
}
 
 
/* usage */
 
$myForm = new xhtmlForm("stuff");
 
$myForm->formOpen();
 
$name = new formElement();
$name->start("your_name");
$name->addAttribute("class","text");
$name->display(); // this line is supposed to write the element to an array inside the xhtmlForm class
echo "<br />";

Open in new window

Line 15: parent::xhtmlForm($this->form_id);

form_id doesn't exist.
Yes, I know. That is my question. I get this warning when nothing is there because the first value is required. So what is the proper way to extend the formElement class so that I can use variables from the xhtmlForm class?
When I use:

      function formElement() {
            parent::xhtmlForm();
      }

I get:

Warning: Missing argument 1 for xhtmlForm::xhtmlForm()
Well, you're lacking a few methods. I've added in some blank ones, but you would need to fill them out.

<?php
 
class xhtmlForm {
        var $form_id;
        var $form_name;
        var $method = "post";
        var $action;
        var $fields = array();
        var $submitAction;
 
 
        function formOpen() {
          // put some code in here
        }
 
        
        function xhtmlForm($form_id, $form_name=NULL, $method=NULL, $action=NULL, $submitCode=NULL) {
                $this->form_id = $form_id;
                $this->form_name = ($form_name) ? $form_name : $this->form_id;
                if(isset($method)){
                        $this->method = $method;
                }
                $this->action = (isset($action)) ? $action : $_SERVER['REQUEST_URI'];
                $this->submitAction = $submitCode;
        }
}
 
 
class formElement extends xhtmlForm {
        var $field_id, $field_name, $tag;
 
 
        function start( $aString ) {
           // do something
        }
 
        function addAttribute( $str1, $str2 ) {
           // do something
        }
 
     
        function display() {
           // do something
        }
 
     
        
        function formElement() {
                parent::xhtmlForm($this->form_id);
        }
}
 
 
/* usage */
 
$myForm = new xhtmlForm("stuff");
 
$myForm->formOpen();
 
$name = new formElement();
$name->start("your_name");
$name->addAttribute("class","text");
$name->display(); // this line is supposed to write the element to an array inside the xhtmlForm class
echo "<br />";
 
?>

Open in new window

"the formElement class so that I can use variables from the xhtmlForm class?"

You have already done it by using the "extends" keyword. Just the variables like so (code snipped for brevity...)

An extended class has direct access to its anscestor variables and can use them as though they had been declared locally. The only exception are variables labelled "private"

You don't need to redeclare them.

class xhtmlForm {
        var $form_id;
        var $form_name;
        var $method = "post";
        var $action;
        var $fields = array();
        var $submitAction;
 
   ...... snip !
 
}
 
 
class formElement extends xhtmlForm {
 
     $this->action = "12345";
     $this->fields = array( 1,2,3,4 );
 
}
 

Open in new window

Here's the issue. If I try:

print_r($myForm->fields);

It dislays an empty array. So, what's happening is all my elements are not collecting in the same array. I would expect the following to occur.
$myForm = new xhtmlForm("stuff");
 
$myForm->formOpen();
 
$name = new formElement();
$name->start("your_name");
$name->addAttribute("class","text");
$name->display();
echo "<br />";
	
$phone = new formElement();
$phone->start("phone");
$phone->saveValue = false;
$phone->addAttribute("class","text");
$phone->addStyle("width:250px");
$phone->display();
echo "<br />";
 
$username = new formElement();
$username->start("user");
$username->setDefault("Type Your Username");
$username->addAttribute("class","text");
$username->display();
echo "<br />";
 
$remember = new formElement();
$remember->start("mycheckbox","mycheckboxes[]");
$remember->setType("checkbox");
$remember->setValue(1);
$remember->display();
echo "<br />";
 
$password = new formElement();
$password->start("pass");
$password->addAttribute("class","text");
$password->setType("password");
$password->display();
echo "<br />";
 
$submit = new formElement();
$submit->start("submitBtn","");
$submit->setType("submit");
$submit->addAttribute("class","button");
$submit->setValue("Go!");
$submit->display();
 
$myForm->formClose();
 
 
// i would expect the following line:
print_r($myForm->fields);
 
// to show me an array of every field added above. since "display()" puts them into the array:
function display(){
	$this->build(); // create the xhtml, store it in main array
	print $this->fields[$this->field_id]; //show the xhtml
}
function build(){
	// do a bunch of stuff and put it in $this->whole_element
	$this->fields[$this->field_id] = $this->whole_element;
}

Open in new window

if I try:

print_r($name->fields);

it shows me an array with 1 item. So the fields variable is separate for each formElement class. I want it to be the same variable and be grouped by the xhtmlForm class.
SOLUTION
Avatar of Beverley Portlock
Beverley Portlock
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ok, i think i understand this, but if I was to do this:

$form = new managedForm();
$form->add( new formElement( "user", "Type your username", array("class", "text"), ""  ) );
$form->add( new formElement( "password", "Type your password", array("class", "text"), ""  ) );

How would I access those elements to change attributes on them, without having a huge list of parameters in the formElement function?

Right now, I can specify the essentials:

$username = new formElement("user");
$username->display();

Using what you showed me, I can now do:

$username = new formElement("user");
      $myForm->add($username->build()); // optional
$username->display();

but if i want to add more options to the field, i would do:

$username = new formElement("user");
$username->setDefault("Type Your Username");
$username->addAttribute("class","text");
      $myForm->add($username->build()); // optional
$username->display();

and i'm not sure how to do that with yours...

Also, I would LIKE to have that element added to the $myForm->field_array when i do $username->display(); using $myForm->add()  just adds one extra step, and this part really isn't necessary most of the time, I would just like the entire form object to be accessible if needed. (for debugging or whatever)....
bdichiara said "How would I access those elements to change attributes on them, without having a huge list of parameters in the formElement function?"

The convention is to have "setters and getters" for each element, thus

function setDisplay( $d ) {
    $this->display = $d;
}

function getDisplay() {
    return $this->display;
}

so you could then do   $username->setDisplay("some value");

In PHP4 (or using the "var" declaration) you can actually access the variable directly from outside the class, but this is considered bad practice. Thus

$username->display = "some value";





bdichiara said: "i want to add more options to the field"

I'm not sure I understand your meaning. Can you clarify please?



bidchiara said "I would LIKE to have that element added to the $myForm->field_array when i do $username->display(); using $myForm->add()"

Keep it simple and just make sure that you do the $myForm->add(...) as the last thing. Trivial to do it that way and it massively simplifies your programming task. Don't make your life any harder than has to be. Keep it simple.... ;-)

I guess you sort of answered my 2nd question in the first part. I should probably "prepare" my element as a new object (like $username = new formElement("username")). Then put that object in my form object like $myForm->add($username);

In the last part, I was asking if it is possible to skip having to add the element into the form object and do it somehow inside the formElement class. For example, inside the formElement class i have a "build()" function that takes all the information you've provided (id, name, type, styles, etc) and puts it together into a string format (like "<input id="blah"... />). Ideally at the end of the build function, it would take my string and put it into the $myForm->fieldArray. I guess maybe you're saying not do to that at all. It would make creating forms just a tad bit easier:
$myForm = new xhtmlForm("formID");
$myForm->open();
 
$myElement = new formElement("elementID");
$myElement->inputType("checkbox");
$myElement->build(); // or $myElement->display(); would be the same as build() but show it on the page.
 
// compared to:
 
$myElement = new formElement("elementID");
$myElement->inputType("checkbox");
$myElement->build();
$myForm->add($myElement);
 
$myForm->close();

Open in new window

Generally, set up the object / class with all the values required and then called your "factory method" to build something. That is usually the simplest approach. Given the exmaples you have posted, I would prefer the first method to the second.

I would have to agree with you 100%, however it brings me right back to my initial question. How can I add the string element created inside the build function (found in the formElement class) to the fieldArray (found in the xhtmForm class)?

I don't understand what you mean when you say "factory method".
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial