Jump to content

Make multiple soap calls faster


myredrook

Recommended Posts

<?php

// Functions that allow reading of the DB interface of the PBX


// Default values

$dbadr = PBX_ADDRESS; //PBX Server Address

$dbport = PBX_PORT; // PBX Web Port


// Temporary variables for the PHP xml parser

$dbparse="";

$dbname="";

$dbvalue="";

$dbdebug=0;

$debug_tbl='';

$dbhandle=NULL;



function parseHeaders($headers, &$response_code = null, &$response_message = null){

$lines = explode("\r\n", $headers);

$return = array();


$response = array_shift($lines);


if (func_num_args() > 1) {

list($proto, $code, $message) = explode(' ', $response, 3);


$response_code = $code;


if (func_num_args() > 2) {

$response_message = $message;

}

}


foreach($lines as $header) {

if (trim($header) == '') continue;

list($name, $value) = explode(':', $header, 2);


$return[strtolower(trim($name))] = trim($value);

}


return $return;

}

function readResponseHeaders($sock, &$response_code, &$response_status){

$headers = '';

$read = 0;


while (true) {

$headers .= fread($sock, 1);

$read += 1;


if ($read >= 4 && $headers[$read - 1] == "\n" && substr($headers, -4) == "\r\n\r\n") {

break;

}

}


$headers = parseHeaders($headers, $resp, $msg);


$response_code = $resp;

$response_status = $msg;


return $headers;

}


function readResponseBody($sock, array $headers){

$contentLength = (isset($headers['content-length'])) ? $headers['content-length'] : -1;

$body = '';

if ($contentLength >= 0) {

$read = 0;

do {

$buf = fread($sock, $contentLength - $read);

$read += strlen($buf);

$body .= $buf;

} while ($read < $contentLength);


}

return $body;

}

// Helper function

function pbx_xml_envelope( $action, $req ) {

$r = '<?xml version="1.0" standalone="yes"?>';

$r .= "\r\n";

$r .= '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sns="http://www.pbxnsip.com/soap/pbx"><env:Body>';

$r .= "<sns:$action>";

$r .= $req;

$r .= "</sns:$action></env:Body></env:Envelope>";

return $r;

}


// Another helper function, Escape necessary XML characters

function pbx_xml_encode( $t ) {

$t = preg_replace('/\'/', "'", $t);

$t = preg_replace('/"/', "\"", $t);

// $t = preg_replace('/&/', "&", $t);

// $t = preg_replace("<", "<", $t);

// $t = preg_replace(">", ">", $t);

return $t;

}


// The main exection function, functions pbx_search(), pbx_get(), pbx_set() and pbx_index() use this function to carry out the SOAP command

function pbx_soap( $req ) {

global $dbadr, $dbport, $dbdebug, $debug_tbl, $dbhandle;

if ( $dbhandle == NULL ) {

$dbhandle = fsockopen($dbadr, $dbport, $errno, $errstr);

if (!$dbhandle) {

if($dbdebug) {

echo "<font color=red>$errstr ($errno)</font><br>\n";

}

return false;

}

}


$request = "POST /soap.xml HTTP/1.1\r\n";

$request .= "Content-Type: application/xml\r\n";

$request .= "Content-Length: " . strlen($req) . "\r\n";

$request .= "Connection: keep-alive\r\n\r\n";

$request .= $req;

fputs($dbhandle, $request);


$headers = readResponseHeaders($dbhandle, $resp, $msg);

$body = readResponseBody($dbhandle, $headers);


// socket is closed when the PHP process ends

// fclose($dbhandle);

return $body;

}


// XML parser helper function provided by the PHP Zend engine

function pbx_start_element( $parser, $name, $attrs ) {

global $dbparse, $dbdebug, $debug_tbl;


if($dbdebug) {

echo "Start $dbparse $name<br>";

}

if($dbparse == "" && strstr($name, ':') == ":ENVELOPE") {

$dbparse = "Envelope";

}

else if($dbparse == "Envelope" && strstr($name, ':') == ":BODY") {

$dbparse = "Body";

}

else if($dbparse == "Body" && strstr($name, ':') == ":DBGETRESPONSE") {

$dbparse = "DBGetResponse";

}

else if($dbparse == "Body" && strstr($name, ':') == ":DBSEARCHRESPONSE") {

$dbparse = "DBSearchResponse";

}

else if($dbparse == "DBGetResponse" && $name == "COLUMN") {

$dbparse = "Column";

}

else if($dbparse == "DBSearchResponse" && $name == "INDEX") {

$dbparse = "Index";

}

else if($dbparse == "Column" && $name == "NAME") {

$dbparse = "Name";

}

else if($dbparse == "Column" && $name == "VALUE") {

$dbparse = "Value";

$dbvalue = "";

}

else if($dbparse == "Search" && $name == "INDEX") {

$dbparse = "Index";

$dbvalue = "";

}

}


// another XML parser helper function provided by the PHP Zend engine

function pbx_end_element( $parser, $name ) {

global $dbparse, $dbname, $dbvalue, $dbresult, $dbdebug, $debug_tbl;


if($dbdebug) {

echo "End $dbparse $name<br>";

}

if($dbparse == "Envelope") {

$dbparse = "";

}

else if($dbparse == "Body") {

$dbparse = "Envelope";

}

else if($dbparse == "DBGetResponse") {

$dbparse = "Body";

}

else if($dbparse == "DBSearchResponse") {

$dbparse = "Body";

}

else if($dbparse == "Column") {

if($dbdebug) {

echo "<B>Set $dbname=$dbvalue</B><br>";

}

$dbresult[$dbname] = $dbvalue;

$dbparse = "DBGetResponse";

$dbname = null;

$dbvalue = null;

}

else if($dbparse == "Index") {

if($dbdebug) {

echo "Set $dbvalue<br>";

}

$dbresult[$dbvalue] = $dbvalue;

$dbparse = "DBSearchResponse";

$dbvalue = null;

}

else if($dbparse == "Name") {

$dbparse = "Column";

}

else if($dbparse == "Value") {

$dbparse = "Column";

}

else if($dbparse == "Index") {

$dbparse = "Search";

}

}


// Yet another XML parser helper function provided by the PHP Zend engine

function pbx_xml_data( $parser, $data ) {

global $dbparse, $dbname, $dbvalue, $dbdebug, $debug_tbl;


if($dbdebug) {

echo "Data $dbparse $data<br>";

}

if($dbparse == "Name") {

$dbname = $data;

}

else if($dbparse == "Value") {

$dbvalue .= htmlentities($data);

}

else if($dbparse == "Index") {

$dbvalue .= htmlentities($data);

}

}


/**

* Get a row of the table:

* This is one of the "getter" function that uses the pbx_soap() function.

* The "$columns" parameter is a basic array where the array value is the column name.

*/

function pbx_get( $table, $row, $columns, &$result ) {

global $dbresult, $dbparse, $dbname, $dbvalue;

$dbparse = "";

$dbname = "";

$dbvalue = "";


// Create a request:

$req = "<Table>$table</Table>";

$req .= "<Index>$row</Index>";

foreach($columns as $col) $req .= "<Column><Name>$col</Name></Column>";

$content = pbx_soap( pbx_xml_envelope("DBGet", $req) );


/**

* PHP will expect the following codes, however you may take advantage of the newest functionality provided by PHP. For more information and functionality, please visit http://us.php.net/soap

*/

$dbresult = array();

$xml_parser = xml_parser_create();

xml_set_element_handler($xml_parser, "pbx_start_element", "pbx_end_element");

xml_set_character_data_handler($xml_parser, "pbx_xml_data");

if( !xml_parse($xml_parser, $content, true) ) {

die(sprintf("Get XML error parsing %s: %s at line %d",

htmlspecialchars($content),

xml_error_string(xml_get_error_code($xml_parser)),

xml_get_current_line_number($xml_parser)));

}

xml_parser_free($xml_parser);

$result = $dbresult;

}



/**

* Set a row of the table:

* This is one of another "getter" function that uses the pbx_soap() function.

* The "$args" parameter is an ASSOCIATIVE array where the array key is is the name of the

* column and the array value is the column value. Some programming and/or web scripting

* language do not support this. If the case you can not use an associative array, ther solution

* is to use TWO (2) arrays with equal length, one being the column name and the other being the

* column value. This issue was encountered and solved when trying to migrate from PHP code to

* Visual Basic .NET platform. Other programming/scripting language may need extra procedures to * provide this functionality.

*/

function pbx_set($table, $row, $args ) {

global $dbresult, $dbparse, $dbname, $dbvalue;

$dbparse = "";

$dbname = "";

$dbvalue = "";


// Create a request:

$req = "<Table>$table</Table>";

$req .= "<Index>$row</Index>";

if(count($args) > 0) {

foreach($args as $col => $val) {

$req .= "<Column><Name>$col</Name><Value>" . pbx_xml_encode($val) . "</Value></Column>";

}

}

$content = pbx_soap(pbx_xml_envelope("DBSet", $req));

return $content;

}


// Search all matching entries of a table:

function pbx_search($table, $max, $skip, $back, $args, &$result) {

global $dbresult, $dbparse, $dbname, $dbvalue;

$dbparse = "";

$dbname = "";

$dbvalue = "";


// Create a request:

$req = "<Table>$table</Table>";

if($skip > 0) $req .= "<Skip>$skip</Skip>";

if($back) $req .= "<Back>true</Back>";

$req .= "<Max>$max</Max>";

if(count($args) > 0) {

foreach($args as $col => $val) {

$req .= "<Column><Name>$col</Name><Value>" . pbx_xml_encode($val) . "</Value></Column>";

}

}

$content = pbx_soap(pbx_xml_envelope("DBSearch", $req) );


$dbresult = array();

$xml_parser = xml_parser_create();

xml_set_element_handler($xml_parser, "pbx_start_element", "pbx_end_element");

xml_set_character_data_handler($xml_parser, "pbx_xml_data");

if( !xml_parse($xml_parser, $content, true)) {

if( xml_get_error_code($xml_parser) == XML_ERROR_NO_ELEMENTS ) {

global $dbadr, $dbport;

echo "<FONT COLOR=RED>Error: $dbadr:$dbport may be invalid, please check.</FONT><BR>";

}


die(sprintf("Search XML error parsing %s: %s at line %d",

htmlspecialchars($content),

xml_error_string(xml_get_error_code($xml_parser)),

xml_get_current_line_number($xml_parser)));

}

xml_parser_free($xml_parser);

$result = $dbresult;

}

?>

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...