SxGeo   F
last analyzed

Complexity

Total Complexity 90

Size/Duplication

Total Lines 292
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 292
rs 1.5789
c 0
b 0
f 0
wmc 90

13 Methods

Rating   Name   Duplication   Size   Complexity  
B parseCity() 0 25 5
A getCountry() 0 6 2
B search_idx() 0 18 10
C get_num() 0 34 13
A get() 0 2 2
A getCityFull() 0 3 2
F unpack() 0 48 31
B search_db() 0 14 6
B about() 0 24 1
C __construct() 0 38 8
B readData() 0 11 6
A getCity() 0 3 2
A getCountryId() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like SxGeo often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SxGeo, and based on these observations, apply Extract Interface, too.

1
<?php
2
/***************************************************************************\
3
| Sypex Geo                  version 2.2.3                                  |
4
| (c)2006-2014 zapimir       [email protected]       http://sypex.net/    |
5
| (c)2006-2014 BINOVATOR     [email protected]                                 |
6
|---------------------------------------------------------------------------|
7
|     created: 2006.10.17 18:33              modified: 2014.06.20 18:57     |
8
|---------------------------------------------------------------------------|
9
| Sypex Geo is released under the terms of the BSD license                  |
10
|   http://sypex.net/bsd_license.txt                                        |
11
\***************************************************************************/
12
namespace Geography;
13
define ('SXGEO_FILE', 0);
14
define ('SXGEO_MEMORY', 1);
15
define ('SXGEO_BATCH',  2);
16
class SxGeo {
17
	protected $fh;
18
	protected $ip1c;
19
	protected $info;
20
	protected $range;
21
	protected $db_begin;
22
	protected $b_idx_str;
23
	protected $m_idx_str;
24
	protected $b_idx_arr;
25
	protected $m_idx_arr;
26
	protected $m_idx_len;
27
	protected $db_items;
28
	protected $country_size;
29
	protected $db;
30
	protected $regions_db;
31
	protected $cities_db;
32
33
	public $id2iso = array(
34
		'', 'AP', 'EU', 'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'CW', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU',
35
		'AW', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BM', 'BN', 'BO', 'BR', 'BS',
36
		'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN',
37
		'CO', 'CR', 'CU', 'CV', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG',
38
		'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'SX', 'GA', 'GB', 'GD', 'GE', 'GF',
39
		'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN',
40
		'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE',
41
		'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR',
42
		'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP',
43
		'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI',
44
		'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN',
45
		'PR', 'PS', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG',
46
		'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'ST', 'SV', 'SY', 'SZ', 'TC', 'TD', 'TF',
47
		'TG', 'TH', 'TJ', 'TK', 'TM', 'TN', 'TO', 'TL', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'UM',
48
		'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'RS', 'ZA',
49
		'ZM', 'ME', 'ZW', 'A1', 'XK', 'O1', 'AX', 'GG', 'IM', 'JE', 'BL', 'MF', 'BQ', 'SS'
50
	);
51
52
	public $batch_mode  = false;
53
	public $memory_mode = false;
54
55
	public function __construct($db_file = 'SxGeo.dat', $type = SXGEO_FILE){
56
		$this->fh = fopen($db_file, 'rb');
57
		// Сначала убеждаемся, что есть файл базы данных
58
		$header = fread($this->fh, 40); // В версии 2.2 заголовок увеличился на 8 байт
0 ignored issues
show
Bug introduced by
It seems like $this->fh can also be of type false; however, parameter $handle of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

58
		$header = fread(/** @scrutinizer ignore-type */ $this->fh, 40); // В версии 2.2 заголовок увеличился на 8 байт
Loading history...
59
		if(substr($header, 0, 3) != 'SxG') die("Can't open {$db_file}\n");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
60
		$info = unpack('Cver/Ntime/Ctype/Ccharset/Cb_idx_len/nm_idx_len/nrange/Ndb_items/Cid_len/nmax_region/nmax_city/Nregion_size/Ncity_size/nmax_country/Ncountry_size/npack_size', substr($header, 3));
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

60
		$info = /** @scrutinizer ignore-call */ unpack('Cver/Ntime/Ctype/Ccharset/Cb_idx_len/nm_idx_len/nrange/Ndb_items/Cid_len/nmax_region/nmax_city/Nregion_size/Ncity_size/nmax_country/Ncountry_size/npack_size', substr($header, 3));

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
61
		if($info['b_idx_len'] * $info['m_idx_len'] * $info['range'] * $info['db_items'] * $info['time'] * $info['id_len'] == 0) die("Wrong file format {$db_file}\n");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
62
		$this->range       = $info['range'];
63
		$this->b_idx_len   = $info['b_idx_len'];
0 ignored issues
show
Bug Best Practice introduced by
The property b_idx_len does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
64
		$this->m_idx_len   = $info['m_idx_len'];
65
		$this->db_items    = $info['db_items'];
66
		$this->id_len      = $info['id_len'];
0 ignored issues
show
Bug Best Practice introduced by
The property id_len does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
67
		$this->block_len   = 3 + $this->id_len;
0 ignored issues
show
Bug Best Practice introduced by
The property block_len does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
68
		$this->max_region  = $info['max_region'];
0 ignored issues
show
Bug Best Practice introduced by
The property max_region does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
69
		$this->max_city    = $info['max_city'];
0 ignored issues
show
Bug Best Practice introduced by
The property max_city does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
70
		$this->max_country = $info['max_country'];
0 ignored issues
show
Bug Best Practice introduced by
The property max_country does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
71
		$this->country_size= $info['country_size'];
72
		$this->batch_mode  = $type & SXGEO_BATCH;
73
		$this->memory_mode = $type & SXGEO_MEMORY;
74
		$this->pack        = $info['pack_size'] ? explode("\0", fread($this->fh, $info['pack_size'])) : '';
0 ignored issues
show
Bug Best Practice introduced by
The property pack does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
75
		$this->b_idx_str   = fread($this->fh, $info['b_idx_len'] * 4);
76
		$this->m_idx_str   = fread($this->fh, $info['m_idx_len'] * 4);
77
78
		$this->db_begin = ftell($this->fh);
0 ignored issues
show
Bug introduced by
It seems like $this->fh can also be of type false; however, parameter $handle of ftell() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

78
		$this->db_begin = ftell(/** @scrutinizer ignore-type */ $this->fh);
Loading history...
79
		if ($this->batch_mode) {
80
			$this->b_idx_arr = array_values(unpack("N*", $this->b_idx_str)); // Быстрее в 5 раз, чем с циклом
81
			unset ($this->b_idx_str);
82
			$this->m_idx_arr = str_split($this->m_idx_str, 4); // Быстрее в 5 раз чем с циклом
83
			unset ($this->m_idx_str);
84
		}
85
		if ($this->memory_mode) {
86
			$this->db  = fread($this->fh, $this->db_items * $this->block_len);
87
			$this->regions_db = $info['region_size'] > 0 ? fread($this->fh, $info['region_size']) : '';
88
			$this->cities_db  = $info['city_size'] > 0 ? fread($this->fh, $info['city_size']) : '';
89
		}
90
		$this->info = $info;
91
		$this->info['regions_begin'] = $this->db_begin + $this->db_items * $this->block_len;
92
		$this->info['cities_begin']  = $this->info['regions_begin'] + $info['region_size'];
93
	}
94
95
	protected function search_idx($ipn, $min, $max){
96
		if($this->batch_mode){
97
			while($max - $min > 8){
98
				$offset = ($min + $max) >> 1;
99
				if ($ipn > $this->m_idx_arr[$offset]) $min = $offset;
100
				else $max = $offset;
101
			}
102
			while ($ipn > $this->m_idx_arr[$min] && $min++ < $max){};
0 ignored issues
show
Unused Code introduced by
This while loop is empty and can be removed.

This check looks for while loops that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

Consider removing the loop.

Loading history...
103
		}
104
		else {
105
			while($max - $min > 8){
106
				$offset = ($min + $max) >> 1;
107
				if ($ipn > substr($this->m_idx_str, $offset*4, 4)) $min = $offset;
108
				else $max = $offset;
109
			}
110
			while ($ipn > substr($this->m_idx_str, $min*4, 4) && $min++ < $max){};
0 ignored issues
show
Unused Code introduced by
This while loop is empty and can be removed.

This check looks for while loops that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

Consider removing the loop.

Loading history...
111
		}
112
		return  $min;
113
	}
114
115
	protected function search_db($str, $ipn, $min, $max){
116
		if($max - $min > 1) {
117
			$ipn = substr($ipn, 1);
118
			while($max - $min > 8){
119
				$offset = ($min + $max) >> 1;
120
				if ($ipn > substr($str, $offset * $this->block_len, 3)) $min = $offset;
121
				else $max = $offset;
122
			}
123
			while ($ipn >= substr($str, $min * $this->block_len, 3) && ++$min < $max){};
0 ignored issues
show
Unused Code introduced by
This while loop is empty and can be removed.

This check looks for while loops that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

Consider removing the loop.

Loading history...
124
		}
125
		else {
126
			$min++;
127
		}
128
		return hexdec(bin2hex(substr($str, $min * $this->block_len - $this->id_len, $this->id_len)));
129
	}
130
131
	public function get_num($ip){
132
		$ip1n = (int)$ip; // Первый байт
133
		if($ip1n == 0 || $ip1n == 10 || $ip1n == 127 || $ip1n >= $this->b_idx_len || false === ($ipn = ip2long($ip))) return false;
134
		$ipn = pack('N', $ipn);
135
		$this->ip1c = chr($ip1n);
136
		// Находим блок данных в индексе первых байт
137
		if ($this->batch_mode){
138
			$blocks = array('min' => $this->b_idx_arr[$ip1n-1], 'max' => $this->b_idx_arr[$ip1n]);
139
		}
140
		else {
141
			$blocks = unpack("Nmin/Nmax", substr($this->b_idx_str, ($ip1n - 1) * 4, 8));
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

141
			$blocks = /** @scrutinizer ignore-call */ unpack("Nmin/Nmax", substr($this->b_idx_str, ($ip1n - 1) * 4, 8));

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
142
		}
143
		if ($blocks['max'] - $blocks['min'] > $this->range){
144
			// Ищем блок в основном индексе
145
			$part = $this->search_idx($ipn, floor($blocks['min'] / $this->range), floor($blocks['max'] / $this->range)-1);
146
			// Нашли номер блока в котором нужно искать IP, теперь находим нужный блок в БД
147
			$min = $part > 0 ? $part * $this->range : 0;
148
			$max = $part > $this->m_idx_len ? $this->db_items : ($part+1) * $this->range;
149
			// Нужно проверить чтобы блок не выходил за пределы блока первого байта
150
			if($min < $blocks['min']) $min = $blocks['min'];
151
			if($max > $blocks['max']) $max = $blocks['max'];
152
		}
153
		else {
154
			$min = $blocks['min'];
155
			$max = $blocks['max'];
156
		}
157
		$len = $max - $min;
158
		// Находим нужный диапазон в БД
159
		if ($this->memory_mode) {
160
			return $this->search_db($this->db, $ipn, $min, $max);
161
		}
162
		else {
163
			fseek($this->fh, $this->db_begin + $min * $this->block_len);
0 ignored issues
show
Bug introduced by
$this->db_begin + $min * $this->block_len of type double is incompatible with the type integer expected by parameter $offset of fseek(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

163
			fseek($this->fh, /** @scrutinizer ignore-type */ $this->db_begin + $min * $this->block_len);
Loading history...
Bug introduced by
It seems like $this->fh can also be of type false; however, parameter $handle of fseek() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

163
			fseek(/** @scrutinizer ignore-type */ $this->fh, $this->db_begin + $min * $this->block_len);
Loading history...
164
			return $this->search_db(fread($this->fh, $len * $this->block_len), $ipn, 0, $len);
0 ignored issues
show
Bug introduced by
It seems like $this->fh can also be of type false; however, parameter $handle of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
			return $this->search_db(fread(/** @scrutinizer ignore-type */ $this->fh, $len * $this->block_len), $ipn, 0, $len);
Loading history...
Bug introduced by
$len * $this->block_len of type double is incompatible with the type integer expected by parameter $length of fread(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
			return $this->search_db(fread($this->fh, /** @scrutinizer ignore-type */ $len * $this->block_len), $ipn, 0, $len);
Loading history...
165
		}
166
	}
167
168
	protected function readData($seek, $max, $type){
169
		$raw = '';
170
		if($seek && $max) {
171
			if ($this->memory_mode) {
172
				$raw = substr($type == 1 ? $this->regions_db : $this->cities_db, $seek, $max);
173
			} else {
174
				fseek($this->fh, $this->info[$type == 1 ? 'regions_begin' : 'cities_begin'] + $seek);
0 ignored issues
show
Bug introduced by
It seems like $this->fh can also be of type false; however, parameter $handle of fseek() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

174
				fseek(/** @scrutinizer ignore-type */ $this->fh, $this->info[$type == 1 ? 'regions_begin' : 'cities_begin'] + $seek);
Loading history...
175
				$raw = fread($this->fh, $max);
0 ignored issues
show
Bug introduced by
It seems like $this->fh can also be of type false; however, parameter $handle of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

175
				$raw = fread(/** @scrutinizer ignore-type */ $this->fh, $max);
Loading history...
176
			}
177
		}
178
		return $this->unpack($this->pack[$type], $raw);
179
	}
180
181
	protected function parseCity($seek, $full = false){
182
		if(!$this->pack) return false;
183
		$only_country = false;
184
		if($seek < $this->country_size){
185
			$country = $this->readData($seek, $this->max_country, 0);
186
			$city = $this->unpack($this->pack[2]);
187
			$city['lat'] = $country['lat'];
188
			$city['lon'] = $country['lon'];
189
			$only_country = true;
190
		}
191
		else {
192
			$city = $this->readData($seek, $this->max_city, 2);
193
			$country = array('id' => $city['country_id'], 'iso' => $this->id2iso[$city['country_id']]);
194
			unset($city['country_id']);
195
		}
196
		if($full) {
197
			$region = $this->readData($city['region_seek'], $this->max_region, 1);
198
			if(!$only_country) $country = $this->readData($region['country_seek'], $this->max_country, 0);
199
			unset($city['region_seek']);
200
			unset($region['country_seek']);
201
			return array('city' => $city, 'region' => $region, 'country' => $country);
202
		}
203
		else {
204
			unset($city['region_seek']);
205
			return array('city' => $city, 'country' => array('id' => $country['id'], 'iso' => $country['iso']));
206
		}
207
	}
208
209
	protected function unpack($pack, $item = ''){
210
		$unpacked = array();
211
		$empty = empty($item);
212
		$pack = explode('/', $pack);
213
		$pos = 0;
214
		foreach($pack AS $p){
215
			list($type, $name) = explode(':', $p);
216
			$type0 = $type{0};
217
			if($empty) {
218
				$unpacked[$name] = $type0 == 'b' || $type0 == 'c' ? '' : 0;
219
				continue;
220
			}
221
			switch($type0){
222
				case 't':
223
				case 'T': $l = 1; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
224
				case 's':
225
				case 'n':
226
				case 'S': $l = 2; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
227
				case 'm':
228
				case 'M': $l = 3; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
229
				case 'd': $l = 8; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
230
				case 'c': $l = (int)substr($type, 1); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
231
				case 'b': $l = strpos($item, "\0", $pos)-$pos; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
232
				default: $l = 4;
0 ignored issues
show
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
233
			}
234
			$val = substr($item, $pos, $l);
235
			switch($type0){
236
				case 't': $v = unpack('c', $val); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

236
				case 't': $v = /** @scrutinizer ignore-call */ unpack('c', $val); break;

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
237
				case 'T': $v = unpack('C', $val); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
238
				case 's': $v = unpack('s', $val); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
239
				case 'S': $v = unpack('S', $val); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
240
				case 'm': $v = unpack('l', $val . (ord($val{2}) >> 7 ? "\xff" : "\0")); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
241
				case 'M': $v = unpack('L', $val . "\0"); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
242
				case 'i': $v = unpack('l', $val); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
243
				case 'I': $v = unpack('L', $val); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
244
				case 'f': $v = unpack('f', $val); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
245
				case 'd': $v = unpack('d', $val); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
246
247
				case 'n': $v = current(unpack('s', $val)) / pow(10, $type{1}); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
248
				case 'N': $v = current(unpack('l', $val)) / pow(10, $type{1}); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
249
250
				case 'c': $v = rtrim($val, ' '); break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
251
				case 'b': $v = $val; $l++; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
252
			}
253
			$pos += $l;
254
			$unpacked[$name] = is_array($v) ? current($v) : $v;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $v does not seem to be defined for all execution paths leading up to this point.
Loading history...
255
		}
256
		return $unpacked;
257
	}
258
259
	public function get($ip){
260
		return $this->max_city ? $this->getCity($ip) : $this->getCountry($ip);
261
	}
262
	public function getCountry($ip){
263
		if($this->max_city) {
264
			$tmp = $this->parseCity($this->get_num($ip));
265
			return $tmp['country']['iso'];
266
		}
267
		else return $this->id2iso[$this->get_num($ip)];
268
	}
269
	public function getCountryId($ip){
270
		if($this->max_city) {
271
			$tmp = $this->parseCity($this->get_num($ip));
272
			return $tmp['country']['id'];
273
		}
274
		else return $this->get_num($ip);
275
	}
276
	public function getCity($ip){
277
		$seek = $this->get_num($ip);
278
		return $seek ? $this->parseCity($seek) : false;
279
	}
280
	public function getCityFull($ip){
281
		$seek = $this->get_num($ip);
282
		return $seek ? $this->parseCity($seek, 1) : false;
283
	}
284
	public function about(){
285
		$charset = array('utf-8', 'latin1', 'cp1251');
286
		$types   = array('n/a', 'SxGeo Country', 'SxGeo City RU', 'SxGeo City EN', 'SxGeo City', 'SxGeo City Max RU', 'SxGeo City Max EN', 'SxGeo City Max');
287
		return array(
288
			'Created' => date('Y.m.d', $this->info['time']),
289
			'Timestamp' => $this->info['time'],
290
			'Charset' => $charset[$this->info['charset']],
291
			'Type' => $types[$this->info['type']],
292
			'Byte Index' => $this->b_idx_len,
293
			'Main Index' => $this->m_idx_len,
294
			'Blocks In Index Item' => $this->range,
295
			'IP Blocks' => $this->db_items,
296
			'Block Size' => $this->block_len,
297
			'City' => array(
298
				'Max Length' => $this->max_city,
299
				'Total Size' => $this->info['city_size'],
300
			),
301
			'Region' => array(
302
				'Max Length' => $this->max_region,
303
				'Total Size' => $this->info['region_size'],
304
			),
305
			'Country' => array(
306
				'Max Length' => $this->max_country,
307
				'Total Size' => $this->info['country_size'],
308
			),
309
		);
310
	}
311
}