SASGIS

Веб-картография и навигация

Поддержка PHP скриптов

Форум для обсуждения деталей разработки программы SAS.Планета

Модераторы: vdemidov, Tolik

Re: Поддержка PHP скриптов

Сообщение zed » 30 мар 2011, 21:00

Ну, кажись получилось :)
Но нужно серьёзно протестировать.

Инструкция простая:
1. Включаем использование php в params.txt: UsePHPScript=1
2. Пишем скрипт и кладём его в zmp. Есть ряд предопределённых переменных, которым в скрипте в обязательном порядке нужно что-то присвоить (описание см. в примере ниже), иначе сас откажется работать. Скрипт должен называться downloader.php и никак иначе.
3. Запускаем и пользуем. Предварительно убеждаемся, в том что у нас php либо установлен в систему, либо в директории с сас лежит php5ts.dll.

Скрипт которым я тестил (немного кривой, но рабочий - в конце тайлов остаются 2 лишних байта: 0D 0A):
Код: Выделить всё
<?php 

/*

Предопределённые переменные:

1. $errstr - строка, любая текстовая информация об ошибке скрипта - возвращается в SAS (необязательный параметр)

2. $download_result - число от 0 до 9 - возвращается в SAS (обязательный параметр)

                      0 - OK
                 1 - SameTileSize
                 2 - ErrorInternetOpen
                 3 - ErrorInternetOpenURL
                 4 - ProxyAuthError
                 5 - ErrorMIMEType
                 6 - DownloadError
                 7 - TileNotExists
                 8 - BanError
                 9 - UnknownError

3. $url - строка, полный url запроса - возвращается в SAS (обязательный параметр)

4. $mme_type - строка, тип контента - возвращается в SAS (обязательный параметр)

5. $cookie - строка, любая информация передаваемая между скриптами - возвращается в SAS (необязательный параметр)

6. $x,$y,$z - числа, параметры карты ($z - нумерация с нуля)

7. $old_tile_sz - число, размер имеющего тайла в кэше, либо -1


*/
   
   /* --------------------------------------------------------------------------------------------------------- */
   
   $download_result = 9;
   
   $url = "http://127.0.0.1:8081/jpegfile?db=earth&ver=0&date=0&x=".$x."&y=".$y."&z=".$z;
   $mme_type = "image/jpg";
   $body = '';
    $cookie = '';
   $errstr = '';
   
   $z = $z + 1;
   
   $body = http_request(
         'GET',
         '127.0.0.1',
         8081,
         "/jpegfile?db=earth&ver=0&date=0&x=".$x."&y=".$y."&z=".$z,
         array(),
         array(),
         array('Cookie' => 'TestCookie'),
         array('Referer' => 'TestReferer'),
         30000,
         false,
         false
         );
   
   if ($body != '') {
   
     $download_result = 0; // говорим сас - OK
     print $body;          // и отдаём тайл (без хидеров)
   
   }
   else
     $download_result = 7; // говорим, что тайл отсутствует
   
      
   /* --------------------------------------------------------------------------------------------------------- */
   
   
   function http_request(
    $verb = 'GET',             /* HTTP Request Method (GET and POST supported) */
    $ip,                       /* Target IP/Hostname */
    $port = 80,                /* Target TCP port */
    $uri = '/',                /* Target URI */
    $getdata = array(),        /* HTTP GET Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $postdata = array(),       /* HTTP POST Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $cookie = array(),         /* HTTP Cookie Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $custom_headers = array(), /* Custom HTTP headers ie. array('Referer: http://localhost/ */
    $timeout = 1000,           /* Socket timeout in milliseconds */
    $req_hdr = false,          /* Include HTTP request headers */
    $res_hdr = false           /* Include HTTP response headers */
    )
{
    $ret = '';
    $verb = strtoupper($verb);
    $cookie_str = '';
    $getdata_str = count($getdata) ? '?' : '';
    $postdata_str = '';

    foreach ($getdata as $k => $v)
        $getdata_str .= urlencode($k) .'='. urlencode($v);

    foreach ($postdata as $k => $v)
        $postdata_str .= urlencode($k) .'='. urlencode($v) .'&';

    foreach ($cookie as $k => $v)
        $cookie_str .= urlencode($k) .'='. urlencode($v) .'; ';

    $crlf = "\r\n";
    $req = $verb .' '. $uri . $getdata_str .' HTTP/1.1' . $crlf;
    $req .= 'Host: '. $ip . $crlf;
    $req .= 'User-Agent: Mozilla/5.0 Firefox/3.6.12' . $crlf;
    $req .= 'Accept: image/jpg' . $crlf;
   
    foreach ($custom_headers as $k => $v)
        $req .= $k .': '. $v . $crlf;
       
    if (!empty($cookie_str))
        $req .= 'Cookie: '. substr($cookie_str, 0, -2) . $crlf;
       
    if ($verb == 'POST' && !empty($postdata_str))
    {
        $postdata_str = substr($postdata_str, 0, -1);
        $req .= 'Content-Type: application/x-www-form-urlencoded' . $crlf;
        $req .= 'Content-Length: '. strlen($postdata_str) . $crlf . $crlf;
        $req .= $postdata_str;
    }
    else $req .= $crlf;
   
    if ($req_hdr)
        $ret .= $req;
   
    if (($fp = @fsockopen($ip, $port, $errno, $errstr)) == false)
        return "Error $errno: $errstr\n";
   
    stream_set_timeout($fp, 0, $timeout * 1000);
   
    fputs($fp, $req);
    while ($line = fgets($fp)) $ret .= $line;
    fclose($fp);
   
    if (!$res_hdr)
        $ret = substr($ret, strpos($ret, "\r\n\r\n") + 4);
   
    return $ret;
}
?>


