Вход Регистрация
Файл: concrete5.7.5.6/concrete/vendor/zendframework/zend-http/src/Headers.php
Строк: 472
<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/zf2 for the canonical source repository
 * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace ZendHttp;

use 
ArrayIterator;
use 
Countable;
use 
Iterator;
use 
Traversable;
use 
ZendLoaderPluginClassLocator;

/**
 * Basic HTTP headers collection functionality
 * Handles aggregation of headers
 *
 * @see        http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
 */
class Headers implements CountableIterator
{
    
/**
     * @var PluginClassLoader
     */
    
protected $pluginClassLoader null;

    
/**
     * @var array key names for $headers array
     */
    
protected $headersKeys = array();

    
/**
     * @var array Array of header array information or Header instances
     */
    
protected $headers = array();

    
/**
     * Populates headers from string representation
     *
     * Parses a string for headers, and aggregates them, in order, in the
     * current instance, primarily as strings until they are needed (they
     * will be lazy loaded)
     *
     * @param  string $string
     * @return Headers
     * @throws ExceptionRuntimeException
     */
    
public static function fromString($string)
    {
        
$headers = new static();
        
$current = array();

        
// iterate the header lines, some might be continuations
        
foreach (explode("rn"$string) as $line) {

            
// check if a header name is present
            
if (preg_match('/^(?P<name>[^()><@,;:"\/[]?=}{ t]+):.*$/'$line$matches)) {
                if (
$current) {
                    
// a header name was present, then store the current complete line
                    
$headers->headersKeys[] = static::createKey($current['name']);
                    
$headers->headers[]     = $current;
                }
                
$current = array(
                    
'name' => $matches['name'],
                    
'line' => trim($line)
                );
            } elseif (
preg_match('/^(?P<ws>s+).*$/'$line$matches)) {
                
// continuation: append to current line
                
$current['line'] .= "rn" $matches['ws'] . trim($line);
            } elseif (
preg_match('/^s*$/'$line)) {
                
// empty line indicates end of headers
                
break;
            } else {
                
// Line does not match header format!
                
throw new ExceptionRuntimeException(sprintf(
                    
'Line "%s" does not match header format!',
                    
$line
                
));
            }
        }
        if (
$current) {
            
$headers->headersKeys[] = static::createKey($current['name']);
            
$headers->headers[]     = $current;
        }
        return 
$headers;
    }

    
/**
     * Set an alternate implementation for the PluginClassLoader
     *
     * @param ZendLoaderPluginClassLocator $pluginClassLoader
     * @return Headers
     */
    
public function setPluginClassLoader(PluginClassLocator $pluginClassLoader)
    {
        
$this->pluginClassLoader $pluginClassLoader;
        return 
$this;
    }

    
/**
     * Return an instance of a PluginClassLocator, lazyload and inject map if necessary
     *
     * @return PluginClassLocator
     */
    
public function getPluginClassLoader()
    {
        if (
$this->pluginClassLoader === null) {
            
$this->pluginClassLoader = new HeaderLoader();
        }
        return 
$this->pluginClassLoader;
    }

    
/**
     * Add many headers at once
     *
     * Expects an array (or Traversable object) of type/value pairs.
     *
     * @param  array|Traversable $headers
     * @return Headers
     * @throws ExceptionInvalidArgumentException
     */
    
public function addHeaders($headers)
    {
        if (!
is_array($headers) && !$headers instanceof Traversable) {
            throw new 
ExceptionInvalidArgumentException(sprintf(
                
'Expected array or Traversable; received "%s"',
                (
is_object($headers) ? get_class($headers) : gettype($headers))
            ));
        }

        foreach (
$headers as $name => $value) {
            if (
is_int($name)) {
                if (
is_string($value)) {
                    
$this->addHeaderLine($value);
                } elseif (
is_array($value) && count($value) == 1) {
                    
$this->addHeaderLine(key($value), current($value));
                } elseif (
is_array($value) && count($value) == 2) {
                    
$this->addHeaderLine($value[0], $value[1]);
                } elseif (
$value instanceof HeaderHeaderInterface) {
                    
$this->addHeader($value);
                }
            } elseif (
is_string($name)) {
                
$this->addHeaderLine($name$value);
            }

        }

        return 
$this;
    }

    
/**
     * Add a raw header line, either in name => value, or as a single string 'name: value'
     *
     * This method allows for lazy-loading in that the parsing and instantiation of Header object
     * will be delayed until they are retrieved by either get() or current()
     *
     * @throws ExceptionInvalidArgumentException
     * @param string $headerFieldNameOrLine
     * @param string $fieldValue optional
     * @return Headers
     */
    
public function addHeaderLine($headerFieldNameOrLine$fieldValue null)
    {
        
$matches null;
        if (
preg_match('/^(?P<name>[^()><@,;:"\/[]?=}{ t]+):.*$/'$headerFieldNameOrLine$matches)
            && 
$fieldValue === null) {
            
// is a header
            
$headerName $matches['name'];
            
$headerKey  = static::createKey($matches['name']);
            
$line $headerFieldNameOrLine;
        } elseif (
$fieldValue === null) {
            throw new 
ExceptionInvalidArgumentException('A field name was provided without a field value');
        } else {
            
$headerName $headerFieldNameOrLine;
            
$headerKey  = static::createKey($headerFieldNameOrLine);
            if (
is_array($fieldValue)) {
                
$fieldValue implode(', '$fieldValue);
            }
            
$line $headerFieldNameOrLine ': ' $fieldValue;
        }

        
$this->headersKeys[] = $headerKey;
        
$this->headers[]     = array('name' => $headerName'line' => $line);

        return 
$this;
    }

    
/**
     * Add a Header to this container, for raw values @see addHeaderLine() and addHeaders()
     *
     * @param  HeaderHeaderInterface $header
     * @return Headers
     */
    
public function addHeader(HeaderHeaderInterface $header)
    {
        
$this->headersKeys[] = static::createKey($header->getFieldName());
        
$this->headers[]     = $header;

        return 
$this;
    }

    
/**
     * Remove a Header from the container
     *
     * @param HeaderHeaderInterface $header
     * @return bool
     */
    
public function removeHeader(HeaderHeaderInterface $header)
    {
        
$index array_search($header$this->headerstrue);
        if (
$index !== false) {
            unset(
$this->headersKeys[$index]);
            unset(
$this->headers[$index]);

            return 
true;
        }
        return 
false;
    }

    
/**
     * Clear all headers
     *
     * Removes all headers from queue
     *
     * @return Headers
     */
    
public function clearHeaders()
    {
        
$this->headers $this->headersKeys = array();
        return 
$this;
    }

    
/**
     * Get all headers of a certain name/type
     *
     * @param  string $name
     * @return bool|HeaderHeaderInterface|ArrayIterator
     */
    
public function get($name)
    {
        
$key = static::createKey($name);
        if (!
in_array($key$this->headersKeys)) {
            return 
false;
        }

        
$class = ($this->getPluginClassLoader()->load($key)) ?: 'ZendHttpHeaderGenericHeader';

        if (
in_array('ZendHttpHeaderMultipleHeaderInterface'class_implements($classtrue))) {
            
$headers = array();
            foreach (
array_keys($this->headersKeys$key) as $index) {
                if (
is_array($this->headers[$index])) {
                    
$this->lazyLoadHeader($index);
                }
            }
            foreach (
array_keys($this->headersKeys$key) as $index) {
                
$headers[] = $this->headers[$index];
            }
            return new 
ArrayIterator($headers);
        }

        
$index array_search($key$this->headersKeys);
        if (
$index === false) {
            return 
false;
        }

        if (
is_array($this->headers[$index])) {
            return 
$this->lazyLoadHeader($index);
        }
        return 
$this->headers[$index];
    }

    
/**
     * Test for existence of a type of header
     *
     * @param  string $name
     * @return bool
     */
    
public function has($name)
    {
        return (
in_array(static::createKey($name), $this->headersKeys));
    }

    
/**
     * Advance the pointer for this object as an iterator
     *
     * @return void
     */
    
public function next()
    {
        
next($this->headers);
    }

    
/**
     * Return the current key for this object as an iterator
     *
     * @return mixed
     */
    
public function key()
    {
        return (
key($this->headers));
    }

    
/**
     * Is this iterator still valid?
     *
     * @return bool
     */
    
public function valid()
    {
        return (
current($this->headers) !== false);
    }

    
/**
     * Reset the internal pointer for this object as an iterator
     *
     * @return void
     */
    
public function rewind()
    {
        
reset($this->headers);
    }

    
/**
     * Return the current value for this iterator, lazy loading it if need be
     *
     * @return array|HeaderHeaderInterface
     */
    
public function current()
    {
        
$current current($this->headers);
        if (
is_array($current)) {
            
$current $this->lazyLoadHeader(key($this->headers));
        }
        return 
$current;
    }

    
/**
     * Return the number of headers in this contain, if all headers have not been parsed, actual count could
     * increase if MultipleHeader objects exist in the Request/Response.  If you need an exact count, iterate
     *
     * @return int count of currently known headers
     */
    
public function count()
    {
        return 
count($this->headers);
    }

    
/**
     * Render all headers at once
     *
     * This method handles the normal iteration of headers; it is up to the
     * concrete classes to prepend with the appropriate status/request line.
     *
     * @return string
     */
    
public function toString()
    {
        
$headers '';
        foreach (
$this->toArray() as $fieldName => $fieldValue) {
            if (
is_array($fieldValue)) {
                
// Handle multi-value headers
                
foreach ($fieldValue as $value) {
                    
$headers .= $fieldName ': ' $value "rn";
                }
                continue;
            }
            
// Handle single-value headers
            
$headers .= $fieldName ': ' $fieldValue "rn";
        }
        return 
$headers;
    }

    
/**
     * Return the headers container as an array
     *
     * @todo determine how to produce single line headers, if they are supported
     * @return array
     */
    
public function toArray()
    {
        
$headers = array();
        
/* @var $header HeaderHeaderInterface */
        
foreach ($this->headers as $header) {
            if (
$header instanceof HeaderMultipleHeaderInterface) {
                
$name $header->getFieldName();
                if (!isset(
$headers[$name])) {
                    
$headers[$name] = array();
                }
                
$headers[$name][] = $header->getFieldValue();
            } elseif (
$header instanceof HeaderHeaderInterface) {
                
$headers[$header->getFieldName()] = $header->getFieldValue();
            } else {
                
$matches null;
                
preg_match('/^(?P<name>[^()><@,;:"\/[]?=}{ t]+):s*(?P<value>.*)$/'$header['line'], $matches);
                if (
$matches) {
                    
$headers[$matches['name']] = $matches['value'];
                }
            }
        }
        return 
$headers;
    }

    
/**
     * By calling this, it will force parsing and loading of all headers, after this count() will be accurate
     *
     * @return bool
     */
    
public function forceLoading()
    {
        foreach (
$this as $item) {
            
// $item should now be loaded
        
}
        return 
true;
    }

    
/**
     * @param $index
     * @return mixed|void
     */
    
protected function lazyLoadHeader($index)
    {
        
$current $this->headers[$index];

        
$key $this->headersKeys[$index];
        
/* @var $class HeaderHeaderInterface */
        
$class = ($this->getPluginClassLoader()->load($key)) ?: 'ZendHttpHeaderGenericHeader';

        
$headers $class::fromString($current['line']);
        if (
is_array($headers)) {
            
$this->headers[$index] = $current array_shift($headers);
            foreach (
$headers as $header) {
                
$this->headersKeys[] = $key;
                
$this->headers[]     = $header;
            }
            return 
$current;
        }

        
$this->headers[$index] = $current $headers;
        return 
$current;
    }

    
/**
     * Create array key from header name
     *
     * @param string $name
     * @return string
     */
    
protected static function createKey($name)
    {
        return 
str_replace(array('-''_'' ''.'), ''strtolower($name));
    }
}
Онлайн: 2
Реклама