我看过类似的类似问题,其中提供的解决方案似乎都没有回答我的问题。
这是我到目前为止的代码(只是学习OOP):
<?php
class page {
var $ot;
function begin(){
$this->ot = '';
}
function finish(){
echo $this->ot;
}
class forms extends page {
function __construct($form_action, $form_type){
$this->ot .= '<form action=' . $form_action . ' method=' . $form_type . ' />';
}
function create_input($type, $name){
$this->ot .= '<input type="' . $type . '" name="' . $name . '" /><br />';
}
function create_submit($value){
$this->ot .= '<input type="submit" value="' . $value . '" />';
}
function __destruct(){
$this->ot .= '</form>';
}
}
class labels extends page {
function create_label($label){
$this->ot .= '<label>' . $label . ' </label>';
}
}
$page = new page();
$page->begin();
$newform = new forms('/class_lib.php', 'GET');
$newlabels = new labels();
$newlabels->create_label('Username:');
$newform->create_input('text', 'username');
$newlabels->create_label('Password:');
$newform->create_input('password', 'password');
$page->finish();
?>
由于某种原因,此代码不会向浏览器输出任何内容。但是,如果我更改子类 forms 和 labels 来回显它们的输出而不是将它存储在父变量中,那么代码似乎会按照预期生效并按预期工作。 / p>
请原谅我的无知,因为我是OOP的新手。
谢谢!
答案 0 :(得分:1)
对象并未真正连接。
您创建了三个新对象,但它们从不相互引用。
试试这个
// Create a new form
$newform = new forms('/class_lib.php', 'GET');
$newform->create_input('text', 'username');
$newform->create_input('password', 'password');
// Output the form, it can use the finish() method because it extends page
$newform->finish();
这将工作并输出<input>
元素,但您的label
类未插入$newForm
来执行任何操作,它刚刚创建并完全独立。
你需要PHP5来运行它,它并不完美,但它是一个好的开始!我已经定义了以下一个名为renderable的接口和名为element,input,label和form的类
// An interface describes the methods that a class must use
interface renderable
{
// Any classes that implement the renderabe interface must define a method called render()
function render();
}
// This abstract class can never be created, so you can never do new element(), it implements renderable
abstract class element implements renderable
{
// Set up some variables for all elemnts
var $attribs = array();
var $name = "";
var $type = "";
// The construct for a element needs a type and a name
function __construct($type, $name)
{
$this->name = $name;
$this->type = $type;
}
// Set an attribute for the element
function setAttribute($name, $value)
{
$this->attribs[$name] = $value;
}
// Get the name of this element
function getName()
{
return $this->name;
}
// The render function outputs an element
function render()
{
// Output the start of the element eg <input
echo "<" . $this->type . " ";
// each attribute eg class='blue'
foreach($this->attribs as $name => $value)
echo " " . $name . "='" . $value ."' ";
// end the element
echo " />";
echo "<br />";
}
}
// The input element extends element but is not abstract
class input extends element
{
// Nothing is overridden here from the parent class element
}
// The label element extends element but is not abstract
class label extends element
{
// Define a new var called label, this is special for the label element
var $label = "";
// Override the contruct for element to only accept a name, this
// is because the label element type will always be label
function __construct($name)
{
$this->name = $name;
$this->type = "label";
}
// Set the label var
function setLabel($label)
{
$this->label = $label;
}
// Override the render function, this means that label has its own render function
// and does not use the function from the abstract class element
function render()
{
echo "<" . $this->type . " ";
foreach($this->attribs as $name => $value)
echo " " . $name . "='" . $value ."' ";
echo " >";
// Here the special label content is displayed
echo $this->label;
echo "</label>";
}
}
// A form extends element
class form extends element
{
// A form has some new vars
var $elements = array();
var $labels = array();
var $action;
var $method;
// Override the contruct and use name, action and method
// There are default values for action and method so they are not required
function __construct($name, $action = "/", $method = "GET")
{
$this->name = $name;
$this->type = "form";
$this->action = $action;
$this->method = $method;
}
// Add a new element to the form along with its label
function appendElement($element, $label)
{
// Add these to an array inside this class
$this->elements[$element->getName()] = $element;
$this->labels[$label->getName()] = $label;
}
// Override the render function
function render()
{
// Output the form's start along with the method and action
echo '<' . $this->type. ' ' . 'action="' . $this->action . '" method="' . $this->method . '" />';
// Iterate over the array of elments and render each one
foreach($this->elements as $name => $ele)
{
// Render the label for the current element
$this->labels[$name]->render();
// Render the element
$ele->render();
}
// End the form
echo "</form>";
}
}
// Create form with name, action and method
$form = new form("login", "/login.php", "POST");
// Create input username
$ele = new input("input", "username");
// Set type
$ele->setAttribute("type", "text");
// Set a class
$ele->setAttribute("class", "blue");
// Create a label for the username long with its content
$label = new label("username");
$label->setLabel("Username: ");
// Add the username element and its label
$form->appendElement($ele, $label);
// Repeat for password
$ele = new input("input", "password");
$ele->setAttribute("type", "password");
$label = new label("password");
$label->setLabel("Password: ");
$form->appendElement($ele, $label);
// Render the form
$form->render();
答案 1 :(得分:1)
$ot
是一个对象属性。这意味着,类page
或任何子类的每个对象都有自己的$ot
“版本”。现在您实例化一些对象并设置一些值,但最后,当您致电$page->finish();
$page->ot
时,无论如何都是空的。
答案 2 :(得分:1)
在OOP中,您有类(类型)和类(对象)的实例。 $ot
属性是您所谓的实例变量,它属于您创建的实例(对象),而不是类本身的属性。
通过使表单成为页面的子类,您可以获得所谓的“是一个”类之间的关系。这意味着表单将继承页面类的结构。在这种情况下,修改子类对象的属性不会影响超类对象或任何其他对象。
首次创建页面对象时,该对象具有$ot
属性。创建表单类型的对象时,该对象具有自己的$ot
属性。
要了解OOP的概念,我建议您阅读一些教程。您可以从阅读本维基百科文章的类,实例和继承部分开始:
答案 3 :(得分:1)
由于您正在学习OOP,现在是时候了解Abstract
Classes (PHP Manual)!
抽象类是一种定义一系列泛型函数的骨架类。抽象类永远不能被实例化(即,您不能调用new AbstractClass
),但可以被其他类extend
编辑。这允许我们定义一些通用且可重复的东西,例如和HTML元素,然后随着时间的推移将其扩展到特定的HTML元素。以下是该概念的示例实现。
abstract class HTMLWriter
{
protected $html = '';
protected $tagName = null;
protected $selfClosing = false;
protected $elements = array();
protected $attributes = array();
protected $closed = false;
abstract public function __construct();
public function addElement(HTMLWriter $element)
{
if ($this->closed || $this->selfClosing) {
return;
}
$element->close(); // automatic!
$this->elements[] = $element->write();
}
public function addElements() {
foreach (func_get_args() as $arg) {
if ($arg instanceof HTMLWriter) {
$this->addElement($arg);
}
}
}
public function addAttribute($name, $value)
{
return $this->attributes[$name] = $value;
}
public function write()
{
if (!$this->closed) {
$this->close();
}
return $this->html;
}
public function close()
{
$this->closed = true;
$this->html = '<' . $this->tagName;
foreach ($this->attributes AS $attr => $val) {
$this->html .= ' ' . $attr . '="' . $val . '"';
}
if ($this->selfClosing) {
$this->html .= '/>';
return;
}
$this->html .= '>';
foreach($this->elements as $elem) {
$this->html .= $elem;
}
$this->html .= '</' . $this->tagName . '>';
}
}
abstract class HTMLWriterWithTextNodes extends HTMLWriter
{
//abstract public function __construct();
public function addText($text)
{
$this->elements[] = htmlentities($text);
}
public function addTextRaw($text)
{
$this->elements[] = $text;
}
}
注意:具体类是任何非抽象类,尽管该术语在应用于不是抽象类扩展的类时会失去其含义。
class Form extends HTMLWriter
{
public function __construct($action, $method, $can_upload = false)
{
$this->tagName = 'form';
$this->addAttribute('action', $action);
$this->addAttribute('method', $method);
if ($can_upload) {
$this->addAttribte('enctype','multipart/form-data');
}
}
}
class Input extends HTMLWriter
{
public function __construct($type, $name, $id = null)
{
$this->tagName = 'input';
$this->selfClosing = true;
$this->addAttribute('type', $type);
$this->addAttribute('name', $name);
if (!is_null($id)) {
$this->addAttribute('id', $id);
}
}
// overrides
public function addElement()
{
return false;
}
}
class Label extends HTMLWriterWithTextNodes
{
public function __construct($labelText = null, $for = null)
{
$this->tagName = 'label';
if (!is_null($labelText)) {
$this->elements[] = $labelText;
}
if (!is_null($for)) {
$this->addAttribute('for', $for);
}
}
}
class GenericElement extends HTMLWriterWithTextNodes
{
public function __construct($tagName, $selfClosing = false)
{
if (empty($tagName)) {
$this->closed = true;
$this->html = '';
return;
}
$this->tagName = $tagName;
$this->selfClosing = (bool)$selfClosing;
}
}
$form = new Form('/class_lib.php','get');
$username = new Input('text','username','username');
$password = new Input('password','password','password');
$submit = new Input('submit','login');
$submit->addAttribute('value','login');
$ulabel = new Label('Username: ', 'username');
$plabel = new Label('Password: ','password');
$br = new GenericElement('br',true);
$form->addElements(
$ulabel, $username, $br,
$plabel, $password, $br,
$submit
);
echo $form->write();
<form action="/class_lib.php" method="get"><label for="username">Username: </label><input type="text" name="username" id="username"/><br/><label for="password">Password: </label><input type="password" name="password" id="password"/><br/><input type="submit" name="login" value="login"/></form>
抽象类的万岁!