Полезные заметки по веб-программированию PHP, Symfony, Propel, Doctrine, JS, jQuery, ExtJS, HTML, CSS, …

Filter symfony для определения города по IP адресу (IPGeo)

Posted on Июнь 15, 2011


Chain Filter для фреймворка симфони, предназначенный для определения города по IP адресу пользователя. Данный фильтр использует онлайн сервис ipgeobase.ru. Доступны города России и Украины. Также с этого сайта взят за основу и сам код.

В любом случае перед началом использования не помешало бы ознакомиться с информацией расположенной на указанном сайте.

Для облегчения нагрузки и небольшого ускорения, используется кеширование города. Название города заносится в куку с именем указанным в константе COOKIE_NAME. Дабы всех запутать и перехитрить значение в куке закодировано в base64.

<?php
 
class IpGeoFilter extends sfFilter
{
  const COOKIE_NAME = 'ct';
 
  public function execute($filterChain)
  {
    if ($this->isFirstCall())
    {
      $ip = sfContext::getInstance()->getRequest()->getRemoteAddress();
 
      if (!sfContext::getInstance()->getRequest()->getCookie(self::COOKIE_NAME))
      {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, sprintf('http://ipgeobase.ru:7020/geo?ip=%s', $ip));
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 3);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
        curl_setopt($ch, CURLOPT_USERAGENT, 'my-site');
 
        $data = curl_exec($ch);
        $city = (!curl_errno($ch) && $xml = simplexml_load_string($data) ) ? $xml->ip->city : false;
 
        curl_close($ch);
 
        if ($city)
        {
          sfContext::getInstance()->getResponse()->setCookie(self::COOKIE_NAME, base64_encode($city), time() + 3600 * 24 * 7);
        }
      }
      else
      {
        $city = base64_decode(sfContext::getInstance()->getRequest()->getCookie(self::COOKIE_NAME));
      }
 
      if ($city)
      {
        sfContext::getInstance()->getUser()->setAttribute('city', $city);
      }
    }
 
    $filterChain->execute();
  }
}

Комментарии (0) Пинги (0)

Пока нет комментариев.


Leave a comment

Нет обратных ссылок на эту запись.