Ссылка: http://narod.ru/disk/8870874001/sas.php.test.zip.html - sas + php5ts.dll + тестовая карта с активированным скриптом (настроен на GeoCacher).
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Поддержка PHP скриптов

Сообщение Tolik » 31 мар 2011, 08:16

в конце тайлов остаются 2 лишних байта: 0D 0A

Может заменить print на printf или типа того?

"/jpegfile?db=earth&ver=0&date=0&x=".$x."&y=".$y."&z=".$z,

Значит, GetUrlScript.txt и DefURLBase тогда не нужны?
Tolik
Гуру
 
Сообщения: 2604
Зарегистрирован: 28 янв 2011, 10:38
Благодарил (а): 280 раз.
Поблагодарили: 587 раз.

Re: Поддержка PHP скриптов

Сообщение nafa » 31 мар 2011, 09:24

Скажите пожалуйста, а можно как-то получить доступ к параметрам GetLLon, GetBLat, GetRLon, GetTLat ? (Это координаты границ тайла. Используются например при доступе к слою Панорамио).

В САСе сейчас это выглядит так: ResultURL:=GetURLBase+RoundEx(GetLLon,9)+','+RoundEx(GetBLat,9)+','+RoundEx(GetRLon,9)+','+RoundEx(GetTLat,9);
nafa
Новичок
 
Сообщения: 25
Зарегистрирован: 20 дек 2010, 10:53
Благодарил (а): 2 раз.
Поблагодарили: 7 раз.

Re: Поддержка PHP скриптов

Сообщение zed » 31 мар 2011, 13:41

Значит, GetUrlScript.txt и DefURLBase тогда не нужны?

Не нужны.
Скажите пожалуйста, а можно как-то получить доступ к параметрам GetLLon, GetBLat, GetRLon, GetTLat ?

Вообще-то, все дополнительные параметры получаются из X,Y,Z по соответствующим алгоритмам, которые можно реализовать самостоятельно на php. Но в принципе ввести все эти переменные что были в паскалевском скрипте в php не сложно.
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Поддержка PHP скриптов

Сообщение vasketsov » 31 мар 2011, 14:15

zed писал(а):
Значит, GetUrlScript.txt и DefURLBase тогда не нужны?

Не нужны

А что будет отображаться в соответствующем поле в настройках карты в программе?
Не хотелось бы просто засерить это поле.
Может там писать список пар
параметр1=значение1
параметр2=значение2
и передавать их в скрипт?
Чтобы скриптом управлять из сас хотя бы минимально можно было без перезапуска.
vasketsov
Специалист
 
Сообщения: 901
Зарегистрирован: 25 июл 2009, 21:15
Благодарил (а): 0 раз.
Поблагодарили: 198 раз.

Re: Поддержка PHP скриптов

Сообщение zed » 31 мар 2011, 20:38

vasketsov писал(а):Чтобы скриптом управлять из сас хотя бы минимально можно было без перезапуска.

А вот этот момент я как-то упустил.
Значит введу ещё кучку параметров:
$url - раньше он приходил всегда пустой, а сейчас в нём будет тот кусок url, что редактируется в сас (т.е. будет возможность его менять)
$def_url - будет всегда равен DefURLBase (на всякий пожарный)
+ надо ещё подумать над аналогами GetLLon, GetBLat, GetRLon, GetTLat, GetLMetr, GetRMetr, GetTMetr, GetBMetr которые маскируют по 2 параметра каждый (X,Y) - итого 16 доп. переменных.
+ в паскаль-скриптах были и такие переменные : dLpix, dTpix, dBpix, dRpix - это ещё 4 переменных.
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Поддержка PHP скриптов

