Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.77 KB | None | 0 0
  1. <?php
  2. /**
  3. * класс для сохранеия статистики проходов по сайту
  4. */
  5. class SiteStatistic
  6. {
  7.     /* в качестве хранилища используеться мемкеш */
  8.     const MEMCACHE_STORE_TYPE = 1;
  9.    
  10.     /* в качестве хранилища используеться mysql */
  11.     const MYSQL_STORE_TYPE = 2;
  12.    
  13.     /* в качестве хранилища используеться file */
  14.     const FILE_STORE_TYPE = 3;
  15.    
  16.     /**
  17.     * название таблицы в к-ой будет сохраняться статистика
  18.     *
  19.     * @var string
  20.     */
  21.     private static $_mysqlStatisticTable = 's_google_stat';
  22.    
  23.     /**
  24.     * максимальное кол-во ключей, по к-ым будет сохраняться статиски в кеше
  25.     *
  26.     * @var int
  27.     */
  28.     private static $_cacheKeyMaxCount = 10;
  29.     /**
  30.     * префикс для ключа кеша
  31.     *
  32.     * @var String
  33.     */
  34.     private static $_cacheKeyPrefix = 'site_stat';
  35.    
  36.     /**
  37.     * время жизни кеша
  38.     *
  39.     * @var int
  40.     */
  41.     private static $_cacheExpireTime = 300;
  42.    
  43.     /**
  44.     * абсолютный путь до файла, в к-ом будет сохраняться статистика
  45.     *
  46.     * @var String
  47.     */
  48.     private static $_fileAbsolutePath = '';
  49.    
  50.     /**
  51.     * массив полей таблицы, к-ая используеться для сохранения статистики
  52.     *
  53.     * @var array
  54.     */
  55.     private static $_tableFieldList = array();
  56.     /**
  57.     * метод сохраняет переданную информацию о статиске
  58.     *
  59.     * @param int $typeStore тип хранилища для статики
  60.     * @param array $statInfo массив с информацией о статистике, имеющий след. поля :
  61.     *  Array('PageUrl', 'ExecuteTime', 'DetailInfo', 'CreateDate', 'RemoteIp')
  62.     *
  63.     * @return bool
  64.     */
  65.     static public function saveInfo( $typeStore, $statInfo )
  66.     {
  67.         switch ($typeStore)
  68.         {
  69.             /* сохранем данные в мемкеше */
  70.             case self::MEMCACHE_STORE_TYPE :            
  71.                 global $oCache;
  72.                 self::_saveInfoToMemcache($statInfo, $oCache);                
  73.             break;
  74.            
  75.             /*сохраняем данные в мускуле*/
  76.             case self::MYSQL_STORE_TYPE :
  77.                 global $DB;
  78.                 self::_saveInfoToMysql($statInfo, $DB);
  79.             break;
  80.            
  81.             case self::FILE_STORE_TYPE:
  82.                 self::_saveInfoToFile($statInfo);
  83.             break;
  84.         }
  85.        
  86.         return true;
  87.        
  88.     }
  89.     /**
  90.     * метод для сохранения статистики в мемкеше
  91.     *
  92.     * @param array $statInfo  массив с инфомрацией о статистике
  93.     * @param GenericCache $memcacheObject объект класса для работы с мемкешом
  94.     *
  95.     * @return bool
  96.     */
  97.     static private function _saveInfoToMemcache ( $statInfo, $memcacheObject )
  98.     {
  99.         // проверяем инстанцирован ли переданный объект от классов-клиентов мемкеша
  100.        
  101.         if ( !is_object($memcacheObject) || get_class($memcacheObject) != 'GenericCache')
  102.         {
  103.             throw new SiteStatistic_Exception('It is not memcache object');
  104.         }
  105.        
  106.         // проверяем валидность переданных данных
  107.         if ( $statInfo = self::_validateStatInfo($statInfo) )
  108.         {
  109.             // статистика в мемкеше будет сохраняться по нескольким ключам
  110.             // таким образом будет решена проблема потери даннвх при одновреаенном вызове хранилища из мемкеша
  111.             $cacheUID = self::$_cacheKeyPrefix . rand(1, self::$_cacheKeyMaxCount);
  112.            
  113.             if ( false === ($statInfoList = $memcacheObject->get($cacheUID)))
  114.             {
  115.                 $statInfoList = array();                                
  116.             }
  117.             $statInfoList[] = $statInfo;
  118.            
  119.             if ( false === $memcacheObject->set($statInfoList, $cacheUID, self::$_cacheExpireTime) )
  120.             {
  121.                 throw new SiteStatistic_Exception('can not save data in cache');                
  122.             }            
  123.         }
  124.         return true;  
  125.     }
  126.     /**
  127.     *
  128.     * метод сохраняет статистику в mysql
  129.     *
  130.     * @param array $statInfoList коллекция массивов с данными по статистике
  131.     * @param GenericDatabase $dbAdapter адаптер для работы с Mysql
  132.     *
  133.     * @return bool
  134.     */
  135.     static private function _saveInfoToMysql ( $statInfoList, $dbAdapter )
  136.     {
  137.         // проверяем инстанцирован ли переданный объект от классов-клиентов мемкеша
  138.         if ( !is_object($dbAdapter) || get_class($dbAdapter) != 'GenericDatabase')
  139.         {
  140.             throw new SiteStatistic_Exception('It is not valid db adapter');
  141.         }
  142.        
  143.         // проверяем валидность переданной коллекции со статистикой
  144.         if ( empty($statInfoList) || isset($statInfoList['PageUrl']) )                
  145.         {
  146.             throw new SiteStatistic_Exception('List of stat info is not valid! ');                        
  147.         }
  148.         // получаем список полей у таблицы, к-ая используеться для сохранения статистики        
  149.         if ( empty(self::$_tableFieldList) )
  150.         {
  151.            
  152.             self::$_tableFieldList = self::_getTableFieldList( self::$_mysqlStatisticTable, $dbAdapter );            
  153.         }
  154.         $tableFields = self::$_tableFieldList;
  155.         if ( empty($tableFields) )
  156.         {
  157.             throw new SiteStatistic_Exception('tableFields is empty!');            
  158.         }
  159.        
  160.         // формируем Sql-запрос для сохрананения статистики
  161.         $sql = 'INSERT INTO `' . self::$_mysqlStatisticTable . '` (' . implode(',', $tableFields) . ') VALUES ';
  162.         $statValuesList = array();
  163.         foreach ( $statInfoList as $statInfo )
  164.         {
  165.             $statValues = array();
  166.             // пробегаемся по полям из таблицы и находим соотвествие с индексами в массиве с данными по стате
  167.             foreach ( $tableFields as $fieldName )
  168.             {
  169.                 if ( !isset($statInfo[$fieldName]) )
  170.                 {
  171.                     throw new SiteStatistic_Exception('Not found fieldName "' . $fieldName .'" in statInfo');                        
  172.                 }
  173.                 $statValues[] = sprintf('"%s"', mysql_escape_string($statInfo[$fieldName]) );                                                                                                    
  174.             }
  175.             $statValuesList[] = '(' . implode(',', $statValues) . ')' ;
  176.         }
  177.         $sql .= implode(',', $statValuesList);
  178.        
  179.         // выполняем запрос на вставку группы данных по статистике          
  180.         $dbAdapter->Query($sql);
  181.        
  182.         return true;
  183.     }
  184.     /**
  185.     * метод сохраняет статистику в файле на сервере
  186.     *
  187.     * @param array $statInfo   массив с инфомрацией о статистике
  188.     *
  189.     * @return bool
  190.     */
  191.     static private function _saveInfoToFile ( $statInfo )
  192.     {  
  193.         if ( file_exists(self::$_fileAbsolutePath) && self::_validateStatInfo($statInfo) )
  194.         {
  195.             $fp = fopen(self::$_fileAbsolutePath, 'a+');
  196.             $sStr = sprintf ('%s page %s main_exec_time %s remote_ip: %s',
  197.                                     date('d.m.Y H:i:s'),
  198.                                     $statInfo['PageUrl'],
  199.                                     $statInfo['ExecuteTime'],
  200.                                     $statInfo['RemoteIp']
  201.                                     );            
  202.             $sStr .= "\n";
  203.             if ($statInfo['ExecuteTime'] > 1)
  204.             {
  205.                $sStr .=  "Detail: \n";
  206.                foreach ($APPLICATION->arSetTimer as $sIndex => $sVal)
  207.                {
  208.                    $sStr .= $sIndex . ": " . $sVal ."\n";          
  209.                }
  210.                
  211.             }
  212.             fputs($fp, $sStr);
  213.             fclose($fp);    
  214.         }
  215.        
  216.         return false;        
  217.     }
  218.     /**
  219.     * метод возращает список полей у переданной таблицы
  220.     *
  221.     * @param string $tableName название таблицы
  222.     * @param GenericDatabase $dbAdapter mysql адаптер
  223.     *
  224.     * @return array
  225.     */
  226.     static private function _getTableFieldList ( $tableName, $dbAdapter )
  227.     {
  228.         $result = array();
  229.         $columnDbRes = $dbAdapter->Query('SHOW COLUMNS FROM ' . $tableName);        
  230.         while ( $columnData = $columnDbRes->Fetch() )
  231.         {
  232.             if ( $columnData['Extra'] != 'auto_increment' )
  233.             {
  234.                 $result[] = $columnData['Field'];                            
  235.             }
  236.         }
  237.        
  238.         return $result;
  239.     }
  240.     /**
  241.     * метод изменяет или возвращает название таблицы, к-ая используеться для сохранения статистики
  242.     *
  243.     * @param string $tableName навзание таблицы
  244.     *
  245.     * @return bool
  246.     */
  247.     static public function mysqlTableForStat ( $tableName = null )
  248.     {
  249.         if ( is_null($tableName) )
  250.         {
  251.             return self::$_mysqlStatisticTable;
  252.         }
  253.        
  254.         self::$_mysqlStatisticTable = $tableName;        
  255.        
  256.         return true;
  257.        
  258.     }
  259.     /**
  260.     * возвращаем или изменяем макимальное кол-во ключей для хранения данных в мемкеше
  261.     *
  262.     * @param int $maxCount число ключей
  263.     *
  264.     * @return bool
  265.     */
  266.     static public function cacheKeyMaxCount ( $maxCount = null )
  267.     {
  268.         if ( is_null($maxCount) )
  269.         {
  270.             return self::$_cacheKeyMaxCount;            
  271.         }
  272.        
  273.         self::$_cacheKeyMaxCount = $maxCount;
  274.        
  275.         return true;
  276.     }
  277.     /**
  278.     * возвращаем или изменяем префикс для ключа, по к-ому будут сохраняться данные в кеше
  279.     *
  280.     * @param string $keyPrefix префикс ключа
  281.     *
  282.     * @return bool
  283.     */
  284.     static public function cacheKeyPrefix ( $keyPrefix = null )
  285.     {
  286.         if ( is_null($keyPrefix) )
  287.         {
  288.             return self::$_cacheKeyPrefix;
  289.         }
  290.        
  291.         self::$_cacheKeyPrefix = $keyPrefix;
  292.        
  293.         return true;
  294.        
  295.     }
  296.     /**
  297.     * возвращаем или изменяем абсолютный путь для файла со статискийо
  298.     *
  299.     * @param string $absolutePath абсолютный путь
  300.     *
  301.     * @return bool
  302.     */
  303.     static public function fileAbsolutePath ( $absolutePath = null )
  304.     {
  305.         if ( is_null($absolutePath) )
  306.         {
  307.             return self::$_fileAbsolutePath;
  308.         }
  309.        
  310.         self::$_fileAbsolutePath = $absolutePath;
  311.        
  312.         return true;
  313.     }
  314.     /**
  315.     * возвращаем или устаналиваем время жизни кеша
  316.     *
  317.     * @param int $time
  318.     */
  319.     static public function cacheExpireTime ( $time = null )
  320.     {
  321.         if ( is_null($time) )
  322.         {
  323.             return self::$_cacheExpireTime;
  324.         }
  325.        
  326.         self::$_cacheExpireTime = $time;
  327.        
  328.         return true;
  329.        
  330.     }
  331.     /**
  332.     * проверяем валидность переданной информации по статистике
  333.     *
  334.     * @param array $statInfo массив с инфомрацией о статистике
  335.     *
  336.     * @return bool
  337.     */
  338.     static private function _validateStatInfo ( $statInfo )
  339.     {
  340.         if ( !isset($statInfo['PageUrl']) || empty($statInfo['PageUrl']) )
  341.         {
  342.             throw new SiteStatistic_Exception('Incorrect field: PageUrl');
  343.         }
  344.        
  345.         if ( !isset($statInfo['ExecuteTime']) || !(int) ($statInfo['PageUrl'] + 1) )
  346.         {
  347.             throw new SiteStatistic_Exception('Incorrect field: ExecuteTime');
  348.         }
  349.        
  350.         if ( !isset($statInfo['DetailInfo']) )
  351.         {
  352.             throw new SiteStatistic_Exception('Not found field: ExecuteTime');
  353.         }
  354.        
  355.         if ( !isset($statInfo['RemoteIp']) || !preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $statInfo['RemoteIp']) )
  356.         {
  357.             throw new SiteStatistic_Exception('Incorrect field: RemoteIp');
  358.         }  
  359.         $statInfo['RemoteIp'] = self::_ip2int($statInfo['RemoteIp']);
  360.         return $statInfo;    
  361.     }
  362.     /**
  363.     * переводим ip в целочисленный вид
  364.     *
  365.     * @param string $ip
  366.     *
  367.     * @return int
  368.     */
  369.     static private function _ip2int($ip)
  370.     {
  371.         $a=explode(".",$ip);
  372.         return $a[0]*256*256*256+$a[1]*256*256+$a[2]*256+$a[3];
  373.     }
  374.  
  375.    
  376. }
  377.  
  378. class SiteStatistic_Exception extends Exception {}
  379. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement