Архив метки: php

Вызов скрипта на python из php с передачей произвольных данных

Редко,  но бывает необходимо из скрипта на PHP, вызвать на исполнение скрипт на python с передачей неких параметров и данных.

Мне например понадобилось потому что основной код у меня на PHP,  а вот часть которая отвечает за взаимодействие с онлайн кассой Атол — на python, и переписывать эту часть на PHP нет возможности (без большого гемороя) —  заголовки драйвера Атола под Linux есть только на python (dto9fptr.py и dto9base.py — поставляются в комплекте с драйвером).

Ниже приведен один из способов:

PHP:

<?php

$idkkm= _POST("idkkm");

$sql = "SELECT * FROM online_kkm where id='$idkkm'";
$result = $sqlcn->ExecuteSQL($sql) or die("Не могу выбрать список настроек!" . mysqli_error($sqlcn->idsqlconnection));
$param=array();
$param["mode"]="getinfo";
while ($row = mysqli_fetch_array($result)) {
    $param["ipaddress"] = $row['ipaddress'];
    $param["ipport"] = $row['ipport'];
    $param["model"] = $row['model'];
    $param["accesspass"] = $row['accesspass'];
    $param["userpass"] = $row['userpass'];
    $param["protocol"] = $row['protocol'];
    $param["logfilename"] = $row['logfilename'];
    $param["testmode"] = $row['testmode'];
    $param["libpath"] = $row['libpath'];
    $param["version"] = $row['version'];
    $ppath= $row['ppath'];
};
$jsonparam= base64_encode(json_encode($param));
$command = "/usr/bin/env python $ppath $jsonparam 2>&1";
$pid = popen( $command,"r");
while( !feof( $pid ) )
{
 echo fread($pid, 256);
 flush();
 ob_flush();
 usleep(100000);
}
pclose($pid);

?>

Python:

#!/usr/bin/env python2
#encoding: UTF-8
import sys, json,base64

prm=json.loads(base64.b64decode(sys.argv[1]))

print prm["ipaddress"]

Т.е. что мы сделали?

  1. В скрипте на PHP сформировали json строку с параметрами и закодировали её в base64
  2. Вызвали python скрипт с аргументом в кодированной строки
  3. Python скрипт соответственно обратно декодирует и обрабатывает json

Профит.

Вложенный в письмо файл winmail.dat

Иногда попадаются письма, которые не удается распарсить средствами модуля imap на php — вложения он упорно видит одним файлом winmail.dat . Это «подарок» от Microsoft Outlook, который когда пользователь выбирает тип письма RTF, не заморачиваясь завертывает в файл winmail.dat и письмо, и вложения и с письмом помимо заголовков отправляет только это вложение. А люди — которые не пользуются Outlook — по мнению Microsoft — это ваши проблемы 😉

Решение — использование консольной утилиты tnef. Например:

tnef -f /usr/local/www/apache24/ssl/data/pays/1/rpost/winmail.dat -C /usr/local/www/apache24/ssl/data/pays/1/rpost

 

Полезные функции для работы с IP адресами

Собрал в кучку полезные функции для работы с IP адресами, которые наиболее часто использую.

/**
 * Конвертируем ip/mask в диапазон IP
 * 127.0.0.1/24 -> массив [0] 127.0.0.1 [1] 127.0.255.255
 * @param type $net
 * @return type
 */
function cidrconv($net) {
    $start = strtok($net,"/");
    $n = 3 - substr_count($net, ".");
    if ($n > 0)
    {
        for ($i = $n;$i > 0; $i--)
            $start .= ".0";
    }
    $bits1 = str_pad(decbin(ip2long($start)), 32, "0", STR_PAD_LEFT);
    $net = (1 << (32 - substr(strstr($net, "/"), 1))) - 1;
    $bits2 = str_pad(decbin($net), 32, "0", STR_PAD_LEFT);
    $final = "";
    for ($i = 0; $i < 32; $i++)
    {
        if ($bits1[$i] == $bits2[$i]) $final .= $bits1[$i];
        if ($bits1[$i] == 1 and $bits2[$i] == 0) $final .= $bits1[$i];
        if ($bits1[$i] == 0 and $bits2[$i] == 1) $final .= $bits2[$i];
    }
    return array($start, long2ip(bindec($final)));
}
/**
 * Возвращает маску из IP вида 255.255.255.0 -> 24
 * @param type $ip
 * @return type
 */
