ООП: Класс должен содержать несколько экземпляров другого класса. Как реализовать.

Leonid

PHP? нет, не слышал...
ООП: Класс должен содержать несколько экземпляров другого класса. Как реализовать.

Задача такая. Создаю класс для формирования HTML-формы.

PHP:
class HTMLForm  //  Скорее всего абстрактный класс, т.к. для каждой конкретной формы будет свой надкласс
{
   var FormTitle; // название формы
   var FormHTML;

   function FormStart()
   {
     //  начало формы
     $this->FormHTML = '<form><h1>'.$this->FormTitle.'</h1>';
   }

   function FormEnd()
   {
    //  конец формы
     $this->FormHTML .= '</form>';
   }

   function GetElements()
   {
    //  функция для заполнения формы элементами text, select и пр.
   }

   function __construct()
   {
    $this->FormStart();
    $this->GetElements();
    $this->FormEnd();
   }
 
   function GetForm()
   {
   return $this->FormHTML;
   }
}
Есть класс FormElement для описания абстрактного элемента формы и его классы наследники для каждого типа элемента - FormElementText, FormElementSelect. У каждого из этих классов есть метод GetElement для получения HTML кода элемента.

PHP:
class FormElement
{
   var $Value, $Name;
   var $ElementHTML;

   function ElStart()
   {
    $this->ElementHTML = $this->$title.'<br>';
   }
   
    function  CreateElementHTML()
   {
    $this->ElStart();
    $this->ElContent($this->Value,$this->Name)
   }

   abstract function ElContent($Value,$Name); 
   
   function GetElement()
   {
    return $this->ElementHTML;
   }

}


class FormElementText extends FormElement
{
  function ElContent($Value,$Name)
  {
   return '<input type ="text" name = "'.$Name.'" value=".$Value."> ';
  }
}

Теперь можем создавать какую либо форму (точнее новый класс)
PHP:
class Form1 extends Form
{
function GetElements()
  $item = new FormElementText;
  $item-> Name = 'Login';
  $item-> Value = 'mylogin';
  $item-> CreateElementHTML();

  $FormHTML .= $item->GetElement();
  //  Хотя конечно правильнее иметь функции SetName и SetValue,  или запихнуть их установку в конструктор, но в данном случае не важно


 $item = new FormElementText;
  $item-> Name = 'Username';
  $item-> Value = 'Вася';
  $item-> CreateElementHTML();

  $FormHTML .= $item->GetElement();


  return $FormHTML;
}

Прошу прощения за большой код, но вопрос такой. Это грамотный подход, или можно как-то попроще?
 

jonjonson

Охренеть
А зачем это все?
Что вы собираетесь этим добиться?
Не больше ли код вашей Form1 нежели такой:
PHP:
<form action="<?=$_SERVER['SCRIPT_NAME']?>" method="post">
<input type="text" name="Login" value="myLogin" /><br />
<input type="text" name="Username" value="Вася" /><br />
<iput type="submit" value="и нахрена эта форма?" />
</form>
А кроме того нужно еще знать как оно работает ваше Form1...
И еще... Добавьте label или JavaScript в свое творение...
Если и появляются универсальные обработчики форм, то как результат опыта и набранного и осознанного кода. В данном случае ваше изобретение пустое. Впрочем судя по вопросу вы сами об этом догадываетесь.
 

Leonid

PHP? нет, не слышал...
Данный код я привел для примера, на самом деле он конечно в разы сложнее, там и генерация JavaScript кодов для проверки корректности и заполненности форм, и формирование сложных элементов напрмер для ввода дат - поле с кнопкой "Календарь", или выбор файла из уже загруженных на сервер.
Я имел в виду сам подход.
Когда Форм много (в админке), и они достаточно большие, намого проще просто перечислить их элементы, а система сама бы сформировала весь нужный код и привязала его к дизайну.

-~{}~ 06.01.07 11:39:

В идеале формирование формы должно быть что-то типа такого
PHP:
$form = new Form('MyForm');
$form->AddElement(new ElementFormText('Login'));
$form->AddElement(new ElementFormText('UserName'));
$form->ShowForm;
-~{}~ 06.01.07 11:40:

А почему бы и нет. Ведь так можно...

-~{}~ 06.01.07 11:43:

И отпадает необходимость в Form1 extends Form
 

jonjonson

