Расчет дистанции между объектами

Приведу пару примеров расчета расстояния между объектами по заданным координатам

SELECT * ,  ( 3959 * acos( cos( radians(47) ) * cos( radians( latitude ) ) * cos( radians( longitude ) – radians( 35 ) ) + sin( radians( 47 ) ) * sin( radians( latitude ) ) ) ) AS distance  FROM sometable ORDER BY distance

Данный запрос возвращает все строки в таблице отсортированные  в порядке удаления от точки с заданными координатами.

3959 используется для вычисление дистанции в милях,  для вычисление дистанции в километрах нужно использовать 6371
в SQL запросе 47=это широта, 35- долгота в градусах.

Для получения строк с координатами объектов, удаленных от заданной точки на определеннорм расстоянии, нужно:

SELECT * ,  ( 3959 * acos( cos( radians(47) ) * cos( radians( latitude ) ) * cos( radians( longitude ) – radians( 35 ) ) + sin( radians( 47 ) ) * sin( radians( latitude ) ) ) ) AS distance  FROM sometable HAVING distance < 25 ORDER BY distance

Данный запрос возвратит только строки с объектами которые находятся ближе 25 миль от заданной точки (в километрах нужно 3959 заменить на 6371 )

Заменив знак < на > получите объекты которые дальше искомой точки не менее чем на 25 миль.

А используя LIMIT в запросе можно ограничивать количество возвращаемых объектов

Например LIMIT 0,1 вернет самый ближний, LIMIT 0,20 вернет 20 объектов.

Данные запросы используют формулу haversine  – частный случай более общей формулы сферической тригонометрии, подробнее о формуле тут http://en.wikipedia.org/wiki/Haversine_formula

И еще несколько расчетов тут http://www.movable-type.co.uk/scripts/latlong.html

Данные примеры рекомендую только для ознакомления с расчетами координат и дистанции.

На больших таблицах запросы ведут себя медленно, так как производится вычисление с каждой строкой в таблице.

Share and Enjoy:
  • Digg
  • Facebook
  • Twitter
  • Google Bookmarks
  • Live
  • MySpace

Базы данных GEO IP

Самые свежие базы geo ip для определения города и страны пользователя по ip адресу находятся тут http://geolite.maxmind.com/download/geoip/database/

Share and Enjoy:
  • Digg
  • Facebook
  • Twitter
  • Google Bookmarks
  • Live
  • MySpace

Оптимизация PHP

Профилирование кода

Если скорость выполнения кода неудовлетворительна, то первым делом необходимо его профилировать и измерить время, которое сценарий тратит на
выполнение различных задач и функций. На основе этой информации можно выяснить, на что сценарий расходует больше всего времени. Эти функции
называются узкими местами (bottlenecks).
Профилирование может преподнести сюрпризы. Например, может оказаться, что 99% времени сценарий тратит на запросы к базе данных, либо выявятся другие узкие места, такие как дисковый ввод/вывод при чтении больших файлов или журналов. Оптимизация не может быть эффективной без предварительного профилирования.

Как профилировать сценарии РНР
Для того чтобы профилировать сценарий РНР, надо снабдить таймерами некоторые функции и задачи сценария и измерить продолжительность их выполнения.
Допустим, есть такой сценарий РНР:
<?php
// Some initializations
require_once(»some_class.php»);
$foo = new some_class();
$res1 = $foo->do_a_method();
$res2 = $foo->do_a_method2();
echo($res1);
echo($res2);
?>

Если эффективность этого сценария недостаточна, то подозрение может пасть на три объекта, первым из которых оказывается конструктор some_class( ), вызываемый при создании объекта $foo.
Второй и третий подозреваемые – два вызываемых метода. Весь сценарий выполняется 2,3 секунды, и надо определить, как это время распределяется между тремя подозреваемыми.
Некоторое подозрение падает еще на четвертого, – как долго выполняется
require_once(), когда some_class() включает много методов. В интересах задач, обсуждаемых в этой главе, предположим, что вызов require_once( ) отнимает незначительную часть из 2,3 секунды времени выполнения сценария.
В РНР есть функция time(), возвращающая количество секунд, истекших с 1970 года. Однако она едва ли нам поможет, поскольку сценарии, в большинстве своем, выполняются менее чем за секунду, а если время выполнения сценария измеряется секундами, нужна намного большая точность, чтобы понять, на что тратится время. Точность эту обеспечивает функция microtime.

