За последние 24 часа нас посетили 17689 программистов и 1743 робота. Сейчас ищут 1060 программистов ...

Деструкторы и exit

Тема в разделе "Прочие вопросы по PHP", создана пользователем botbot, 7 янв 2010.

  1. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Знаешь еще что меня смущает?

    Это источник всех этих танцев с бубнами.

    А именно почему ты не сохраняешь по факту модификации объекта?

    PHP:
    1. <?php
    2. $obj->a = 1;
    3. $obj->b = 2;
    4. DB::getInstance()->save($obj);
    и плевать что кто-то где-то потом выйдет.

    Есть небольшой смысл в этих плясках на случай фатальных ошибок. На этот случай вот мусолили
    http://www.php.ru/forum/viewtopic.php?t=22992
    Но и тут, я бы сбрасывал в файлы, а не в базу... ибо базы к этому моменту может не быть физически :)
     
  2. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Ну, ты всегда можешь спросит у разработчиков :) Возможно тебе даже ответят :)
     
  3. botbot

    botbot Активный пользователь

    С нами с:
    7 янв 2010
    Сообщения:
    12
    Симпатии:
    0
    Объект меняется в разных местах. Писать каждый раз в базу негламурно. Отследить когда он в последний раз поменяется сложно. И вообще, хочется автоматизма, ибо много кода.
    Насчёт register_shutdown_function() - я пробовал вызвать деструкторы, поэтому и не работало. С самописными ф-циями похоже всё будет хорошо.
    Ещё один вопрос, чисто эстетический. Можно как-то авторегистрацию объектов сделать?
    Ну чтобы в каждом конструкторе не писать это destruct_stack::add_obj($this).
    Что-то типа
    PHP:
    1.  
    2.  abstract class destruct_control {
    3.      function __construct() {
    4.          destruct_stack::add_obj($this);
    5.      }
    6.      abstract public function destruct();
    7.  }
    8.  
    И чтобы при наследовании само вызывалось?
     
  4. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Вообще-то менять его в разых местах не менее негламурно :)
    Если это у тебя происходит с массовыми данными - это ошибка.
    Если таких объектов 3-4 в процессе жизни приложения...
    я бы забил на гламур и таки писал бы в базу. А рабочее приложение отпрофилировал по нагрузке. И увидел бы мешает ли данный факт мне :)


    spl_autoload_register - поможет для самих классов.
    А вот для объектов... хм

    Есть варианты фабрик и локаторов, поищи в гугле описание этих паттернов.
    Но локаторы я недолюбливаю. Во-первых убивает весь автокомплит в IDE. А во-вторых, типичный звездный объект от которого начинает зависеть все.
    К фабрикам я потолерантнее отношусь.

    для объектов с общим родителем возможен еще такой вариант

    PHP:
    1. <?php
    2. astract class cparent {
    3.     function __construct() {
    4.         stack::add($this);
    5.         $this->init();
    6.     }
    7.     abstract public function init();
    8. }
    9.  
    10. class cchild extends cparent {
    11.     /**
    12.      * этот метод у нас теперь вместо конструктора
    13.      */
    14.     function init() {
    15.     }
    16. }
     
  5. botbot

    botbot Активный пользователь

    С нами с:
    7 янв 2010
    Сообщения:
    12
    Симпатии:
    0
    Их сейчас как раз всего 4 штуки, но потом может стать больше. Вот например 1, он добавляет записи в таблицу, у которой много индексных полей:
    PHP:
    1. <?php
    2. class events extends destruct_control {
    3.     var $id;
    4.     var $mySql;
    5.     var $cache = '';
    6.     function __construct($id, $mySql) {
    7.         $this->id = $id;
    8.         $this->mySql = $mySql;
    9.         $this->register();
    10.     }
    11.     function  destruct() {
    12.         if($this->cache != '') {
    13.             $query = 'INSERT INTO chat(source, type, dest, message, time)' .  ($this->cache);
    14.             $this->mySql->query($query);
    15.         }
    16.     }
    17.     function add_event($packet, $type) {
    18.         if($this->cache == '') {
    19.             $this->cache .= "VALUES (' ', {$type}, '{$this->id}', '{$packet}', NOW())";
    20.         }
    21.         else {
    22.             $this->cache .= ",(' ', {$type}, '{$this->id}', '{$packet}', NOW())";
    23.         }
    24.     }
    25. }
    Разделять такую запись на много insert-ов и смешивать их с другими запросами к базе сильно увеличит время выполнения, это понятно даже и без профилинга.
    У другого объекта ситуация такая: он пишет в базу просто свои поля, но эти поля во время выполнения скрипта могут меняться неоднократно. Писать каждый раз изменения в базу увеличит кол-во запросов в несколько раз.
    Насчёт авторегистрации значит простых вариантов нету. Ладно, буду так писать.
    В целом пользуюсь тем что мы тут написали, ещё добавил конечно register_shutdown_function('destruct_stack::exiter');. Впечатления от первого применения приятные.
    Всем спасибо за помощь, особенно Simpliest.