Охренеть
Leonid, я бы посоветовал вам изучить имеющие место генераторы форм, если вас так тянет на "автоматизацию".
И еще отмечу... ИМХО ошибка вставлять в генератор формы её валидацию. Валидация относится к контроллеру и модели (Controller и Model), а генерация и вывод формы к виду (View) в MVC.

Лучше уж для вывода формы с её полями отписать helper'ы, а не соединять это в нечто монолитное.
 

Leonid

PHP? нет, не слышал...
Не понял, какое отношение имеет MVС к процессу проверки функцией JavaScript заполнено поле "Имя" или нет при нажатии Submit....
Обработка данных формы естественно вынесена в отдельный файл
 

tf

крылья рулят
Обработка данных формы естественно вынесена в отдельный файл
скажи пожалосто зачем?
т.е. у тебя в одном файле форма инициализируется а в другом обрабатывается?
 

Leonid

PHP? нет, не слышал...
Да. Э что в этом удивительного? Причем в одном файле может быть и не один обработчик, а несколько. Например одна и та же форма используется для добавления и редактирования новости, формируется она в файле, который также выводит список новостей для выбора, выбор категории новости. А в отдельном файле может быть например 6 разных обработчиков - добавление новости, сохранение измененй, удаление, добавление, редактирование, удаление новостной категории... Хотя конечно эти обработчики работают по единому признаку и содержат 3-4 строки кода - Получаем $_POST, вызываем функцию формирования SQL кода c 3 параметрами (Update/delete/insert + table_name + $_POST), выполнение SQL, возврат к форме (Header: Location....)

-~{}~ 06.01.07 13:25:

Функция формирования SQL вообще универсальная не только для новостей, а вообще для всех форм
 

tf

крылья рулят
Например одна и та же форма используется для добавления и редактирования новости
ну это не проблема использовать вообще один код для редактирования и создания новости (это уменьшить существование ненужного кода в раз)
вызываем функцию формирования SQL кода c 3 параметрами (Update/delete/insert + table_name + $_POST)
(Update/delete/insert + table_name + heandler($_POST))
а зачем для delete передавать post данные - т.е. у тебя эта функция контролер?
 

Leonid

PHP? нет, не слышал...
а зачем для delete передавать post данные - т.е. у тебя эта функция контролер?

Ну, надо же знать, что удалять. А в $_POST есть ID записи в таблице.

heandler - это зачем?
 

tf

крылья рулят
heandler - обработка данных
DELETE FROM table WHERE parent='5' and visible='yes'
как твоя функция определит что надо выполнить именно это?
имхо - функция создания sql запроса должна создавать sql запрос, по переденные данным, а подготовкой данных должна заниматся другая функция/ объект
 

Leonid

PHP? нет, не слышал...
Ну, в принципе такая функция нужна, но в более простом случае, когда удаляешь только какую-то одну новость, достаточно иметь $_POST[id] = ID новости.
А все остальных случаях (Insert, Update) поля в форме просто имею те же имена, что и поля в таблице, плюс префикс
str_, int_, dat_, чтобы функция во первых поняла, что эта переменная должна быть помещена в SQL запрос, и обработать ее тип, например dat_newsdate = '28.01.2007' предварительно преобразовать к виду timestamp
 

tf

крылья рулят
ООП: Класс должен содержать несколько экземпляров другого класса. Как реализовать.
массивами ;)
Хотя конечно правильнее иметь функции SetName и SetValue, или запихнуть их установку в конструктор
сделай это

ps/ если бы я сейчас начал писать обработчки форм то сделал бы так
зы получились теже яйца, тоже вид сбоку :D
PHP:
class heandler_form() {
	private $element = array();

	function addElement($obj) {
		$this->element[] = $obj;
	}

	function getElement($name) {
		return $this->element[$name];
	}

	function html_tag($name) {
		return $this->getElement($name)->html_tag();
	}
}

class html_input() {
	private $name;
	private $option = array();

	function __construct($name) {
		$this->name = $name;
	}

	function addOption($name, $value){
		$this->option[$name] = $value;
	}
}


$text = new html_input('password');
$text->addOption('type', 'hidden');

$form = new heandler_form();
$form->addElement($text);
-~{}~ 06.01.07 14:04:

str_, int_, dat_, чтобы функция во первых поняла, что эта переменная должна быть помещена в SQL запрос, и обработать ее тип, например dat_newsdate = '28.01.2007' предварительно преобразовать к виду timestamp
добавиш в обработчик форм преобразование данные к нужному типу и в префиксах небудет необходимости
 

Leonid

PHP? нет, не слышал...
Автор оригинала: tf