Функция microtime
Эта функция возвращает строку вида msec sec, где msec представляет составляющую в микросекундах, a sec – количество секунд после 1970 года, например:

<?php
echo(microtimeO);
?>

Результат может быть таким: 0.15672253 987612546
Это не очень удобно для вычисления разницы во времени, поэтому результат можно обработать так:
<?php
$time_portions = explode( ‘ ‘, microtimeO);
$actual_time = $titne_portions[1] . substr($time_portions[0], 1);
echo($actual_time);

С помощью этого кода преобразуем 0.15672253 987612546 в 987612546.15672253
Теперь надо получить эти числа перед выполнением функции или участка кода и после и найти разность между ними. Для получения разности с достаточной точностью служит функция bc_sub():

<?php
$elapsect_time = bcsub($end_time, $start_time, 6);
Для выполнения этого сценария расширение bcmath надо скомпилировать с РНР с помощью параметра –enable-bc-math.
Здесь 6 указывает количество десятичных знаков, которое надо сохранить в результате.
Создание класса Timer.
Заводить класс таймера при наличии средства профилирования РНР необязательно.
Этот класс поддерживает множественные таймеры. Далее описываются его основные функции:
timerStart().
Запускаем новый таймер или оставляем его как таймер по умолчанию.
Чтобы запустить таймер с определенным именем, вызываем timer_start(’foo’).
timerStop()
Останавливает заданный таймер или таймер по умолчанию, если имя не задано. Возвращает истекшее время работы таймера.
<?php
class Timer
var $timers = array();
function Timer() ;
// Nothing
function timerStart($name = ‘default’)
$time_portions = explode(’ ‘, microtime());
$actual_time =, $time_portions[1] . substr($time_portions[0], 1);
$this->timers['$name'] = $actual_time;
function timerStop($name = ‘default’)
$time_portions = explode(’ ‘, microtime());
$actual_time = $time_portions[1].substr($time_portipns[0], 1);
$elapsed_time = bcsub($actual_time, $this->timers['$name.'],6);
}
}
return $elapsed_time;
?>
Класс Timer вычитает одно время из другого с помощью функции bcsub( ), гарантирующей применения арифметики с повышенной точностью.
Сообщение error_message(undefined function bcsub ….. ) означает, что функции bcmath не были скомпилированы с РНР. Добавьте -enable-bcmath в строку
конфигурации, перекомпилируйте РНР и попытайтесь выполнить сценарий снова.
Мы проверили основу работы класса таймера. Еще один класс таймера входит в состав PEAR в файле pear/Benchmark/Timer. php дистрибутива РНР.
Класс PEAR отличается большей полнотой и сложностью.
Напишем другой класс – Time_Info, показывающий время, затраченное на выполнение функции phpinfo() и функции multiply(), умножающей большие числа:
<?php
// Этот тестовый класс показывает время, затраченное на выполнение функции,
// содержащей phpinfo(), и другой функции, перемножающей большие числа.
class Time_Info
{
// Конструктор
function Time_Info(){}
// Метод 1: содержит встроенную функцию phpinfoO
function phpinf()
{
phpinfo();
}
// Метод 2: перемножение больших чисел
function multiply()
{
$multiplied=10000*10000*10000*10000;
}
}
?>
Напишем теперь более сложный сценарий, основываясь на приведенном примере. Окружим каждый подозреваемый участок кода вызовами timer Start() и timerStop(), чтобы измерить время выполнения фрагментов:
<?php
// Инициализация
require_once(»Timer. php»);
require_once( «Time_Info.php» );
$tim = new Tlmer();
$tim->timerStart( ‘total’);
$tim->timerStart();
$foo = new Time_Info();
print(»Constructor: » . $tim->timerStop(). «<br>» );
$tim->titnerStart();
$res1 = .$foo->phpinf();
print(»Method1: » . $tim->timerStop(). «<br>» );
$tim->timerStart();
$res2 = $foo->multiply();
print(»Method2: » . $tim->timerStop(). «<br>» );
echo($res1);
echo($res2);
print( «Total execution time: » , $tim->tinierStop( ‘ total’) . «<br>»);
?>
Посмотрим, сколько времени заняли конструктор, php_inf() и multiply(), а также общее время выполнения сценария:
Constructor: 0.000084
Method1: 0.037100
Method2: 0.000101
Total execution time: 0.037980
Прогнав этот тест несколько раз, мы получим всю информацию, необходимую, чтобы узнать, которая из трех функций нуждается в оптимизации.
Итак, мы создали профиль для сценария.
Классификация узких мест
Профилирование осуществляется для поиска узких мест, а когда они обнаружены, их следует классифицировать по нескольким параметрам. Во-первых, надо оценить степень серьезности каждого узкого места. Во-вторых, следует оценить сложность оптимизации каждого из них. С учетом этих факторов принимается решение о том, какие функции, участки кода или методы сценария должны быть оптимизированы.

