是否可以使用PHP和SOAP上传文件?
以下是使用的PHP代码:
$post = "a.txt";
$fp = fopen($post, "r");
$client = new SoapClient("http://api.4shared.com/servlet/services/DesktopApp?wsdl");
$id = $client->createUploadSessionKey("user","pass",-1);
$new_id = $client->uploadStartFile("user","pass",-1, "name", 500*1024);
$dcId = $client->getNewFileDataCenter("user","pass");
$sessKey = $client->createUploadSessionKey("user","pass", -1);
$upload = $client->getUploadFormUrl($dcId, $sessKey);
$res = $client->uploadFinishFile("user","pass", $new_id, $fp);
答案 0 :(得分:3)
是的,这是可能的。
到目前为止你尝试了什么?你在使用肥皂库还是自己动手?您是否在使文件传输工作时遇到任何问题?如果是这样,你试图做什么以及当你试图做什么时发生了什么?
编辑 - 检查HTTP流量可能是调试SOAP服务器的有用方法。此外,如果您使用的客户端与服务器不兼容,您可能必须找到另一个客户端或“自己动手”。我写了一个非常简单的客户端,它与MS框架生成的SOAP服务器配合得很好,它也可以很好地与Java服务器配合使用。
如果您最终需要创建自己的客户端,这可能有助于您入门:
<强> SimpleSoapClient.php 强>
用你自己的班级来扩展它。见下文......
<?php
/**
* Simple Soap Client
*
* Override this class to create a SOAP client.
*
* </pre>
**/
class SimpleSoapClient
{
protected $host;
protected $port;
protected $ns;
protected $url;
protected $act;
protected $debug;
protected function Post($method, $params)
{
return $this->_Post($method, $params);
}
protected function _Post($method, $params)
{
$namespaces = array();
foreach($params as $p)
{
if (isset($p->ns))
{
if ($namespaces[$p->ns])
$p->prefix = $namespaces[$p->ns];
else
$p->prefix = $namespaces[$p->ns] = 'ns'.count($namespaces);
}
}
if ($this->debug)
{
$cn = get_class($this);
echo "\n ====== Calling $cn::$method ====== \n\nParams: ";
print_r($params);
}
$host = $this->host;
$port = $this->port;
$ns = $this->ns;
$url = $this->url;
$act = $this->act;
$fp = fsockopen($host, $port, $errno, $errstr, 30);
if (!$fp)
die ("Oops: $errstr ($errno)<br />\n");
$xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"";
foreach($namespaces as $k=>$v)
$xml .= " xmlns:$v=\"$k\"";
$xml .= "><s:Body><$method xmlns=\"$ns\">";
foreach($params as $k=>$v)
$xml .= "<$k>$v</$k>";
$xml .= "</$method></s:Body></s:Envelope>";
$head = "POST $url HTTP/1.1\r\n"
. "Host: $host\r\n"
. "Content-Type: text/xml; charset=utf-8\r\n"
. "Content-Length: ".strlen($xml)."\r\n"
. "SOAPAction: \"$act$method\"\r\n"
. "Connection: Close\r\n\r\n";
if ($this->debug)
echo "\nRequest:\n\n$head$xml\n\n";
$s;
fwrite($fp, $head.$xml);
while (!feof($fp))
$s .= fgets($fp);
fclose($fp);
$s = trim(substr($s,strpos($s, "\r\n\r\n")));
if ($this->debug)
echo "Response:\n\n$s\n\n";
if (strstr($s,'<error_message>'))
die("\nError communicating with SOAP server.\n");
return($this->xml2assoc($s));
}
private function xml2assoc($xmlstring)
{
$xml;
if (is_object($xmlstring))
$xml = $xmlstring;
else
{
$xml = new XMLReader();
$xml->xml($xmlstring);
}
$tree = null;
while($xml->read())
{
switch ($xml->nodeType)
{
case XMLReader::END_ELEMENT: return $tree;
case XMLReader::ELEMENT:
$node = array('tag' => $xml->name,
'value' => $xml->isEmptyElement ? '' : $this->xml2assoc($xml));
if($xml->hasAttributes)
while($xml->moveToNextAttribute())
$node['attributes'][$xml->name] = $xml->value;
$tree[] = $node;
break;
case XMLReader::TEXT:
case XMLReader::CDATA:
$tree .= $xml->value;
}
}
// if ($this->debug) { echo "\nTREE:\n"; print_r($tree); }
return $tree;
}
public function DateFormat($date=null)
{
if (is_string($date))
$date = new DateTime($date);
return implode('-',array_slice(split('-',$date ? $date->format('c') : date('c')), 0, 3));
}
}
class SimpleSoapType
{
public $prefix;
public $type;
public $value;
public $ns;
function __construct($value)
{
$this->value = $value;
}
function __toString()
{
$t = (isset($this->prefix) ? $this->prefix.':' : '').$this->type;
$st = "<$t>"; $et = "</$t>";
if (is_array($this->value))
foreach ($this->value as $v)
$r .= $st.$v.$et;
else
$r = $st.$this->value.$et;
return $r;
}
protected function init() { throw('init is abstract'); }
}
?>
<强> ExampleSoapClient.php 强>
这实际上是一个生产 [1] soap客户端重命名为'Example'。
<?php
require_once 'SimpleSoapClient.php';
/**
* Example Soap Client
**/
class ExampleSoapClient extends SimpleSoapClient
{
function __construct()
{
$this->host = 'connect.example.com';
$this->port = 80;
$this->ns = "https://{$this->host}/connect";
$this->url = "http://{$this->host}/svc/connect.svc";
$this->act = "{$this->ns}/IConnect/";
$this->debug = true;
}
protected function Post ($method, $params) {
$params['apiKey'] = 'abcdef1234567890';
return $this->_Post($method, $params);
}
private function returnMulti($d)
{
foreach($d[0]['value'][0]['value'][0]['value'][0]['value'] as $v)
$r[] = $v['value'];
return $r;
}
private function returnSingle($d)
{
$r = $d[0]['value'][0]['value'][0]['value'][0]['value'];
return $r;
}
private function returnMultiPairs($d)
{
$d = $this->returnMulti($d);
foreach ($d as $v)
$r[$v[0]['value']] = $v[1]['value'];
return $r;
}
/**
* Get Property Categories
*
*
**/
public function GetPropertyCategories()
{
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $this->returnMulti($d);
}
/**
* Get Property IDs (undocumented)
*
* @param dateTime $lastMod Last modified date
*
**/
public function GetPropertyIDs($lastMod)
{
$lastMod = $this->DateFormat($lastMod);
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $this->returnMulti($d);
}
/**
* Get Property (undocumented)
*
* @param string $propertyID Property ID
*
**/
public function GetProperty($propertyID)
{
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $this->returnSingle($d);
}
/**
* Get Property IDs by Category
*
* @param int $propertyCategory Property category to get IDs for
*
**/
public function GetPropertyIDsByCategory($propertyCategory)
{
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $this->returnMulti($d);
}
/**
* Get Rates
*
* @param int $propertyID Property ID to get rates for
* @param string $rateType Currently unused
* @param int $los Length of stay - 1 (daily), 7 (weekly), or 30 (monthly)
* @param string $startDate Beginning of period to retrieve data for
* @param string $endDate End of period to retrieve data for
* @param string $currency Currently 'USD' only
*
**/
public function GetRates($propertyID, $rateType, $los, $startDate, $endDate, $currency)
{
$startDate = $this->DateFormat($startDate);
$endDate = $this->DateFormat($endDate);
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $this->returnMultiPairs($d);
}
/**
* Get Availability
*
* @param int $propertyID Property ID to get availability for
* @param string $rateType Currently unused
* @param string $startDate Beginning of period to retrieve data for
* @param string $endDate End of period to retrieve data for
*
**/
public function GetAvailability($propertyID, $rateType, $startDate, $endDate)
{
$startDate = $this->DateFormat($startDate);
$endDate = $this->DateFormat($endDate);
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $this->returnMultiPairs($d);
}
/**
* Set Rates
*
* @param int $propertyID Property ID to set rates for
* @param string $rateType Currently unused
* @param int $los Length of stay - 1 (daily), 7 (weekly), or 30 (monthly)
* @param array $effDates Effective dates
* @param array $rates Rate for each date
* @param string $currency Currently 'USD' only
*
**/
public function SetRates($propertyID, $rateType, $los, $effDates, $rates, $currency)
{
if (!get_class($effDates) == 'msDateTime')
$effDates = new msDateTime($effDates);
if (!get_class($rates) == 'msDecimal')
$rates = new msDecimal($rates);
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $d;
}
/**
* Set Availability
*
* @param int $propertyID Property ID to set availability for
* @param array $effDates Effective dates
* @param array $numAvailabile Available units for each date [sic]
*
**/
public function SetAvailability($propertyID, $effDates, $numAvailabile) // notice spelling: numAvailabile
{
if (!get_class($effDates) == 'msDateTime')
$effDates = new msDateTime($effDates);
if (!get_class($numAvailabile) == 'msInt')
$numAvailabile = new msInt($numAvailabile);
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $d;
}
/**
* Set Rates and Availability
*
* @param int $propertyID Property ID to set rates and availability for
* @param string $rateType Currently unused
* @param int $los Length of stay - 1 (daily), 7 (weekly), or 30 (monthly)
* @param array $effDates Effective dates
* @param array $rates Rate for each date
* @param string $currency Currently 'USD' only
* @param array $numAvailabile Available units for each date [sic]
*
**/
public function SetRatesAndAvailability($propertyID, $rateType, $los, $effDates, $rates, $currency, $numAvailabile)
{
if (!get_class($effDates) == 'msDateTime')
$effDates = new msDateTime($effDates);
if (!get_class($rates) == 'msDecimal')
$rates = new msDecimal($rates);
if (!get_class($numAvailabile) == 'msInt')
$numAvailabile = new msInt($numAvailabile);
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $d;
}
/**
* Get Booking
*
* @param int $bookingID ID of Booking to retrieve
*
**/
public function GetBooking($bookingID)
{
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $this->returnSingle($d);
}
/**
* Make Booking
*
* @param bcBooking $booking Booking object
* @param bool $infoOnly If true, simulate booking without actually booking anything
*
**/
public function MakeBooking($booking, $infoOnly)
{
$d = $this->Post(__FUNCTION__, get_defined_vars());
return $d; // $this->returnMulti($d);
}
}
/**
* base soap type - MS array serialization
**/
class msSoapType extends SimpleSoapType
{
function __construct($value)
{
$this->ns = 'http://schemas.microsoft.com/2003/10/Serialization/Arrays';
parent::__construct($value);
}
}
/**
* dateTime soap type - MS array serialization
**/
class msDateTime extends msSoapType
{
function __construct($value)
{
$this->type = 'dateTime';
parent::__construct($value);
if (is_array($value))
foreach ($value as $k=>$v)
$this->value[$k] = SimpleSoapClient::DateFormat($v);
else
$this->value = SimpleSoapClient::DateFormat($value);
}
}
/**
* decimal soap type - MS array serialization
**/
class msDecimal extends msSoapType
{
function __construct($value)
{
$this->type = 'decimal';
parent::__construct($value);
}
}
/**
* int soap type - MS array serialization
**/
class msInt extends msSoapType
{
function __construct($value)
{
$this->type = 'int';
parent::__construct($value);
}
}
?>
[1] - 可能看起来不是生产质量,但我在一些cron作业和PHP网站上使用它和其他人喜欢它并且它运行良好:)
答案 1 :(得分:1)
是的。
您可以传输您喜欢的任何数据。您只需要对二进制数据进行base64编码。它会将其转换为ascii字符。然后你可以像普通的字符串变量一样传输它。唯一需要注意的是服务器限制。
此致