Всем привет. У меня такая вот проблема: есть найденный в сети скрипт, который проверяет айпишник пользователя, пришедшего на сайт, на принадлежность к диапазону. В тестовом виде все работает отлично: PHP: <?php function CheckIP ( ) { $ip_arr = explode ( '/' , '212.98.160.0/19' ); $network_long = ip2long ( $ip_arr [ 0 ]); $x = ip2long ( $ip_arr [ 1 ]); $mask = long2ip ( $x ) == $ip_arr [ 1 ] ? $x : 0xffffffff << ( 32 - $ip_arr [ 1 ]); $ip_long = ip2long ( $_SERVER['REMOTE_ADDR'] ); // echo ">".$ip_arr[1]."> ".decbin($mask)."\n"; return ( $ip_long & $mask ) == ( $network_long & $mask ); } ?> Айпишник моего компа входит в диапазон и то что нужно отображается, а когда захожу через проксю - нет. Что и требуется. Но нужно прикрутить проверку многих диапазонов, по-этому я "написал" вот это: PHP: <?php function CheckIP() { $range_from = array("62.32.47.0/24", "62.32.61.0/28", "62.187.241.0/27", "65.110.43.30/31", "65.110.43.32/29", "65.110.45.150/31", "65.110.45.152/29", "65.110.50.40/29", "65.110.50.48/31", "65.110.54.20/30", "65.110.54.24/30", "65.110.54.28/31", "66.118.187.128/29", "66.118.187.152/29", "77.74.32.0/21", "78.109.30.32/29", "79.98.48.0/21", "79.170.104.0/21", "80.94.160.0/20", "80.94.224.0/20", "80.249.80.0/20", "81.25.32.0/20", "81.30.80.0/20", "82.209.192.0/18", "84.201.224.0/20", "86.57.128.0/17", "87.252.224.0/19", "91.149.128.0/18", "91.187.0.0/19", "93.84.0.0/15", "93.125.0.0/17", "93.191.96.0/21", "193.17.173.0/24", "193.26.18.0/24", "193.151.40.0/22", "193.232.92.0/24", "193.232.248.0/22", "194.67.192.0/23", "194.69.70.72/29", "194.84.74.64/26", "194.84.74.128/25", "194.84.145.0/24", "194.85.254.0/23", "194.158.192.0/19", "194.226.120.0/22", "194.226.124.0/23", "194.226.126.0/24", "195.50.0.0/19", "195.51.243.0/26", "195.95.218.0/23", "195.137.160.0/24", "195.137.180.0/24", "195.212.202.64/26", "195.222.64.0/19", "206.49.97.0/24", "207.150.184.120/29", "207.241.164.224/28", "208.66.193.80/28", "212.63.175.174/32", "212.95.54.0/24", "212.98.160.0/19", "212.176.22.32/27", "212.176.22.64/26", "212.176.22.128/27", "212.176.22.192/26", "213.85.57.0/24", "213.156.141.0/24", "213.184.224.0/19", "217.21.32.0/19", "217.23.112.0/20", "217.107.213.0/25"); $ip_long = ip2long ( $_SERVER['REMOTE_ADDR'] ); for ($i = 0; $i < 72; $i++) { $ip_arr = explode ( '/' , $range_from[i] ); $network_long = ip2long ( $ip_arr[0] ); $x = ip2long ( $ip_arr [1]); $mask = long2ip ( $x ) == $ip_arr [ 1 ] ? $x : 0xffffffff << ( 32 - $ip_arr [ 1 ]); // echo ">".$ip_arr[1]."> ".decbin($mask)."\n"; if(( $ip_long & $mask ) == ( $network_long & $mask )) return true; } return false; } ?> И вот эта дрянь уже работать не захотела, помогите пожалуйста, где я намуд(р)ил? P.S. : Сразу массив range_from инициализировался константами- не работало, поменял на строке - один хрен. Переменными тут вроде не отделаешься. На мой дилетантский взгляд синтаксис правильный, тем более что большей частью код скопипастен. Увы я PHP пока не знаю.
Вижу опечатку: $ip_arr = explode ( '/' , $range_from[i] ); Надо: $ip_arr = explode ( '/' , $range_from[$i] );
Sephiroth_Lukaw Нет, он один раз высчитает, обрати внимание на: На $size = count($range_from) http://ru2.php.net/for Последний пример:
Позволю с вами не согласиться: Замечу, что for($i = 0, $size = sizeof($people); $i < $size; ++$i) и for ($i = 0; $i < $size = count($range_from); $i++) все же разные вещи, в первом случае при инициализации будет 1 раз вычислен размер массива и значение присвоено переменной $size. (Как в приведенном вами примере с http://ru2.php.net/for) А во втором случае (в вашем) при каждой итерации будет вычисляться размер массива и значение присваиваться переменной $size. Чтобы не быть голословным. Пример с http://ru2.php.net/for: PHP: // создал ("накопипастил") большой вложенный массив элементов на 1000 $array = array(.............................................. .............................................. .............................................. ); // отсечка времени $time = microtime(true); for ($i = 0, $count = count($array); $i < $count; $i++) { $test[$i] = 1; } printf("Время работы скрипта: %f c<br />", microtime(true) - $time); // в среднем получилось чуть меньше 0.000500 c А в вашем случае: PHP: for ($i = 0; $i < count($array); $i++) { $test[$i] = 1; } printf("Время работы скрипта: %f c<br />", microtime(true) - $time); // в среднем получилось около 0.000900 c Разница 0.000500 c и 0.000900 c заметная. А вы пишете "Нет, он один раз высчитает". Вводите в заблуждение людей!
А главное, был бы прок оптимизировать. count() - это очень быстрая нативная функция, немногим медленнее чтения значения из переменной Если внутри цикла будет что-то чуть посложнее одного присваивания, вся ваша копеечная экономия прикажет долго жить.
Полностью согласен. Но я не удержался и написал, потому что было категоричное высказывание "что при каждой итерации не будет вычисляться значение, а лишь при инициализации цикла". А на счет экономии даже где-то в мануале(книге) читал такое и кстати так же если нет строгой необходимости пишу for($i; $i< sizeof($array); $i++) - потому как более визуально приятнее.
В моем случае как раз таки и не так, а Видишь разницу? А теперь проверим: PHP: #!/usr/local/bin/php <?php $array= array("62.32.47.0/24", "62.32.61.0/28", "62.187.241.0/27", "65.110.43.30/31", "65.110.43.32/29", "65.110.45.150/31", "65.110.45.152/29", "65.110.50.40/29", "65.110.50.48/31", "65.110.54.20/30", "65.110.54.24/30", "65.110.54.28/31", "66.118.187.128/29", "66.118.187.152/29", "77.74.32.0/21", "78.109.30.32/29", "79.98.48.0/21", "79.170.104.0/21", "80.94.160.0/20", "80.94.224.0/20", "80.249.80.0/20", "81.25.32.0/20", "81.30.80.0/20", "82.209.192.0/18", "84.201.224.0/20", "86.57.128.0/17", "87.252.224.0/19", "91.149.128.0/18", "91.187.0.0/19", "93.84.0.0/15", "93.125.0.0/17", "93.191.96.0/21", "193.17.173.0/24", "193.26.18.0/24", "193.151.40.0/22", "193.232.92.0/24", "193.232.248.0/22", "194.67.192.0/23", "194.69.70.72/29", "194.84.74.64/26", "194.84.74.128/25", "194.84.145.0/24", "194.85.254.0/23", "194.158.192.0/19", "194.226.120.0/22", "194.226.124.0/23", "194.226.126.0/24", "195.50.0.0/19", "195.51.243.0/26", "195.95.218.0/23", "195.137.160.0/24", "195.137.180.0/24", "195.212.202.64/26", "195.222.64.0/19", "206.49.97.0/24", "207.150.184.120/29", "207.241.164.224/28", "208.66.193.80/28", "212.63.175.174/32", "212.95.54.0/24", "212.98.160.0/19", "212.176.22.32/27", "212.176.22.64/26", "212.176.22.128/27", "212.176.22.192/26", "213.85.57.0/24", "213.156.141.0/24", "213.184.224.0/19", "217.21.32.0/19", "217.23.112.0/20", "217.107.213.0/25"); $time = microtime(true); for ($i = 0; $i < count($array); $i++) $test[$i] = 1; printf("Время работы скрипта: %f c\n", microtime(true) - $time); $time = microtime(true); for ($i = 0; $i < $size = count($array); $i++) $test[$i] = 1; printf("Время работы скрипта: %f c\n", microtime(true) - $time); ?> Как раз таки один раз и выщитывается, так что в заблуждение людей вводишь ты.
Вы меня заставили отвлечься от черчения курсача по водоснабжению :E PHP: <?php $array = Array(1, 2, 3, 4, 5, 6, 7); function gg($array) { echo 'ohh no!<br>'; return sizeof($array); } for ($i = 0; $i < $count = gg($array); $i++); ?> result: Код (Text): ohh no! ohh no! ohh no! ohh no! ohh no! ohh no! ohh no! ohh no! PHP: <?php $array = Array(1, 2, 3, 4, 5, 6, 7); function gg($array) { echo 'ohh no!<br>'; return sizeof($array); } for ($i = 0; $i < gg($array); $i++); ?> Код (Text): ohh no! ohh no! ohh no! ohh no! ohh no! ohh no! ohh no! ohh no! PHP: <?php $array = Array(1, 2, 3, 4, 5, 6, 7); function gg($array) { echo 'ohh no!<br>'; return sizeof($array); } for ($i = 0, $count = gg($array); $i < $count; $i++); ?> Код (Text): ohh no! P.S. В for только первый параметр выполняется один раз, а остальные - при каждой итерации.
На самом деле я не прав, разница во времени выполнения этого примера приведённого мною выше совсем не из-за этого. Это можно легко проверить поменяв местами. PHP: for ($i = 0; $i < count($array); $i++); for ($i = 0; $i < $size = count($array); $i++); При каждой итерации будет заново считаться count. Мне просто вначале показалось что php "оптимизирует" такое выражение. Но это не так, да и не должно быть так... В общем переклинело меня сегодня немного что-то. Извиняюсь за то что ввел кого-то в заблуждение..
Спасибо всем откликнувшимся, очень познавательно. Завтра (те уже сегодня, но попозже) сообщу результаты.
Все это хорошо знакомо мне, но мне нужно узнать его программно в php... для того чтобы выдавать определенные права с привязкой по айпи, ну и возможно подсчета находящихся на сайте пользователей - кстати может такое уже есть готовое?
По поводу microtime() вопросик ещё возник. В начале скрипта вставляю такое: $mcrtime = microtime(); В конце такое: $mcrtime = microtime() - $mcrtime; echo $mcrtime; Обычно выскакивает вполне понятное 0.00хххх или 0.0ххххх, но иногда почему-то совсем непонятное -0.9ххххх . Почему?
sobachnik Видимо твой скрипт работает назад во времени, не тормозя, а ускоряя сервер! Научи нас тоже :lol:
:lol: :lol: :lol: Забавно! Только ведь он не всегда так работает... Обычно внизу появляется вполне понятное 0.00хххх, и где-то примерно в 5% случаях вот это -0.9ххххх . Причём в тексте самого скрипта не делаю никаких изменений - просто нажимаю F5 в браузере и примерно 1 раз на 20 выскакивает эта хрень... :roll:
Sergey89, спасибо! Мучал свой бедный комп наверно минуты три нажимая обновить, отрицательных значений не выскакивает! И всё же интересно, почему так было...?