function ip2mask($ip){
    $res=false;
    $intip=ip2long($ip);    
    if ($intip>0){
	$binstr=decbin($intip);	
	$res=  strpos($binstr,"0");		
    };
    return $res;
};

/**
 * Попадает ли ip в заданный диапазон 
 * true - да, false - нет
 * Например: (10.0.1.3,10.0.0.0/8) -> true
 * @param type $ip
 * @param type $mask
 */
function ip_in_range($ip,$mask){
  $res=false;
  $ipd=cidrconv($mask);     
  $ip=ip2long($ip);  
  $start=ip2long($ipd[0]);  
  $end=ip2long($ipd[1]);  
  if (($ip>=$start) and ($ip<=$end)){$res=true;};
  return $res;
};

/**
 * Возвращает true если IP  белый, false если серый
 * @param type $ip
 */
function WhiteIP($ip){
    $res=true;
    if (ip_in_range($ip,"10.0.0.0/8")==true){$res=false;};
    if (ip_in_range($ip,"172.16.0.0/12")==true){$res=false;};
    if (ip_in_range($ip,"192.168.0.0/16")==true){$res=false;};
    return $res;
};

Пример использования:

var_dump(cidrconv("10.0.0.0/8"));
var_dump(ip2mask("255.255.255.0"));
var_dump(ip_in_range("10.20.30.40","10.0.0.0/8"));
var_dump(WhiteIP("172.16.40.11"));
var_dump(WhiteIP("176.192.40.11"));

Результат:

array(2) {
  [0]=>
  string(8) "10.0.0.0"
  [1]=>
  string(14) "10.255.255.255"
}
int(24)
bool(true)
bool(false)
bool(true)

 

Простой способ сохранить файл по нажатию кнопки на странице (HTML)

Задача: по нажатию кнопки на странице, чтоб вызывался диалог сохранения файла и собственно сохранялся произвольный файл с сервера.

Решение:

В коде html страницы упоминаем скрытую форму:

<form method="post" action="inc/csvExport.php">
	<input type="hidden" name="csvBuffer" id="csvBuffer" value="" />
</form>

Добавляем туда же обработчик нажатия вида:

    $("#viewwork").click(function(){       
            document.forms[0].method='POST';
            document.forms[0].action=save_file.php; 
            document.forms[0].target='_self';
            document.forms[0].submit();  	    	    
       return false;
    });

Ну код на сервере для:

save_file.php:

<?php

// Данный код создан и распространяется по лицензии GPL v3
// Изначальный автор данного кода - Грибов Павел
// http://грибовы.рф

$ex= "1;2;3;4;5;6;7";
 header("Content-type: application/msexcel");
    header("Accept-Ranges: bytes");
    header("Content-Length: " . strlen($ex));
    header("Content-Disposition: attachment; filename=rep_by_addr.csv");

?>

csvExport.php:

<?php

// Данный код создан и распространяется по лицензии GPL v3
// Изначальный автор данного кода - Грибов Павел
// http://грибовы.рф

header('Content-type: application/vnd.ms-excel');
if (isset($_GET["csv"])==true){
    header("Content-Disposition: attachment; filename=file.csv");
} else {
    header("Content-Disposition: attachment; filename=file.xls");
};
header("Pragma: no-cache");

$buffer = $_POST['csvBuffer'];

try{
    echo $buffer;
}catch(Exception $e){

}
?>