На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Обработчик событий PHP - упрощаем жизнь , Вот создал я класс обрабатывающий события
    Когда-то, давным давно, я хотел создать класс который будет каким то образом облегчать работу программиста и создал топик Никому не нужный Класс :(

    Много времени прошло с тех пор, но я все таки доработал свою идею. В итоге можно сказать получился релиз.

    Итак, что же этот класс умеет:
    * при наличии определенного сообщения вызывать обработчик
    * вызвать обработчик только в том случае если в GET или POST или REQUEST или COOCKIE или SESSION присутствуют определенные переменные
    * перехватывать буфер вывода с обработчиков

    и много другое - пока описывать не буду

    Обработчиком может являться как метод объекта, статический метод или функция.

    Вот код класса (PHP 5)

    НЕ забудте почитать Никому не нужный Класс :(

    ExpandedWrap disabled
      <?php
      /**
       * Event Listener Class
       * PHP version 5.1.4
       *
       * @version 1.1.3
       * @copyright 2007 Web2l Framework
       * @link http://web2l.org
       * @author zx_master
       */
       
      class CEL
      {
      /** Method run correct */
      const OK = 0x1;
      /** Run default action after this */
      const DEF = 2;
      /** Run action switch again */
      const AGAIN = 0x4;
      /** Treat only get vars */
      const GET = 0x8;
      /** Treat only post vars */
      const POST = 0x10;
      /** Treat $_REQUEST */
      const REQUEST = 24;
      const COOKIE = 0x20;
      const SESSION = 0x40;
      /** Flush method buffer to handle after it  */
      const FLUSH = 0x100;
      /** Define preaction (only for internal use) */
      const PRE_FILTER = 0x800;
       
      /** Loop block. Max while cycle runs */
      private $antiloop = 128;
       
      /**
       * Массив обработчиков событий
       * array(
       * 'link' => call_link,
       * 'new_event'=> string (This action will set if condition fail),
       * 'fail_msg'=> string (This message will show before new_action run),
       * 'vars_type'=> GET, POST e.t.c,
       * 'vars'=> array(var names)
       * )
       */
      private  $events = array();
       
      /**
       * Массив обработчиков предварительных сообщениий (перед основными сообщениями)
       * array(
       * 'link' => call_link,
       * 'vars_type' => GET, POST e.t.c,
       * 'vars'=> array(var names)
       * )
       */
      private $pre_filters = array(/*param=>function_name*/);
       
      /** Default handler name */
      private $default_handler = null;
      /** Buffer handle method */
      private $buffer_handler = null;
      /** Methods captured buffers */
      private $m_buffers= array();
      /** Имя параметра события */
      private $event_name = '';
      /** Значение параметра события */
      private $event_val = '';
       
      /** Last method result */
      private $last_result = 0x0;
       
      private $use_ob = false;
      private $continue = false;
       
      public function  __construct($a_name = 'event') {
          $this->event_name = $a_name;
       
      }
       
      /**
       * Устанавливает обработчик события по умолчанию
       * Данный обработчик будет запускаться в том случае если событие не пришло или
       * не было найдено обработчкиков для текущего события
       *
       * @param string $name Method name
       * @return boolean
       */
      public function setDefaultHandler($link) {
          if(is_callable($link)){
              $this->default_handler = $link;
              return true;
          }
          else {
              $this->trigger_error('Method '.(is_array($link)? $$link[1] : $link ).' is not exist or wrong input values!', ' setDefaultHandler');
              return false;
          }
      }
       
      /**
       * Устанавливает обработчик данных из буфера вывода
       * Прототип обработчика <b>function method_name($buffer)</b>
       * Если обработчик не установлен, то буфер вывода не перехватывается
       *
       * @param string $link Ссылка на обработчик
       * @return boolean
       */
      public function setBufferHandler($link) {
          if(is_callable($link)){
              $this->buffer_handler = $link;
              $this->use_ob = true;
              return true;
          }
          else {
              $this->trigger_error('Method '.(is_array($link)? $link[1] : $link ).' is not exist or wrong input values!', ' setBufferHandler');
              return false;
          }
      }
       
      /**
       * Устанавливаем обработчик для события. Прототип обработчика <b>function method_name($event, &$new_event)</b>
       *
       * @param string $link Ссылка на обработчик
       * @param string/array $action String: event_name OR Array 1-event_name, 2-new event_name if condition fail, 3 - message to show before new event run
       * @param mask $vars_type Тип переменных для обработки
       * @return boolean
       */
      public function setEventHandler($link, $event, $vars_type=0){
          if(is_callable($link))
          {
              $add_data=array('link'=>$link, 'vars_type'=>0, 'vars'=>array() );
              $add_data['vars_type'] = (int)$vars_type;
              // Adding input vars into function call properties //
              for($i=3; $i<func_num_args(); $i++)
                  $add_data['vars'][]=(string)func_get_arg($i);
       
              if (is_array($event)) {
                  if (!empty($event[2])) $add_data['fail_msg'] = $event[2];
                  $add_data['new_event'] = $event[1];
                  $this->events[$event[0]]=$add_data;
              }
              else
                  $this->events[$event]=$add_data;
              return true;
          }
          else {
              $this->trigger_error('Method '.(is_array($link)? $link[1] : $link ).' is not exist or wrong input values!', 'setEventHandler');
              return false;
          }
      }
       
      /**
       * Устанавливает обработчик для префилтра
       *
       * @param string $link Ссылка на обработчик
       * @param mask $vars_type Тип переменных для обработки
       * @return boolean
       */
      public function setPreFilter($link, $vars_type=0) {
          if(is_callable($link) && func_num_args()>2 &&($vars_type&CEL::REQUEST))
          {
              $add_data=array('link'=>$link, 'vars_type'=>0, 'vars'=>array());
              // Adding input vars into function call properties //
              $add_data['vars_type'] = (int)$vars_type;
              for($i=2; $i<func_num_args(); $i++)
                  $add_data['vars'][]=(string)func_get_arg($i);
       
              $this->pre_filters[]=$add_data;
              return true;
          }
          else {
              $this->trigger_error('Method '.(is_array($link)? $link[1] : $link ).' is not exist or wrong input values!', 'setPreFilter');
              return false;
          }
      }
       
      /**
       * Запускаем обработчики событий
       */
      public function runHandlers()
      {
          $this->runPreFilters();
          $this->runEventHandlers();
      }
       
      /**
       *  Запусткает обработку префильтров
       *
       * @return void
       */
      private function runPreFilters()
      {
          if(empty($this->pre_filters)) return;
          if(!empty($this->was_p_launch)) {
              $this->trigger_error('Can\'t launch pre filters again!', 'runPreFilters');
              return;
          }
          $this->was_p_launch = true;
       
          // Run on request exist functions //
          $this->last_result = 0;
          foreach ($this->pre_filters as $method)
          {
              $run_this = false;
              $check_data = &$this->getDataLink($method['vars_type']);
              foreach ($method['vars'] as $var_name) {
                  if (!empty($check_data[$var_name]))
                      $run_this = true;
                  else {
                      $run_this = false;
                      break;
                  }
              }
       
              if (!$run_this) continue; // Check cycle run //
       
              if($this->use_ob) ob_start();
              // Run method //
              $this->last_result = (int)call_user_func($method['link']) | CEL::PRE_FILTER;
              // Treat method result //
              $buffer = null;
              if($this->use_ob) {
                  $buffer = ob_get_contents();
                  ob_end_clean();
              }
              $this->treatHandleResult($buffer, $null, $method['link']);
          }
      }
       
      /**
       * Запускает обработчики событий
       *
       *  @return void
       */
      private function runEventHandlers()
      {
          if(!empty($this->was_e_launch)) {
              $this->trigger_error('Can\'t launch event handlers again!', 'runEventHandlers');
              return;
          }
          $this->was_e_launch = true;
       
          // Check for default method //
          if(empty($this->default_handler)) {
              $this->trigger_error('Can\'t find default handler!', 'runEventHandlers');
              return;
          }
       
          // Get action param //
          $this->event_val = isset($_REQUEST[$this->event_name]) && ereg('^[a-zA-Z]+[a-zA-Z\d_]+$',$_REQUEST[$this->event_name]) ? $_REQUEST[$this->event_name] : '';
          // Run action cycle //
          do {
              $this->continue = false;
              $new_event = null;
              $this->last_result = 0;
              $this->antiloop --;
              $buffer = null;
       
              if($this->use_ob) ob_start();
       
              if(!empty($this->event_val) && isset($this->events[$this->event_val]))
              {
                  // Running function depending on input vars existence
                  if ($this->events[$this->event_val]['vars_type'])
                  {
                      $run_this = false;
                      $check_data = &$this->getDataLink($this->events[$this->event_val]['vars_type']);
                      foreach ($this->events[$this->event_val]['vars'] as $var_name) {
                          if (!empty($check_data[$var_name]))
                              $run_this = true;
                          else {
                              $run_this = false;
                              break;
                          }
                      }
       
                      if($run_this)
                          $this->last_result = call_user_func_array($this->events[$this->event_val]['link'], array($this->event_val, &$new_event));
                      // Change action if condition fail //
                      elseif(!empty($this->events[$this->event_val]['new_event']))
                      {
                          // Show fail message //
                          if (!empty($this->events[$this->event_val]['fail_msg']))
                          {
                              if($this->use_ob)
                                  $this->m_buffers[] = $this->events[$this->event_val]['fail_msg'];
                              else
                                  echo $this->events[$this->event_val]['fail_msg'];
                          }
                          $this->event_val = $this->events[$this->event_val]['new_event'];
                          $this->continue = true;
                          continue;
                      }
                      else {
                          // Show fail message //
                          if (!empty($this->events[$this->event_val]['fail_msg']))
                          {
                              if($this->use_ob)
                                  $this->m_buffers[] = $this->events[$this->event_val]['fail_msg'];
                              else
                                  echo $this->events[$this->event_val]['fail_msg'];
                          }
                          $this->runDefault();
                          break;
                      }
                  }
                  else
                      $this->last_result = (int)call_user_func_array($this->events[$this->event_val]['link'], array($this->event_val, &$new_event));
       
              }
              // Run default method //
              else {
       
                  $this->runDefault();
                  break;
              }
       
              if($this->use_ob) {
                  $buffer = ob_get_contents();
                  ob_end_clean();
              }
       
              // Treat method result //
              $this->treatHandleResult($buffer, $new_event, $null);
       
          } while ($this->continue);
       
          // Treat all functions buffers //
          if($this->use_ob && sizeof($this->m_buffers)) {
              call_user_func_array($this->buffer_handler, array($this->m_buffers));
          }
      }
       
      private function treatHandleResult(&$buffer, &$new_event, &$PRE_FILTER = '')
      {
          static $x;
          // Flush OB from method //
          if($this->last_result & CEL::FLUSH && $this->use_ob && !empty($buffer)) {
              $ob_treat = call_user_func_array($this->buffer_handler, array(&$buffer));
          }
       
          // Get OB from method //
          if(!empty($buffer) && $this->use_ob && ~(int)$this->last_result&CEL::FLUSH) {
              $this->m_buffers[] = $buffer;
          }
       
          if (CEL::PRE_FILTER&$this->last_result) return;
       
          // Run action cycle again //
          if($this->last_result&CEL::AGAIN  && !empty($new_event) && $this->event_val !== $new_event) {
              $this->event_val = $new_event;
              $new_event = null;
              $this->continue = true;
          }
       
          // Running default action //
          if($this->last_result&CEL::DEF) {
              $this->event_val = null;
              $this->continue = true;
          }
      }
       
      private function &getDataLink($options)
      {
          switch (true) {
              case $options&CEL::GET && $options&CEL::POST :
                  return $_REQUEST;
              case $options&CEL::POST:
                  return $_POST;
              case $options&CEL::GET:
                  return $_GET;
              case $options&CEL::SESSION:
                  return $_SESSION;
              case $options&CEL::COOKIE:
                  return $_COOKIE;
              default:
       
                  return null;
          }
      }
       
      private function runDefault()
      {
          call_user_func($this->default_handler);
          $this->last_result = CEL::OK;
          // Treat default function run result Before break //
          $buffer = null;
          if($this->use_ob) {
              $buffer = ob_get_contents();
              ob_end_clean();
          }
          $this->treatHandleResult($buffer, $null, $null);
      }
       
      private function trigger_error($error_msg, $method_name, $error_type = E_USER_WARNING)
      {
          $error_txt = '<strong>CEL error (method '.$method_name.')</strong>: '.$error_msg;
          trigger_error($error_txt, $error_type);
      }
      };
       
      // ПРИМЕР РАБОТЫ //
       
      // Тестовый класс
      class TEZT
      {
          // Метод по умолчанию //
          function main ()
          {
              echo 'Main';
          }
       
          // Обработчик события test //
          function someEvent()
          {
              echo 'Event';
       
          }
       
          // Обработчик события fuck //
          function someEvent2()
          {
              echo 'Fuck Event';
              // Если вернуть CEL::DEF то после отработки этого обработчика будет запущен обработчик по умолчанию
              return CEL::DEF;
          }
       
          // СТАТИЧЕСКИЙ Метод перехватывающий исходящий буффер //
          static function bufHandle($buf)
          {
              echo "Buffer\n";
              print_r($buf);
          }
       
      }
       
      // Пре фильтр //
      function preFilter()
      {
          echo 'Pre filter';
      }
       
      // Cоздаем тестовый класс
      $tst = new TEZT();
       
      // Создаем класс сообщений
      $event = new CEL();
       
      // Устанавливаем обработчик по умолчанию //
      $event->setDefaultHandler(array(&$tst,'main'));
       
      // Ставим метод/функцию перехватывающую буфер вывода (МОЖНО НЕ УСТАНАВЛИВАТЬ)
      $event->setBufferHandler(array('TEZT','bufHandle'));
       
       
      // ставим обработчик для собыитя test //
      $event->setEventHandler(array(&$tst,'someEvent'), 'test');
       
      // ставим обработчик события fuck
      $event->setEventHandler(array(&$tst,'someEvent2'), 'fuck');
       
      // ставим обработчик для собыитя test только если $_GET['id'] не empty //
      //$event->setEventHandler(array(&$tst,'someEvent'), array('test', null, 'error'), CEL::GET, 'id');
       
      // ставим обработчик для собыитя test только если $_GET['id'] не empty
      // если $_GET['id'] == empty  тогда запускается метод по умолчанию
      //$event->setEventHandler(array(&$tst,'someEvent'), array('test', null), CEL::GET, 'id');
       
      // ставим обработчик для собыитя test только если $_GET['id'] не empty
      // если $_GET['id'] == empty  тогда запускается обработчик события fuck
      //$event->setEventHandler(array(&$tst,'someEvent'), array('test', 'fuck'), CEL::GET, 'id');
       
      // ставим обработчик для собыитя test только если $_GET['id'] не empty
      // если $_GET['id'] == empty  тогда запускается метод по умолчанию и выводиться сообщение об ошибке
      //$event->setEventHandler(array(&$tst,'someEvent'), array('test', null, 'ЭТо сообщение об ошибке'), CEL::GET, 'id');
       
       
      // Определяем префильтр срабатывающий если $_POST['x'] и $_POST['y'] не empty
      $event->setPreFilter('preFilter', CEL::POST , 'x', 'y');
       
      // Ставим событие //
      $_REQUEST['event'] = 'fuck';
       
      // Определяем переменные
      $_GET['id'] = 'test';
      $_POST['x'] = 1;
      $_POST['y'] = 1;
       
      // Запускаем обработчики //
      $event->runHandlers();
      ?>
    Сообщение отредактировано: zx_master -
    1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script execution time: 0,0275 ]   [ 14 queries used ]   [ Generated: 6.10.24, 09:25 GMT ]