Сообщение Tolik » 01 апр 2011, 08:52

zed писал(а):dLpix, dTpix, dBpix, dRpix

А это что?
Tolik
Гуру
 
Сообщения: 2604
Зарегистрирован: 28 янв 2011, 10:38
Благодарил (а): 280 раз.
Поблагодарили: 587 раз.

Re: Поддержка PHP скриптов

Сообщение zed » 01 апр 2011, 21:27

Tolik писал(а):А это что?

А чтоб я знал?

Сегодняшняя альфа, для теста php: http://narod.ru/disk/9048054001/SAS.Pla ... P.zip.html

params.txt:
Код: Выделить всё
Поддержка php скриптов в SAS является опциональной и может быть включена для
каждой карты/слоя в отдельности. Настройки php находятся в zmp карты в файле
настроек params.txt - секция PHP:

[PHP]
Use=1
Preload=1
Debug=0
CustomParams=0

Описание:

Use=1 - использовать php скрипт downloader.php из текущего zmp для загрузки тайлов
        из интернета. При этом встроенный в SAS загрузчик тайлов не используется.
       
Use=0 - использовать стандартный способ загрузки тайлов.

Preload=1 - загружать скрипт в память единожды, и выполнять его оттуда не насилуя винт.
            НО если скрипт подключает дополнительные файлы (include/requare), то будучи
            загруженным в память он не сможет запуститься, т.к. php не сможет найти все
            инклуды.
           
Preload=0 - скрит запускается с диска и проблем с инклудами быть не должно.
           
Debug=1 - включить выдачу ошибок от движка php (включать только для отладки скрипта - для
          нормального режима предусмотрен вывод ошибки из скрипта через зарезервированную
          переменную $ErrStr)
         
CustomParams=1 - включить объявление дополнительных переменных для скрипта.

Если секция [PHP] отсутствует в params.txt, то используется стандартный способ загрузки тайлов.

P.S. Поскольку SAS не интерпретирует скрипты, а лишь запускает их на выполнение, то необходим
     собственно интерпретатор php - это либо файл php5ts.dll в корневой директории SAS, либо
     установленный в системе php (путь до php должен быть прописан в PATH, в следствии чего,
     скрипты должны иметь возможность выполняться прямо из командной строки).     
     
P.P.S. Работа SAS тестировалась с php версии 5.3.6, но по идее, должно работать с любой
       версией php 5.x


downloader.php:
Код: Выделить всё
Предопределённые (зарезервированные) переменные - переменные, объявленные и
проинициализированные в SAS перед вызовом скрипта.

По смысловой нагрузке предопределённые переменные подразделяются на:

    - обязательные переменные (параметры) - переменные, значение которых
      проверяется в SAS после завершения скрипта. В звисимости от значений данных
      переменных SAS ведёт себя тем или иным образом. В скрипте этим переменным
      должны быть присвоены определённые значения в ОБЯЗАТЕЛЬНОМ порядке;

    - необязательные переменные - значение этих переменных так же проверяется в
      SAS, но в скрипте их использовать и присваивать им какие-либо значения
      не обязательно. Значение этих переменных так же может влиять на поведение
      SAS;

    - основные переменные - базовый набор переменных для выполнения запроса. В SAS
      никак не проверяются (только инициализируются);

    - дополнительные переменные - дополнительный набор переменных. Аналогичен основным
      переменным, за исключением того, что они присутствуют лишь опционально. Для того,
      чтобы эти переменные были проинициализированы в SAS, нужно включить соответствующую
      опцию в params.txt
   
    - параметры прокси-сервера которые выбраны в текущий момент в SAS (вкладка Интернет)

Список и расшифровка всех предопределённых переменных:


1. Обязательные переменные.

1.1. $DownloadResult - integer, от 0 до 9. На основе данной переменной SAS
                       определяет была ли загрузка тайла удачной или возникла
                       ошибка. Расшифровка возможных значений:
                        0 - OK
                        1 - SameTileSize
                        2 - ErrorInternetOpen
                        3 - ErrorInternetOpenURL
                        4 - ProxyAuthError
                        5 - ErrorMIMEType
                        6 - DownloadError
                        7 - TileNotExists
                        8 - BanError
                        9 - UnknownError
                       Переменная проинициализирована значением: 9 - UnknownError

1.2. $MIMEType - string, должна содержать ContentType. По результату выполнения скрипта,
                 значение переменной сравнивается с соответствующей строкой из params.txt.
                 По результатам этих сравнений SAS принимает решение о (не)сохранении
                 и (не)отображении тайла.
                 Проинициализирована пустой строкой: ''


2. Необязательные переменные.

