You are here

public function Database::__construct in Smart IP 6.2

Same name and namespace in other branches
  1. 7.2 includes/vendor/ip2location/ip2location-php/IP2Location.php \IP2Location\Database::__construct()

Constructor

@access public

Parameters

string $file Filename of the BIN database to load:

int $mode Caching mode (one of FILE_IO, MEMORY_CACHE, or SHARED_MEMORY):

Throws

\Exception

File

includes/vendor/ip2location/ip2location-php/IP2Location.php, line 644

Class

Database
IP2Location database class

Namespace

IP2Location

Code

public function __construct($file = null, $mode = self::FILE_IO, $defaultFields = self::ALL) {

  // find the referred file and its size
  $rfile = self::findFile($file);
  $size = filesize($rfile);

  // initialize caching backend
  switch ($mode) {
    case self::SHARED_MEMORY:

      // verify the shmop extension is loaded
      if (!extension_loaded('shmop')) {
        throw new \Exception(__CLASS__ . ": Please make sure your PHP setup has the 'shmop' extension enabled.", self::EXCEPTION_NO_SHMOP);
      }
      $limit = self::getMemoryLimit();
      if (false !== $limit && $size > $limit) {
        throw new \Exception(__CLASS__ . ": Insufficient memory to load file '{$rfile}'.", self::EXCEPTION_NO_MEMORY);
      }
      $this->mode = self::SHARED_MEMORY;
      $shmKey = self::getShmKey($rfile);

      // try to open the shared memory segment
      $this->resource = @shmop_open($shmKey, 'a', 0, 0);
      if (false === $this->resource) {

        // the segment did not exist, create it and load the database into it
        $fp = fopen($rfile, 'rb');
        if (false === $fp) {
          throw new \Exception(__CLASS__ . ": Unable to open file '{$rfile}'.", self::EXCEPTION_FILE_OPEN_FAILED);
        }

        // try to open the memory segment for exclusive access
        $shmId = @shmop_open($shmKey, 'n', self::SHM_PERMS, $size);
        if (false === $shmId) {
          throw new \Exception(__CLASS__ . ": Unable to create shared memory block '{$shmKey}'.", self::EXCEPTION_SHMOP_CREATE_FAILED);
        }

        // load SHM_CHUNK_SIZE bytes at a time
        $pointer = 0;
        while ($pointer < $size) {
          $buf = fread($fp, self::SHM_CHUNK_SIZE);
          shmop_write($shmId, $buf, $pointer);
          $pointer += self::SHM_CHUNK_SIZE;
        }
        shmop_close($shmId);
        fclose($fp);

        // now open the memory segment for readonly access
        $this->resource = @shmop_open($shmKey, 'a', 0, 0);
        if (false === $this->resource) {
          throw new \Exception(__CLASS__ . ": Unable to access shared memory block '{$shmKey}' for reading.", self::EXCEPTION_SHMOP_READING_FAILED);
        }
      }
      break;
    case self::FILE_IO:
      $this->mode = self::FILE_IO;
      $this->resource = @fopen($rfile, 'rb');
      if (false === $this->resource) {
        throw new \Exception(__CLASS__ . ": Unable to open file '{$rfile}'.", self::EXCEPTION_FILE_OPEN_FAILED);
      }
      break;
    case self::MEMORY_CACHE:
      $this->mode = self::MEMORY_CACHE;
      $this->resource = $rfile;
      if (!array_key_exists($rfile, self::$buffer)) {
        $limit = self::getMemoryLimit();
        if (false !== $limit && $size > $limit) {
          throw new \Exception(__CLASS__ . ": Insufficient memory to load file '{$rfile}'.", self::EXCEPTION_NO_MEMORY);
        }
        self::$buffer[$rfile] = @file_get_contents($rfile);
        if (false === self::$buffer[$rfile]) {
          throw new \Exception(__CLASS__ . ": Unable to open file '{$rfile}'.", self::EXCEPTION_FILE_OPEN_FAILED);
        }
      }
      break;
    default:
  }

  // determine the platform's float size
  //
  // NB: this should be a constant instead, and some unpack / typebanging magic
  //     should be used to accomodate different float sizes, but, as the libreary
  //     is written, this is the sanest thing to do anyway
  //
  if (null === self::$floatSize) {
    self::$floatSize = strlen(pack('f', M_PI));
  }

  // set default fields to retrieve
  $this->defaultFields = $defaultFields;

  // extract database metadata
  $this->type = $this
    ->readByte(1) - 1;
  $this->columnWidth[4] = $this
    ->readByte(2) * 4;
  $this->columnWidth[6] = $this->columnWidth[4] + 12;
  $this->offset[4] = -4;
  $this->offset[6] = 8;

  //
  $this->year = 2000 + $this
    ->readByte(3);
  $this->month = $this
    ->readByte(4);
  $this->day = $this
    ->readByte(5);
  $this->date = date('Y-m-d', strtotime("{$this->year}-{$this->month}-{$this->day}"));

  //
  $this->ipCount[4] = $this
    ->readWord(6);
  $this->ipBase[4] = $this
    ->readWord(10);

  //hjlim readword
  $this->ipCount[6] = $this
    ->readWord(14);
  $this->ipBase[6] = $this
    ->readWord(18);
  $this->indexBaseAddr[4] = $this
    ->readWord(22);

  //hjlim
  $this->indexBaseAddr[6] = $this
    ->readWord(26);

  //hjlim
}