Мне нужно проверить, открыт ли файл «локально» (тот же компьютер или сеть). Я использую:
<?php if ((substr($_SERVER['REMOTE_ADDR'],0,8) == "192.168.") || ($_SERVER['REMOTE_ADDR'] == "127.0.0.1")) { // client is local } else { // client is not local }
Но я не уверен, что это лучший способ.
Что является более надежным способом сделать это?
«Безвредность», как всегда, может быть сложной.
Если мы ограничимся IPv4, то проверка «127.0.0.1» позаботится о случае localhost, но проверяет «192.168». просто неверно – он будет работать, только если скрипт запускается на сервере, который находится в сети 192.168, используя 16-разрядную маску подсети.
Проверка $ _SERVER ['REMOTE_ADDR'] против $ _SERVER ['SERVER_ADDR'] была бы лучшей ставкой. Тем не менее это все равно не заботится о случае многодомного хоста (то есть, который имеет несколько IP-адресов в дополнение к 127.0.0.1).
Чтобы поймать все случаи с одинаковой сетью, вам нужно проверить комбинацию SERVER_ADDR и маски подсети с REMOTE_ADDR, но маска подсети недоступна в $ _SERVER.
НО я нашел функцию, которая делает в значительной степени то, что вы хотите здесь . Это несколько экранов, и это называется clientInSameSubnet. Не мой код, но выглядит правильно.
То, что сказал Фрик, верно, но при условии, что вы знаете, как получить IP-адрес реального клиента, вы можете определить, является ли он локальным адресом с использованием фильтров PHP :
if ( ! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) ) { // is a local ip address }
Если у кого-то есть проблемы с поиском вышеуказанного кода, предложенным @Uffe, я включил его ниже:
<?php /** * Check if a client IP is in our Server subnet * * @param string $client_ip * @param string $server_ip * @return boolean */ function clientInSameSubnet($client_ip=false,$server_ip=false) { if (!$client_ip) $client_ip = $_SERVER['REMOTE_ADDR']; if (!$server_ip) $server_ip = $_SERVER['SERVER_ADDR']; // Extract broadcast and netmask from ifconfig if (!($p = popen("ifconfig","r"))) return false; $out = ""; while(!feof($p)) $out .= fread($p,1024); fclose($p); // This is to avoid wrapping. $match = "/^.*".$server_ip; $match .= ".*Bcast:(\d{1,3}\.\d{1,3}i\.\d{1,3}\.\d{1,3}).*"; $match .= "Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/im"; if (!preg_match($match,$out,$regs)) return false; $bcast = ip2long($regs[1]); $smask = ip2long($regs[2]); $ipadr = ip2long($client_ip); $nmask = $bcast & $smask; return (($ipadr & $smask) == ($nmask & $smask)); }
в<?php /** * Check if a client IP is in our Server subnet * * @param string $client_ip * @param string $server_ip * @return boolean */ function clientInSameSubnet($client_ip=false,$server_ip=false) { if (!$client_ip) $client_ip = $_SERVER['REMOTE_ADDR']; if (!$server_ip) $server_ip = $_SERVER['SERVER_ADDR']; // Extract broadcast and netmask from ifconfig if (!($p = popen("ifconfig","r"))) return false; $out = ""; while(!feof($p)) $out .= fread($p,1024); fclose($p); // This is to avoid wrapping. $match = "/^.*".$server_ip; $match .= ".*Bcast:(\d{1,3}\.\d{1,3}i\.\d{1,3}\.\d{1,3}).*"; $match .= "Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/im"; if (!preg_match($match,$out,$regs)) return false; $bcast = ip2long($regs[1]); $smask = ip2long($regs[2]); $ipadr = ip2long($client_ip); $nmask = $bcast & $smask; return (($ipadr & $smask) == ($nmask & $smask)); }