Skip to content

Instantly share code, notes, and snippets.

@hakre
Created November 2, 2013 22:55
Show Gist options
  • Save hakre/f13e1d633301bf5f221c to your computer and use it in GitHub Desktop.
Save hakre/f13e1d633301bf5f221c to your computer and use it in GitHub Desktop.
<?php
/**
* Create zip from inline binary attachment to multi-part message
*
* @link http://stackoverflow.com/a/19746863/367456
*/
/**
* Class HttpFiledValue
*
* Hands On Parameter Parsing and Extraction via http_parse_params()
*/
class HttpFieldValue implements ArrayAccess
{
private $value;
public function __construct($value)
{
$this->value = $value;
}
public function getParameterByName($name)
{
$params = http_parse_params($this);
foreach ($params->params as $index => $param) {
if (!is_array($param)) {
if ($name === NULL) {
return $param;
}
continue;
}
foreach ($param as $paramName => $value) {
if ($name === $paramName) {
return $value;
}
}
}
}
public function __toString()
{
return $this->value;
}
public function offsetExists($offset)
{
return NULL !== $this->getParameterByName($offset);
}
public function offsetGet($offset)
{
return $this->getParameterByName($offset);
}
public function offsetSet($offset, $value)
{
throw new BadMethodCallException('Read only.');
}
public function offsetUnset($offset)
{
throw new BadMethodCallException('Read only.');
}
}
/**
* Class MultipartRelatedHttpMessage
*/
class MultipartHttpMessage extends HttpMessage
{
/**
* @param null $message
* @param null $class_name
* @return MultipartHttpMessage
*/
public static function fromString($message = NULL, $class_name = NULL)
{
if (NULL === $class_name) {
$class_name = __CLASS__;
}
return parent::fromString($message, $class_name);
}
/**
* @return array|HttpMessage[]
* @throws UnexpectedValueException
*/
public function getParts()
{
$boundary = $this->getBoundary();
if (!$boundary) {
return [];
}
$needle = "--$boundary";
$needleLen = strlen($needle);
$counter = 0;
$offset = 0;
$parts = [];
$foundLast = FALSE;
while (false !== $pos = strpos($this->body, $needle, $offset)) {
$nextTwo = substr($this->body, $pos + $needleLen, 2);
if ($nextTwo === "--") {
$message = substr($this->body, $offset, $pos - $offset);
$parts[] = self::fromString("HTTP/1.1 206 Partial Content\r\n$message");
$foundLast = TRUE;
$counter++;
break;
}
if ($nextTwo === "\r\n") {
if (!$counter) {
} else {
$message = substr($this->body, $offset, $pos - $offset);
$parts[] = self::fromString("HTTP/1.1 206 Partial Content\r\n$message");
}
$offset = $pos + $needleLen + 2;
$counter++;
continue;
}
throw new UnexpectedValueException($nextTwo);
}
// add last one on good luck if it didn't found the last-marker so far
if (!$foundLast) {
$message = substr($this->body, $offset);
$parts[] = self::fromString("HTTP/1.1 206 Partial Content\r\n$message");
}
return $parts;
}
/**
* @param string $header
* @return HttpFieldValue|string
*/
public function getHeader($header)
{
return new HttpFieldValue(parent::getHeader($header));
}
public function getHeaders()
{
$headers = parent::getHeaders(); #
foreach ($headers as &$header) {
$header = new HttpFieldValue("$header");
}
return $headers;
}
public function getBoundary()
{
return $this->getHeader('content-type')['boundary'];
}
}
$url = 'http://developer.ebay.com/DevZone/file-transfer/CallRef/Samples/downloadFile_basic_out_xml.txt';
$raw = file_get_contents('downloadFile_basic_out_xml.txt');
$message = MultipartHttpMessage::fromString($raw);
echo 'Boundary: ', $message->getBoundary(), "\n";
foreach ($message->getParts() as $index => $part) {
printf("Part #%d:\n", $index);
foreach ($part->getHeaders() as $name => $value) {
printf(" %s: %s (%s)\n", $name, $value[NULL], $value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment