За последние 24 часа нас посетили 63117 программистов и 1742 робота. Сейчас ищут 1168 программистов ...

классы

Тема в разделе "PHP для новичков", создана пользователем osvical, 6 июн 2015.

  1. osvical

    osvical Новичок

    С нами с:
    9 янв 2015
    Сообщения:
    67
    Симпатии:
    0
    Здравствуйте. Помогите пожалуйста разобраться, как правильно работать с классами. Задача такая - создать объект Table и, манипулируя им, создать любую html табличку. То, что написал сейчас я, большей частью работает, но такое чувство, что подход не правильный. Кроме объекта "таблица" создаются объекты "строка" и "ячейка" и доступ к ним публичный. Т.е. можно написать new Tr и создастся строка, хотя, по идее, создавать строки должен уметь только класс Table, из вне это делать не к чему. Можно как-то заприватить один класс для всего, кроме другого класса? =) Или вообще не правильно подхожу к вопросу.

    Это было про подход, но есть еще и косяк...
    Вот это будет работать:
    Код (PHP):
    1.   $table= new Table(2,2);
    2.   $table->addAttr('border','1');
    3.  
    Это нет:
    Код (PHP):
    1.   $table= new Table(2,2);
    2.   $table->trArr[0]->addAttr('border','1');
    3.  
    Не могу врубиться, почему =( Вот класс:
    Код (PHP):
    1. <?
    2. interface TableTnterface{
    3.     public function __construct($trNum=0,$tdNum=0,$caption='');
    4.     public function writeCell($trNum,$tdNum,$content);
    5.     public function addRow($num=1);
    6.     public function addCol($num=1);
    7.     public function addAttr($attr,$val);
    8.     public function getHtml();
    9. }
    10. abstract class Attributable{
    11.     public $attrArray;
    12.     public function addAttr($attr,$val){
    13.         $this->attrArray[$attr]= $val;
    14.     }
    15.     public function getAttrStr(){
    16.         $attrStr= '';
    17.         foreach($this->attrArray as $name=>$value){
    18.             $attrStr.= ' '.$name.'="'.$value.'"';
    19.         }
    20.         return $attrStr;
    21.     }
    22. }
    23. class Td extends Attributable{
    24.     public $content;
    25.     public function __construct($content='',$attrArray=array()){
    26.         $this->content= $content;
    27.         $this->attrArray= $attrArray;
    28.     }
    29.     public function getHtml(){
    30.         return '<td'.$this->getAttrStr.'>'.$this->content.'</td>';
    31.     }
    32. }
    33. class Tr extends Attributable{
    34.     public $tdArr= array();
    35.     public function __construct($tdNum=0,$attrArray=array()){
    36.         for($i=0;$i<$tdNum;$i++){
    37.             $this->tdArr[]= new Td();
    38.         }
    39.         $this->attrArray= $attrArray;
    40.     }
    41.     public function addTd($num=1){
    42.         for($i=0;$i<$num;$i++){
    43.             $this->tdArr[]= new Td();
    44.         }
    45.     }
    46.     public function getHtml(){
    47.         $tdsStr= '';
    48.         foreach($this->tdArr as $td){
    49.             $tdsStr.= $td->getHtml();
    50.         }
    51.         return '<tr'.$this->getAttrStr.'>'.$tdsStr.'</tr>';
    52.     }
    53. }
    54. class Table extends Attributable implements TableTnterface{
    55.     public $caption;
    56.     private $trNum;
    57.     private $tdNum;
    58.     public $trArr= array();
    59.     public function __construct($trNum=0,$tdNum=0,$caption=''){
    60.         for($i=0;$i<$trNum;$i++){
    61.             $this->trArr[]= new Tr($tdNum);
    62.         }
    63.         $this->caption= $caption;
    64.         $this->trNum= $trNum;
    65.         $this->tdNum= $tdNum;
    66.     }
    67.     public function addRow($num=1){
    68.         for($i=0;$i<$num;$i++){
    69.             $this->trArr[]= new Tr($this->tdNum);
    70.         }
    71.         $this->trNum+= $num;
    72.     }
    73.     public function addCol($num=1){
    74.         for($i=0;$i<$this->trNum;$i++){ //для всех строк
    75.             $this->trArr[$i]->addTd($num);
    76.         }
    77.         $this->tdNum+= $num;
    78.     }
    79.     public function writeCell($trNum,$tdNum,$content){
    80.         if($trNum>$this->trNum){ //если строки нет
    81.             $this->addRow($trNum-$this->trNum);
    82.         }
    83.         if($tdNum>$this->tdNum){ //если столбца нет
    84.             $this->addCol($tdNum-$this->tdNum);
    85.         }
    86.         $this->trArr[$trNum-1]->tdArr[$tdNum-1]->content= $content;
    87.     }
    88.     public function getHtml(){
    89.         $caption= '';
    90.         if($this->caption) $caption= '<caption>'.$this->caption.'</caption>' ;
    91.         $trsStr= '';
    92.         foreach($this->trArr as $tr){
    93.             $trsStr.= $tr->getHtml();
    94.         }
    95.         return '<table'.$this->getAttrStr().'>'.$caption.'<tbody>'.$trsStr.'</tbody></table>';
    96.     }
    97. }
    98.  
    PHP, JavaScript, SQL и другой код пишите внутри тегов
    Код ( (Unknown Language)):
    1. [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
     
  2. p@R@dox 55RU

    p@R@dox 55RU Зэк
    [ БАН ]

    С нами с:
    21 май 2014
    Сообщения:
    1.358
    Симпатии:
    7
    Адрес:
    с планеты Ялмез
    видимо, свойство
    Код (Text):
    1. $table->trArr[0]
    не обладает методом
    Код (Text):
    1. addAttr
    ну, а что бы врубиться, нужно чуток почитать про ОПП и поковырять :)
     
  3. osvical

    osvical Новичок

    С нами с:
    9 янв 2015
    Сообщения:
    67
    Симпатии:
    0
    обладает... это свойство является массивом из объектов Tr. Эти объекты наследуют метод через extends Attributable. Так же, как и объекты Table. Но с объектами Table все работает, а с Tr нет. Хотя оба extends Attributable.

    Добавлено спустя 9 минут 52 секунды:
    при попытке $table->trArr[0]->addAttr('border','1'); выдает ошибку
    в сроке 17:
    Код (PHP):
    1. abstract class Attributable{
    2.     public $attrArray;
    3.     public function addAttr($attr,$val){
    4.         $this->attrArray[$attr]= $val;
    5.     }
    6.     public function getAttrStr(){
    7.         $attrStr= '';
    8.         foreach($this->attrArray as $name=>$value){ //это строка 17
    9.             $attrStr.= ' '.$name.'="'.$value.'"';
    10.         }
    11.         return $attrStr;
    12.     }
    13. } 
    т.е. плохой аргумент для foreach. В объектах Table он не плохой, а в Tr почему-то плохой =)

    PHP, JavaScript, SQL и другой код пишите внутри тегов
    Код ( (Unknown Language)):
    1. [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
     
  4. p@R@dox 55RU

    p@R@dox 55RU Зэк
    [ БАН ]

    С нами с:
    21 май 2014
    Сообщения:
    1.358
    Симпатии:
    7
    Адрес:
    с планеты Ялмез
    а что показывает
    Код (Text):
    1. var_dump($this->attrArray);
    перед этим циклом? ))
     
  5. osvical

    osvical Новичок

    С нами с:
    9 янв 2015
    Сообщения:
    67
    Симпатии:
    0
    Туда вообще пустая переменная приходит. Хотя, по идее, я ее задаю так:
    $table->trArr[0]->addAttr('border','1');
    Как я понимаю, что должно происходить:
    Берется первый объект Tr из trArr свойства-массива объекта Table. Т.е. первая строка таблицы. Этот объект Tr наследует свойство $attrArray и метод addAttr($attr,$val) из абстрактного класса Attributable (также, как это делают объекты Table и с ними все работает!). Этот метод запишет в свойство $attrArray наши border и 1. Но когда я прошу этот же объект сделать метод getAttrStr(), свойство $attrArray уже пустое и выдает ошибку Invalid argument supplied for foreach(). Не понимаю в чем подвох =(

    Добавлено спустя 2 минуты 8 секунд:
    NULL
     
  6. p@R@dox 55RU

    p@R@dox 55RU Зэк
    [ БАН ]

    С нами с:
    21 май 2014
    Сообщения:
    1.358
    Симпатии:
    7
    Адрес:
    с планеты Ялмез
    так всё так и, может, всё иначе, а не так как ты понимаешь ? )))

    что бы понять, почитай лучшее по ОПП и делай
    Код (Text):
    1. var_dump($this->???);
    в методах ;)
     
  7. osvical

    osvical Новичок

    С нами с:
    9 янв 2015
    Сообщения:
    67
    Симпатии:
    0
    Извиняюсь! не правильно описал ошибку в первом сообщении. Понял только сейчас.
    Код (Text):
    1.  
    2. $table= new Table(2,2);
    3. $table->trArr[0]->addAttr('border','1');
    это ошибку не выдаст. вылетит она когда после этого попытаюсь показать таблицу:
    Код (Text):
    1.  
    2. $table= new Table(2,2);
    3. $table->trArr[0]->addAttr('border','1');
    4. echo $table->getHtml();
     
  8. p@R@dox 55RU

    p@R@dox 55RU Зэк
    [ БАН ]

    С нами с:
    21 май 2014
    Сообщения:
    1.358
    Симпатии:
    7
    Адрес:
    с планеты Ялмез
    а как же
    Код (Text):
    1. Notice: Undefined property: Td::$getAttrStr in ... on line
    2.  
    3. Notice: Undefined property: Td::$getAttrStr in ... on line
    4.  
    5. Notice: Undefined property: Tr::$getAttrStr in ... on line
    6.  
    7. Notice: Undefined property: Td::$getAttrStr in ... on line
    8.  
    9. Notice: Undefined property: Td::$getAttrStr in ... on line
    10.  
    11. Notice: Undefined property: Tr::$getAttrStr in ... on line
    ???
     
  9. osvical

    osvical Новичок

    С нами с:
    9 янв 2015
    Сообщения:
    67
    Симпатии:
    0
    похоже, эти ошибки у меня выключены. надо включить, спасибо. исправил в декларации public $attrArray= array(); добавил значением по умолчанию пустой массив. думаю, должны пропасть

    Добавлено спустя 3 минуты 39 секунд:
    теперь ошибки нет, в var_dump($this->attrArray); приходит пустой массив. проблема только, что он пустой)
     
  10. osvical

    osvical Новичок

    С нами с:
    9 янв 2015
    Сообщения:
    67
    Симпатии:
    0
    все, нашел косяк. обращался к методу как к свойству, забыл про скобки =(
    return '<tr'.$this->getAttrStr.'>'.$tdsStr.'</tr>';
    return '<tr'.$this->getAttrStr().'>'.$tdsStr.'</tr>';

    остался вопрос о правильности подхода, нужно ли как-то скрывать доступ к объектам строка и ячейка... ну да ладно, главное все правильно работает
     
  11. p@R@dox 55RU

    p@R@dox 55RU Зэк
    [ БАН ]

    С нами с:
    21 май 2014
    Сообщения:
    1.358
    Симпатии:
    7
    Адрес:
    с планеты Ялмез
    похвально! :)
     
  12. osvical

    osvical Новичок

    С нами с:
    9 янв 2015
    Сообщения:
    67
    Симпатии:
    0
    выложу на всякий случай итоговый рабочий код. если вдруг кто-то попадет сюда через поиск и эта ересь куму-то понадобится =) Класс умеет создавать таблицы заданной высоты/ширины. Также можно создать пустую, она будет автоматически расширяться по мере обращения к несуществующим элементам. если добавляется уже существующий атрибут, то его значение дописывается к старому через пробел

    Код (PHP):
    1. <?
    2. interface TableTnterface{
    3.     public function __construct($trNum=0,$tdNum=0,$caption='');
    4.     public function writeCell($trNum,$tdNum,$content);
    5.     public function addRow($num=1);
    6.     public function addCol($num=1);
    7.     public function addAttr($attr,$val);
    8.     public function addAttrToRow($numRow,$attrName,$attrValue);
    9.     public function addAttrToRowCells($numRow,$attrName,$attrValue);
    10.     public function addAttrToColCells($numCol,$attrName,$attrValue);
    11.     public function addAttrToCell($numRow,$numCol,$attrName,$attrValue);
    12.     public function getHtml();
    13. }
    14. abstract class Attributable{
    15.     public $attrArray= array();
    16.     public function addAttr($attr,$val){
    17.         if(isset($this->attrArray[$attr])){
    18.             $this->attrArray[$attr].= ' '.$val;
    19.         }else{
    20.             $this->attrArray[$attr]= $val;
    21.         }
    22.     }
    23.     public function getAttrStr(){
    24.         $attrStr= '';
    25.         foreach($this->attrArray as $name=>$value){
    26.             $attrStr.= ' '.$name.'="'.$value.'"';
    27.         }
    28.         return $attrStr;
    29.     }
    30. }
    31. class Td extends Attributable{
    32.     public $content;
    33.     public function __construct($content=''){
    34.         $this->content= $content;
    35.     }
    36.     public function getHtml(){
    37.         return '<td'.$this->getAttrStr().'>'.$this->content.'</td>';
    38.     }
    39. }
    40. class Tr extends Attributable{
    41.     public $tdArr;
    42.     public function __construct($tdNum=0){
    43.         for($i=0;$i<$tdNum;$i++){
    44.             $this->tdArr[]= new Td();
    45.         }
    46.     }
    47.     public function addTd($num=1){
    48.         for($i=0;$i<$num;$i++){
    49.             $this->tdArr[]= new Td();
    50.         }
    51.     }
    52.     public function getHtml(){
    53.         $tdsStr= '';
    54.         foreach($this->tdArr as $td){
    55.             $tdsStr.= $td->getHtml();
    56.         }
    57.         return '<tr'.$this->getAttrStr().'>'.$tdsStr.'</tr>';
    58.     }
    59. }
    60. class Table extends Attributable implements TableTnterface{
    61.     public $caption;
    62.     private $_trNum;
    63.     private $_tdNum;
    64.     private $trArr= array();
    65.     public function __construct($trNum=0,$tdNum=0,$caption=''){
    66.         for($i=0;$i<$trNum;$i++){
    67.             $this->trArr[]= new Tr($tdNum);
    68.         }
    69.         $this->caption= $caption;
    70.         $this->_trNum= $trNum;
    71.         $this->_tdNum= $tdNum;
    72.     }
    73.     private function trNumControl($num){
    74.         if($num>$this->_trNum){ //если строки нет
    75.             $this->addRow($num-$this->_trNum);
    76.             if($this->_tdNum===0){
    77.                 $this->addCol();
    78.             }
    79.         }
    80.     }
    81.     private function tdNumControl($num){
    82.         if($num>$this->_tdNum){ //если столбца нет
    83.             if($this->_trNum===0){
    84.                 $this->addRow();
    85.             }
    86.             $this->addCol($num-$this->_tdNum);
    87.         }
    88.     }
    89.     public function addRow($num=1){
    90.         for($i=0;$i<$num;$i++){
    91.             $this->trArr[]= new Tr($this->_tdNum);
    92.         }
    93.         $this->_trNum+= $num;
    94.     }
    95.     public function addCol($num=1){
    96.         for($i=0;$i<$this->_trNum;$i++){ //для всех строк
    97.             $this->trArr[$i]->addTd($num);
    98.         }
    99.         $this->_tdNum+= $num;
    100.     }
    101.     public function addAttrToRow($numRow,$attrName,$attrValue){
    102.         $this->trNumControl($numRow);
    103.         $this->trArr[$numRow-1]->addAttr($attrName,$attrValue);
    104.     }
    105.     public function addAttrToRowCells($numRow,$attrName,$attrValue){
    106.         $this->trNumControl($numRow);
    107.         foreach($this->trArr[$numRow-1]->tdArr as $td){
    108.             $td->addAttr($attrName,$attrValue);
    109.         }
    110.     }
    111.     public function addAttrToColCells($numCol,$attrName,$attrValue){
    112.         $this->tdNumControl($numCol);
    113.         foreach($this->trArr as $tr){
    114.             $tr->tdArr[$numCol-1]->addAttr($attrName,$attrValue);
    115.         }
    116.     }
    117.     public function addAttrToCell($numRow,$numCol,$attrName,$attrValue){
    118.         $this->trNumControl($numRow);
    119.         $this->tdNumControl($numCol);
    120.         $this->trArr[$numRow-1]->tdArr[$numCol-1]->addAttr($attrName,$attrValue);
    121.     }
    122.     public function writeCell($trNum,$tdNum,$content){
    123.         $this->trNumControl($trNum);
    124.         $this->tdNumControl($tdNum);
    125.         $this->trArr[$trNum-1]->tdArr[$tdNum-1]->content= $content;
    126.     }
    127.     public function getHtml(){
    128.         $caption= '';
    129.         if($this->caption) $caption= '<caption>'.$this->caption.'</caption>' ;
    130.         $trsStr= '';
    131.         foreach($this->trArr as $tr){
    132.             $trsStr.= $tr->getHtml();
    133.         }
    134.         return '<table'.$this->getAttrStr().'>'.$caption.'<tbody>'.$trsStr.'</tbody></table>';
    135.     }
    136. }
    Пример использования:
    Код (PHP):
    1. $table= new Table();
    2. $table->writeCell(1,1,'1');
    3. $table->writeCell(1,2,'2');
    4. $table->writeCell(1,3,'3');
    5. $table->writeCell(2,2,'4');
    6. $table->writeCell(3,3,'5');
    7. $table->writeCell(4,1,'6');
    8. $table->addAttr('border','1');
    9. $table->addAttr('class','a');
    10. $table->addAttrToColCells(1,'style','background-color:#bbb;');
    11. $table->addAttrToRowCells(1,'style','background-color:#888;');
    12. $table->addAttrToCell(4,3,'style','background-color:#f88;');
    13. echo $table->getHtml();
    PHP, JavaScript, SQL и другой код пишите внутри тегов
    Код ( (Unknown Language)):
    1. [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
     
  13. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Это лучше как трейт оформить (если php >= 5.4). А вообще, интересная идея. Мне не разу не приходило в голову делать класс для вёрстки
     
  14. osvical

    osvical Новичок

    С нами с:
    9 янв 2015
    Сообщения:
    67
    Симпатии:
    0
    странно, я этот класс переписал, наверно старую версию отправил в сообщении выше. сейчас он дописывает новые значения атрибутов через пробел.

    Код (PHP):
    1. abstract class Attributable{
    2.     public $attrArray= array();
    3.     public function addAttr($attr,$val){
    4.         if(isset($this->attrArray[$attr])){
    5.             $this->attrArray[$attr].= ' '.$val;
    6.         }else{
    7.             $this->attrArray[$attr]= $val;
    8.         }
    9.     }
    10.     public function getAttrStr(){
    11.         $attrStr= '';
    12.         foreach($this->attrArray as $name=>$value){
    13.             $attrStr.= ' '.$name.'="'.$value.'"';
    14.         }
    15.         return $attrStr;
    16.     }
    17. }
    исправил прошлое сообщение.

    спасибо, посмотрю что это такое)
     
  15. p@R@dox 55RU

    p@R@dox 55RU Зэк
    [ БАН ]

    С нами с:
    21 май 2014
    Сообщения:
    1.358
    Симпатии:
    7
    Адрес:
    с планеты Ялмез
    а так заработало ? :)
     
  16. osvical

    osvical Новичок

    С нами с:
    9 янв 2015
    Сообщения:
    67
    Симпатии:
    0
    тогда да, сейчас нет, ибо этот массив я заприватил =) дописал методы, которые с ним работают, и заприватил. мало ли в голову взбредет удалить из него что-то, а счетчики высоты-ширины таблицы тикают только в методах