Share and Enjoy:
  • Digg
  • Facebook
  • Twitter
  • Google Bookmarks
  • Live
  • MySpace

Создание xls на php (без установки PEAR)

php_writeexcel является аналогом библиотеки PEAR:: Spreadsheet_Excel_Writer
 - Perl пакет для PHP. Это позволяет создавать документы Microsoft Excel на PHP без установки на сервер каких-либо дополнительных инструментов. Просто загружаете файлы и вперед…….. создавать xls

Работа с библиотекой сводится к простым вызовам функций. К сожалению даннай аналог не имеет документации.  Поэтому прийдется осваивать самому.

xls-writer вы найдете здесь http://www.bettina-attack.de/jonny/view.php/projects/php_writeexcel/, там же и несколько примеров о том  как создавать xls на php.

Это лучший скрипт для создания xls на php в своем роде.

Вот несколько особенностей (но данными не ограничивается)

  • Поддержка вставки картинок
  • Стили ячеек, шрифтов 
  • Работа с большими файлами
  • Работа со страницами

И самое главное данный xls-writer очень пригоден для работы в паре с xls-reader. Смотри статью Чтение xls на php

Share and Enjoy:
  • Digg
  • Facebook
  • Twitter
  • Google Bookmarks
  • Live
  • MySpace

Чтение xls на php

Если вам необходимо читать файлы Excel (.xls) средствами PHP, то библиотека PHP-ExcelReader создана специально для вас. Для работы необходима поддержка или mbstring. Вот пример того, как можно оформить вывод xls-документа в HTML-таблицу с использованием этой библиотеки.

Для работы с кириллицей нужно изменить кодировку UTF8 (по умолчанию) на CP1251 в файле excell_reader2.php: var $_defaultEncoding = «CP1251″
Данная библиотека протестированна и работает почти на 100%. Единственная проблема это использование функции dump(), она не отображает кириллицу. Однако если использовать просто массивы возвращаемые данной библиотекой то данное решение можно считать окончательным.

В последней версии xls-reader есть поддержка шрифтов, размеров столбцов и строк, цвета ячеек, границы, заливка и многое другое

http://code.google.com/p/php-excel-reader/ по данной ссылку вы найдете страницу разработчика xls-reader и сможете скачать последнюю вернсию.

От себя скажу, что это самая лучшая реализация чтения excel на php из всех тех, что я находил в сети.

Share and Enjoy:
  • Digg
  • Facebook
  • Twitter
  • Google Bookmarks
  • Live
  • MySpace