Вот простой один вкладыш
$ip = $_SERVER['HTTP_X_FORWARDED_FOR']?: $_SERVER['HTTP_CLIENT_IP']?: $_SERVER['REMOTE_ADDR'];
EDIT:
Выше код может возвращать зарезервированные адреса (например, 10.0.0.1), список адресов всех прокси-серверов на пути и т. д. Для обработки этих случаев используйте следующий код:
function valid_ip($ip) {
// for list of reserved IP addresses, see https://en.wikipedia.org/wiki/Reserved_IP_addresses
return $ip && substr($ip, 0, 4) != '127.' && substr($ip, 0, 4) != '127.' && substr($ip, 0, 3) != '10.' && substr($ip, 0, 2) != '0.' ? $ip : false;
}
function get_client_ip() {
// using explode to get only client ip from list of forwarders. see https://en.wikipedia.org/wiki/X-Forwarded-For
return
@$_SERVER['HTTP_X_FORWARDED_FOR'] ? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2)[0] :
@$_SERVER['HTTP_CLIENT_IP'] ? explode(',', $_SERVER['HTTP_CLIENT_IP'], 2)[0] :
valid_ip(@$_SERVER['REMOTE_ADDR']) ?:
'UNKNOWN';
}
echo get_client_ip();
Относительный импорт происходит всякий раз, когда вы импортируете пакет относительно текущего скрипта / пакета.
Рассмотрим следующее дерево, например:
mypkg
├── base.py
└── derived.py
Теперь ваш derived.py
требует что-то из base.py
. В Python 2 вы можете сделать это так (в derived.py
):
from base import BaseThing
Python 3 больше не поддерживает это, поскольку он не является явным, хотите ли вы «относительного» или «абсолютного» base
. Другими словами, если в системе был установлен пакет Python с именем base
, вы бы ошибались.
Вместо этого он требует, чтобы вы использовали явный импорт , который явно указать расположение модуля на основе пути. Ваш derived.py
будет выглядеть так:
from .base import BaseThing
Ведущий .
говорит «import base
из каталога модуля»; Другими словами, .base
отображается на ./base.py
.
Аналогичным образом существует префикс ..
, который поднимается вверх по иерархии каталогов, такой как ../
(с ..mod
отображением на ../mod.py
), и затем ...
, который идет на два уровня вверх (../../mod.py
) и т. д.
Пожалуйста, обратите внимание, что относительные пути, перечисленные выше, относились к каталогу, в котором находится текущий модуль (derived.py
), не текущий рабочий каталог.
@BrenBarn уже объяснил случай импорта звезды. Для полноты, я должен будет сказать то же самое;).
Например, вам нужно использовать несколько функций math
, но вы используете их только в одной функции. В Python 2 вам разрешили быть полу-ленивым:
def sin_degrees(x):
from math import *
return sin(degrees(x))
Обратите внимание, что он уже запускает предупреждение в Python 2:
a.py:1: SyntaxWarning: import * only allowed at module level
def sin_degrees(x):
В современном коде Python 2 вы должны и в Python 3 вы должны сделать либо:
def sin_degrees(x):
from math import sin, degrees
return sin(degrees(x))
, либо:
from math import *
def sin_degrees(x):
return sin(degrees(x))
Чтобы поддерживать как Python 2, так и Python 3, используйте явно относительный импорт, как показано ниже. Они относятся к текущему модулю. Они поддерживаются , начиная с 2.5 .
from .sister import foo
import .brother
from ..aunt import bar
import ..uncle
Для относительного импорта см. документацию . Относительный импорт - это когда вы импортируете из модуля относительно местоположения этого модуля, а не абсолютно из sys.path
.
Что касается import *
, Python 2 допускал импорт звезд внутри функций, например:
>>> def f():
... from math import *
... print sqrt
Предупреждение выдается для этого в Python 2 (по крайней мере, в последних версиях). В Python 3 это больше не разрешено, и вы можете только импортировать звезды на верхнем уровне модуля (не внутри функций или классов).
Добавил еще один ответ на вопрос Михаила Горни:
Обратите внимание, что относительный импорт основан на имени текущего модуля. Поскольку имя основного модуля всегда «основное», модули, предназначенные для использования в качестве основного модуля приложения Python, должны всегда использовать абсолютный импорт.