добавиш в обработчик форм преобразование данные к нужному типу и в перфиксах небудет необходимости
Все таки он нужен, так как в $_POST могут быть и переменные, которые пихать в SQL не нужно, либо в случае ID (без префикса int_) знаем, что это ключ и его надо поместить в where id = ...

-~{}~ 06.01.07 14:10:

У меня сейчас тоже сделано массивами: берется массив объектов типа FormElement_Имя типа_ и в цикле выводятся элемеенты. Но как-то это не красиво, не ООП-шно :)
 

tf

крылья рулят
Все таки он нужен, так как в $_POST могут быть и переменные, которые пихать в SQL не нужно, либо в случае ID (без префикса int_) знаем, что это ключ и его надо поместить в where id = ...
обработчк должен выбрать нужные данные, превести к нужному тебе формату, и вернуть массив корретныъ данных
твой префик будет заменен на свойство элемента формы
ты будеш работать уже не с post а именно твоими нужными данными
зачем нужны будут потом префиксы?

массив объектов не OOП-шно интересно почему?
а как должно?
 

Leonid

PHP? нет, не слышал...
Автор оригинала: tf
обработчк должен выбрать нужные данные, превести к нужному тебе формату, и вернуть массив корретныъ данных
твой префик будет заменен на свойство элемента формы
ты будеш работать уже не с post а именно твоими нужными данными
зачем нужны будут потом префиксы?
функция формирования SQL не знает, какие поля есть в данной таблице, каких нет. Она универсальная для любой таблицы. Она просто в цикле берет все переменные из $_POST, смотрит - есть префикс -приводим к нужному типу, пихаем в SQL, нет префикса - игнорируем.

массив объектов не OOП-шно интересно почему?
а как должно?
Ну не знаю, работать- то работает, но нет красоты кода :)

-~{}~ 06.01.07 14:21:

И алгорить такой - создали объект, запихнули в массив и тд.
Потом передали массив в функцию Функция извлекает объект из массива, выводит результат. Наверне правильно просто их последовательно указать
 

tf

крылья рулят
функция формирования SQL не знает, какие поля есть в данной таблице, каких нет. Она универсальная для любой таблицы. Она просто в цикле берет все переменные из $_POST, смотрит - есть префикс -приводим к нужному типу, пихаем в SQL, нет префикса - игнорируем.
хм, наверное это мертвый случай...

зачем ты пиши обрабочик форм?
 

Leonid

PHP? нет, не слышал...
Автор оригинала: tf
хм, наверное это мертвый случай...

зачем ты пиши обрабочик форм?
Не понял. Что значит мертвый случай?

-~{}~ 06.01.07 14:24:

Я не говорю, что она подходит для любых задач. Но для админки, выполняющей добавление, удаление, правку новости или раздела сайта прекрасно подходит
 

tf

крылья рулят
мертвый - значит мое объекнение почему префиксы не нужны не доходит... ну и ладно
делай как знаеш, ответ ты уже поучил

ps/ мы каждый день делаем велосипеды :)))
 

Leonid

PHP? нет, не слышал...
ну объясни, почему префиксы не нужны. Как тогда отличить нужный параметр, от ненужного? Ну, можно конечно получить список полей таблицы и их типы, но это сложнее...

-~{}~ 06.01.07 14:37:

Хотя при формировании формы можно сделать отдельный список нужных полей с указанием их типа...

-~{}~ 06.01.07 14:39:

Либо у класса Form сделать метод форомирования и даже выполнения SQL....

-~{}~ 06.01.07 14:40:

Вот так сам с собой поговоришь, что-нибудь умное узнаешь.... :)
 

tf

крылья рулят
Хотя при формировании формы можно сделать отдельный список нужных полей с указанием их типа...
Либо у класса Form сделать метод форомирования и даже выполнения SQL....
неа, форматирования +, sql -

пример того что я сейчаю юзаю
PHP:
$form->add_object('pos',	array('type'=>'text', 'float'=>1, 'old'=>1));
$form->add_object('int',	array('type'=>'text', 'int'=>1, 'old'=>1));
$form->add_object('float',	array('type'=>'text', 'float'=>1, 'old'=>1));
на выходе после обработки данных array(
'pos'=>1.5
'int'=>24
'float'=>3.6
)
в отоге у тебя только нужные отформатированне данные, об это я тебе и твердил, потом делай с ними что хочеш, хоть в базу пихай, фиолетово
 
Сверху