2.1. $ErrStr - string, любая текстовая информация об ошибке скрипта.
               Если в $ErrStr будет содержаться любая информация, то в SAS будет
               возбуждено исключение с текстом из $ErrStr (данный текст будет
               отображен на месте тайла в SAS, в следствии чего, длина сообщения
               должна быть как можно короче).
               Проинициализирована пустой строкой: ''

2.2. $СookieStr - string, любая информация передаваемая между скриптами. Инициализируется
                  предыдущим состоянием.


3. Основные переменные.

3.1. $Url - string, проинициализирована значением DefURLBase взятым из GUI SAS

3.2. $DefUrl - string, проинициализирована значением DefURLBase взятым из params.txt

3.3. $X,$Y,$Z - integer, параметры тайла

3.4. $OldTileSize - integer, размер имеющего тайла в кэше, либо -1


4. Дополнительные переменные.

4.1. $LLon - double,

4.2. $TLat - double,

4.3. $RLon - double,

4.4. $BLat - double,

4.4. $LMetr - double,

4.6. $TMetr - double,

4.7. $RMetr - double,

4.8. $BMetr - double,


5. Параметры прокси-сервера.

5.1. $ProxyUseIESettings - boolean, брать настройки из реестра

5.2. $UseProxy - boolean, использовать прокси

5.3. $ProxyUseLogin - boolean, использовать логин и пароль

5.4. $ProxyLogin - string, логин

5.5. $ProxyPassword - string, пароль

5.6. $ProxyHost - string, прокси:порт (ip:port)


Примечание: Следует обратить внимание на то, что в PHP все переменные
            регистрозависимые: $X и $x - две различные переменные.

За это сообщение автора zed поблагодарили: 2
nafa (01 апр 2011, 23:15) • zOn (12 янв 2012, 23:50)
Рейтинг: 10.53%
 
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Поддержка PHP скриптов

Сообщение zed » 01 апр 2011, 21:31

Tolik писал(а):
в конце тайлов остаются 2 лишних байта: 0D 0A

Может заменить print на printf или типа того?

Ничё не помогает. Возможно оно уходит нормально, а приходит уже с лишними байтами. Придётся тогда резать уже в SAS, по факту получения...
zed
Гуру
 
Сообщения: 2888
Зарегистрирован: 16 авг 2008, 20:21
Благодарил (а): 89 раз.
Поблагодарили: 568 раз.

Re: Поддержка PHP скриптов

Сообщение Parasite » 02 апр 2011, 08:22

zed писал(а):
Tolik писал(а):
в конце тайлов остаются 2 лишних байта: 0D 0A

Может заменить print на printf или типа того?

Ничё не помогает. Возможно оно уходит нормально, а приходит уже с лишними байтами. Придётся тогда резать уже в SAS, по факту получения...

Сам скрипт пока не видел, посему вопрос - а читаем\пишем данные мы в скрипте\в хэндлере в бинарном режиме или в строковом? ;)
В перле для этого есть BINMODE <хэндлер>, в PHP всё не так прозрачно:
Код: Выделить всё
Processing Binary Files In PHP

This little tip might be usefull for people who have recently started learning PHP and have some experience in other languages (like me).

Recently I needed to write a PHP script that would process a binary file I had created in my Delphi program. However, it turned out that fread() doesn’t work as expected – it always returns a string. So if you want to read a 32-bit integer from a binary file, doing $an_integer=fread($f, 4) won’t get the desired result – $an_integer will be a string containing some weird characters.

To correctly read/write binary data in PHP you need to use the pack() and unpack() functions.

For example, to read two cardinals (unsigned 32-bit integer) from a file:
$fp=fopen(“file.bin”,”rb”);
$bin=fread($fp,8);
$data=unpack(“V1x/V1y”,$bin);
fclose($fp)

$data["x"] and $data["y"] would contain the two numbers. The first argument to unpack() defines the structure of data to be read. See the documentation for a description of the format string.

Another thing to note is that Delphi (at least the latest versions) will save fixed-length strings as null-padded (format code “a”). Also, if you write record structures to a file you intend to process with PHP or another non-Delphi program, it is advisable to use the packed keyword to make the actual structure of binary data more predictable.

http://w-shadow.com/blog/2006/10/17/processing-binary-files-in-php/
The only difference between me and a mad man is that I am not mad. /Salvador Dali/
Изображение
Аватара пользователя
Parasite
Администратор
 
Сообщения: 5646
Зарегистрирован: 23 окт 2008, 17:38
Благодарил (а): 124 раз.
Поблагодарили: 512 раз.

Пред.След.

Вернуться в Раздел для разработчиков программы SAS.Планета

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

cron