├── lib ├── Type │ ├── TypeInterface.php │ ├── TypeBase.php │ ├── TypeBmp.php │ ├── TypeGif.php │ ├── TypePng.php │ ├── TypeJp2.php │ ├── TypeIco.php │ ├── TypePsd.php │ ├── TypeWbmp.php │ ├── TypeIff.php │ ├── TypeWebp.php │ ├── TypeTif.php │ └── TypeJpeg.php └── FastImageSize.php ├── LICENSE ├── composer.json └── composer.lock /lib/Type/TypeInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | interface TypeInterface 15 | { 16 | /** @var int 4-byte long size */ 17 | const LONG_SIZE = 4; 18 | 19 | /** @var int 2-byte short size */ 20 | const SHORT_SIZE = 2; 21 | 22 | /** 23 | * Get size of supplied image 24 | * 25 | * @param string $filename File name of image 26 | * 27 | * @return null 28 | */ 29 | public function getSize($filename); 30 | } 31 | -------------------------------------------------------------------------------- /lib/Type/TypeBase.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | use \FastImageSize\FastImageSize; 15 | 16 | abstract class TypeBase implements TypeInterface 17 | { 18 | /** @var FastImageSize */ 19 | protected $fastImageSize; 20 | 21 | /** 22 | * Base constructor for image types 23 | * 24 | * @param FastImageSize $fastImageSize 25 | */ 26 | public function __construct(FastImageSize $fastImageSize) 27 | { 28 | $this->fastImageSize = $fastImageSize; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Marc Alexander 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "marc1706/fast-image-size", 3 | "type": "library", 4 | "description": "fast-image-size is a PHP library that does almost everything PHP's getimagesize() does but without the large overhead of downloading the complete file.", 5 | "keywords": ["getimagesize", "fast", "PHP", "image", "size", "imagesize"], 6 | "homepage": "https://www.m-a-styles.de", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Marc Alexander", 11 | "email": "admin@m-a-styles.de", 12 | "homepage": "https://www.m-a-styles.de", 13 | "role": "Developer" 14 | } 15 | ], 16 | "require": { 17 | "php": ">=5.3.0", 18 | "ext-mbstring": "*" 19 | }, 20 | "require-dev": { 21 | "phpunit/phpunit": "^4.8" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "FastImageSize\\": "lib" 26 | } 27 | }, 28 | "autoload-dev": { 29 | "psr-4": { 30 | "FastImageSize\\tests\\": "tests" 31 | } 32 | }, 33 | "extra": { 34 | "branch-alias": { 35 | "dev-master": "1.1.x-dev" 36 | } 37 | }, 38 | "config": { 39 | "platform": { 40 | "php": "5.4.7" 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/Type/TypeBmp.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypeBmp extends TypeBase 15 | { 16 | /** @var int BMP header size needed for retrieving dimensions */ 17 | const BMP_HEADER_SIZE = 26; 18 | 19 | /** @var string BMP signature */ 20 | const BMP_SIGNATURE = "\x42\x4D"; 21 | 22 | /** qvar int BMP dimensions offset */ 23 | const BMP_DIMENSIONS_OFFSET = 18; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function getSize($filename) 29 | { 30 | $data = $this->fastImageSize->getImage($filename, 0, self::BMP_HEADER_SIZE); 31 | 32 | // Check if supplied file is a BMP file 33 | if (substr($data, 0, 2) !== self::BMP_SIGNATURE) 34 | { 35 | return; 36 | } 37 | 38 | $size = unpack('lwidth/lheight', substr($data, self::BMP_DIMENSIONS_OFFSET, 2 * self::LONG_SIZE)); 39 | 40 | $this->fastImageSize->setSize($size); 41 | $this->fastImageSize->setImageType(IMAGETYPE_BMP); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/Type/TypeGif.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypeGif extends TypeBase 15 | { 16 | /** @var string GIF87a header */ 17 | const GIF87A_HEADER = "\x47\x49\x46\x38\x37\x61"; 18 | 19 | /** @var string GIF89a header */ 20 | const GIF89A_HEADER = "\x47\x49\x46\x38\x39\x61"; 21 | 22 | /** @var int GIF header size */ 23 | const GIF_HEADER_SIZE = 6; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function getSize($filename) 29 | { 30 | // Get data needed for reading image dimensions as outlined by GIF87a 31 | // and GIF89a specifications 32 | $data = $this->fastImageSize->getImage($filename, 0, self::GIF_HEADER_SIZE + self::SHORT_SIZE * 2); 33 | 34 | $type = substr($data, 0, self::GIF_HEADER_SIZE); 35 | if ($type !== self::GIF87A_HEADER && $type !== self::GIF89A_HEADER) 36 | { 37 | return; 38 | } 39 | 40 | $size = unpack('vwidth/vheight', substr($data, self::GIF_HEADER_SIZE, self::SHORT_SIZE * 2)); 41 | 42 | $this->fastImageSize->setSize($size); 43 | $this->fastImageSize->setImageType(IMAGETYPE_GIF); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/Type/TypePng.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypePng extends TypeBase 15 | { 16 | /** @var string PNG header */ 17 | const PNG_HEADER = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"; 18 | 19 | /** @var int PNG IHDR offset */ 20 | const PNG_IHDR_OFFSET = 12; 21 | 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getSize($filename) 26 | { 27 | // Retrieve image data including the header, the IHDR tag, and the 28 | // following 2 chunks for the image width and height 29 | $data = $this->fastImageSize->getImage($filename, 0, self::PNG_IHDR_OFFSET + 3 * self::LONG_SIZE); 30 | 31 | // Check if header fits expected format specified by RFC 2083 32 | if (substr($data, 0, self::PNG_IHDR_OFFSET - self::LONG_SIZE) !== self::PNG_HEADER || substr($data, self::PNG_IHDR_OFFSET, self::LONG_SIZE) !== 'IHDR') 33 | { 34 | return; 35 | } 36 | 37 | $size = unpack('Nwidth/Nheight', substr($data, self::PNG_IHDR_OFFSET + self::LONG_SIZE, self::LONG_SIZE * 2)); 38 | 39 | $this->fastImageSize->setSize($size); 40 | $this->fastImageSize->setImageType(IMAGETYPE_PNG); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/Type/TypeJp2.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypeJp2 extends TypeBase 15 | { 16 | /** @var string JPEG 2000 signature */ 17 | const JPEG_2000_SIGNATURE = "\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A"; 18 | 19 | /** @var string JPEG 2000 SOC marker */ 20 | const JPEG_2000_SOC_MARKER = "\xFF\x4F"; 21 | 22 | /** @var string JPEG 2000 SIZ marker */ 23 | const JPEG_2000_SIZ_MARKER = "\xFF\x51"; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function getSize($filename) 29 | { 30 | $data = $this->fastImageSize->getImage($filename, 0, TypeJpeg::JPEG_MAX_HEADER_SIZE, false); 31 | 32 | // Check if file is jpeg 2000 33 | if (substr($data, 0, strlen(self::JPEG_2000_SIGNATURE)) !== self::JPEG_2000_SIGNATURE) 34 | { 35 | return; 36 | } 37 | 38 | // Get SOC position before starting to search for SIZ. 39 | // Make sure we do not get SIZ before SOC by cutting at SOC. 40 | $data = substr($data, strpos($data, self::JPEG_2000_SOC_MARKER)); 41 | 42 | // Remove SIZ and everything before 43 | $data = substr($data, strpos($data, self::JPEG_2000_SIZ_MARKER) + self::SHORT_SIZE); 44 | 45 | // Acquire size info from data 46 | $size = unpack('Nwidth/Nheight', substr($data, self::LONG_SIZE, self::LONG_SIZE * 2)); 47 | 48 | $this->fastImageSize->setSize($size); 49 | $this->fastImageSize->setImageType(IMAGETYPE_JPEG2000); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/Type/TypeIco.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypeIco extends TypeBase 15 | { 16 | /** @var string ICO reserved field */ 17 | const ICO_RESERVED = 0; 18 | 19 | /** @var int ICO type field */ 20 | const ICO_TYPE = 1; 21 | 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function getSize($filename) 26 | { 27 | // Retrieve image data for ICO header and header of first entry. 28 | // We assume the first entry to have the same size as the other ones. 29 | $data = $this->fastImageSize->getImage($filename, 0, 2 * self::LONG_SIZE); 30 | 31 | if ($data === false) 32 | { 33 | return; 34 | } 35 | 36 | // Check if header fits expected format 37 | if (!$this->isValidIco($data)) 38 | { 39 | return; 40 | } 41 | 42 | $size = unpack('Cwidth/Cheight', substr($data, self::LONG_SIZE + self::SHORT_SIZE, self::SHORT_SIZE)); 43 | 44 | $this->fastImageSize->setSize($size); 45 | $this->fastImageSize->setImageType(IMAGETYPE_ICO); 46 | } 47 | 48 | /** 49 | * Return whether image is a valid ICO file 50 | * 51 | * @param string $data Image data string 52 | * 53 | * @return bool True if file is a valid ICO file, false if not 54 | */ 55 | protected function isValidIco($data) 56 | { 57 | // Get header 58 | $header = unpack('vreserved/vtype/vimages', $data); 59 | 60 | return $header['reserved'] === self::ICO_RESERVED && $header['type'] === self::ICO_TYPE && $header['images'] > 0 && $header['images'] <= 255; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/Type/TypePsd.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypePsd extends TypeBase 15 | { 16 | /** @var string PSD signature */ 17 | const PSD_SIGNATURE = "8BPS"; 18 | 19 | /** @var int PSD header size */ 20 | const PSD_HEADER_SIZE = 22; 21 | 22 | /** @var int PSD dimensions info offset */ 23 | const PSD_DIMENSIONS_OFFSET = 14; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function getSize($filename) 29 | { 30 | $data = $this->fastImageSize->getImage($filename, 0, self::PSD_HEADER_SIZE); 31 | 32 | if ($data === false) 33 | { 34 | return; 35 | } 36 | 37 | // Offset for version info is length of header but version is only a 38 | // 16-bit unsigned value 39 | $version = unpack('n', substr($data, self::LONG_SIZE, 2)); 40 | 41 | // Check if supplied file is a PSD file 42 | if (!$this->validPsd($data, $version)) 43 | { 44 | return; 45 | } 46 | 47 | $size = unpack('Nheight/Nwidth', substr($data, self::PSD_DIMENSIONS_OFFSET, 2 * self::LONG_SIZE)); 48 | 49 | $this->fastImageSize->setSize($size); 50 | $this->fastImageSize->setImageType(IMAGETYPE_PSD); 51 | } 52 | 53 | /** 54 | * Return whether file is a valid PSD file 55 | * 56 | * @param string $data Image data string 57 | * @param array $version Version array 58 | * 59 | * @return bool True if image is a valid PSD file, false if not 60 | */ 61 | protected function validPsd($data, $version) 62 | { 63 | return substr($data, 0, self::LONG_SIZE) === self::PSD_SIGNATURE && $version[1] === 1; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/Type/TypeWbmp.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypeWbmp extends TypeBase 15 | { 16 | /** 17 | * {@inheritdoc} 18 | */ 19 | public function getSize($filename) 20 | { 21 | $data = $this->fastImageSize->getImage($filename, 0, self::LONG_SIZE); 22 | 23 | // Check if image is WBMP 24 | if ($data === false || !$this->validWBMP($data)) 25 | { 26 | return; 27 | } 28 | 29 | $size = unpack('Cwidth/Cheight', substr($data, self::SHORT_SIZE, self::SHORT_SIZE)); 30 | 31 | // Check if dimensions are valid. A file might be recognised as WBMP 32 | // rather easily (see extra check for JPEG2000). 33 | if (!$this->validDimensions($size)) 34 | { 35 | return; 36 | } 37 | 38 | $this->fastImageSize->setSize($size); 39 | $this->fastImageSize->setImageType(IMAGETYPE_WBMP); 40 | } 41 | 42 | /** 43 | * Return if supplied data might be part of a valid WBMP file 44 | * 45 | * @param bool|string $data 46 | * 47 | * @return bool True if data might be part of a valid WBMP file, else false 48 | */ 49 | protected function validWBMP($data) 50 | { 51 | return ord($data[0]) === 0 && ord($data[1]) === 0 && $data !== substr(TypeJp2::JPEG_2000_SIGNATURE, 0, self::LONG_SIZE); 52 | } 53 | 54 | /** 55 | * Return whether dimensions are valid 56 | * 57 | * @param array $size Size array 58 | * 59 | * @return bool True if dimensions are valid, false if not 60 | */ 61 | protected function validDimensions($size) 62 | { 63 | return $size['height'] > 0 && $size['width'] > 0; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/Type/TypeIff.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypeIff extends TypeBase 15 | { 16 | /** @var int IFF header size. Grab more than what should be needed to make 17 | * sure we have the necessary data */ 18 | const IFF_HEADER_SIZE = 32; 19 | 20 | /** @var string IFF header for Amiga type */ 21 | const IFF_HEADER_AMIGA = 'FORM'; 22 | 23 | /** @var string IFF header for Maya type */ 24 | const IFF_HEADER_MAYA = 'FOR4'; 25 | 26 | /** @var string IFF BTMHD for Amiga type */ 27 | const IFF_AMIGA_BTMHD = 'BMHD'; 28 | 29 | /** @var string IFF BTMHD for Maya type */ 30 | const IFF_MAYA_BTMHD = 'BHD'; 31 | 32 | /** @var string PHP pack format for unsigned short */ 33 | const PACK_UNSIGNED_SHORT = 'n'; 34 | 35 | /** @var string PHP pack format for unsigned long */ 36 | const PACK_UNSIGNED_LONG = 'N'; 37 | 38 | /** @var string BTMHD of current image */ 39 | protected $btmhd; 40 | 41 | /** @var int Size of current BTMHD */ 42 | protected $btmhdSize; 43 | 44 | /** @var string Current byte type */ 45 | protected $byteType; 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public function getSize($filename) 51 | { 52 | $data = $this->fastImageSize->getImage($filename, 0, self::IFF_HEADER_SIZE); 53 | 54 | $signature = $this->getIffSignature($data); 55 | 56 | // Check if image is IFF 57 | if ($signature === false) 58 | { 59 | return; 60 | } 61 | 62 | // Set type constraints 63 | $this->setTypeConstraints($signature); 64 | 65 | // Get size from data 66 | $btmhdPosition = strpos($data, $this->btmhd); 67 | $size = unpack("{$this->byteType}width/{$this->byteType}height", substr($data, $btmhdPosition + self::LONG_SIZE + strlen($this->btmhd), $this->btmhdSize)); 68 | 69 | $this->fastImageSize->setSize($size); 70 | $this->fastImageSize->setImageType(IMAGETYPE_IFF); 71 | } 72 | 73 | /** 74 | * Get IFF signature from data string 75 | * 76 | * @param string|bool $data Image data string 77 | * 78 | * @return false|string Signature if file is a valid IFF file, false if not 79 | */ 80 | protected function getIffSignature($data) 81 | { 82 | $signature = substr($data, 0, self::LONG_SIZE); 83 | 84 | // Check if image is IFF 85 | if ($signature !== self::IFF_HEADER_AMIGA && $signature !== self::IFF_HEADER_MAYA) 86 | { 87 | return false; 88 | } 89 | else 90 | { 91 | return $signature; 92 | } 93 | } 94 | 95 | /** 96 | * Set type constraints for current image 97 | * 98 | * @param string $signature IFF signature of image 99 | */ 100 | protected function setTypeConstraints($signature) 101 | { 102 | // Amiga version of IFF 103 | if ($signature === 'FORM') 104 | { 105 | $this->btmhd = self::IFF_AMIGA_BTMHD; 106 | $this->btmhdSize = self::LONG_SIZE; 107 | $this->byteType = self::PACK_UNSIGNED_SHORT; 108 | } 109 | // Maya version 110 | else 111 | { 112 | $this->btmhd = self::IFF_MAYA_BTMHD; 113 | $this->btmhdSize = self::LONG_SIZE * 2; 114 | $this->byteType = self::PACK_UNSIGNED_LONG; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /lib/Type/TypeWebp.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | use \FastImageSize\FastImageSize; 15 | 16 | class TypeWebp extends TypeBase 17 | { 18 | /** @var string RIFF header */ 19 | const WEBP_RIFF_HEADER = "RIFF"; 20 | 21 | /** @var string Webp header */ 22 | const WEBP_HEADER = "WEBP"; 23 | 24 | /** @var string VP8 chunk header */ 25 | const VP8_HEADER = "VP8"; 26 | 27 | /** @var string Simple(lossy) webp format */ 28 | const WEBP_FORMAT_SIMPLE = ' '; 29 | 30 | /** @var string Lossless webp format */ 31 | const WEBP_FORMAT_LOSSLESS = 'L'; 32 | 33 | /** @var string Extended webp format */ 34 | const WEBP_FORMAT_EXTENDED = 'X'; 35 | 36 | /** @var int WEBP header size needed for retrieving image size */ 37 | const WEBP_HEADER_SIZE = 30; 38 | 39 | /** @var array Size info array */ 40 | protected $size; 41 | 42 | /** 43 | * Constructor for webp image type. Adds missing constant if necessary. 44 | * 45 | * @param FastImageSize $fastImageSize 46 | */ 47 | public function __construct(FastImageSize $fastImageSize) 48 | { 49 | parent::__construct($fastImageSize); 50 | 51 | if (!defined('IMAGETYPE_WEBP')) 52 | { 53 | define('IMAGETYPE_WEBP', 18); 54 | } 55 | } 56 | 57 | /** 58 | * {@inheritdoc} 59 | */ 60 | public function getSize($filename) 61 | { 62 | // Do not force length of header 63 | $data = $this->fastImageSize->getImage($filename, 0, self::WEBP_HEADER_SIZE); 64 | 65 | $this->size = array(); 66 | 67 | $webpFormat = substr($data, 15, 1); 68 | 69 | if (!$this->hasWebpHeader($data) || !$this->isValidFormat($webpFormat)) 70 | { 71 | return; 72 | } 73 | 74 | $data = substr($data, 16, 14); 75 | 76 | $this->getWebpSize($data, $webpFormat); 77 | 78 | $this->fastImageSize->setSize($this->size); 79 | $this->fastImageSize->setImageType(IMAGETYPE_WEBP); 80 | } 81 | 82 | /** 83 | * Check if $data has valid WebP header 84 | * 85 | * @param string $data Image data 86 | * 87 | * @return bool True if $data has valid WebP header, false if not 88 | */ 89 | protected function hasWebpHeader($data) 90 | { 91 | $riffSignature = substr($data, 0, self::LONG_SIZE); 92 | $webpSignature = substr($data, 8, self::LONG_SIZE); 93 | $vp8Signature = substr($data, 12, self::SHORT_SIZE + 1); 94 | 95 | return !empty($data) && $riffSignature === self::WEBP_RIFF_HEADER && 96 | $webpSignature === self::WEBP_HEADER && $vp8Signature === self::VP8_HEADER; 97 | } 98 | 99 | /** 100 | * Check if $format is a valid WebP format 101 | * 102 | * @param string $format Format string 103 | * @return bool True if format is valid WebP format, false if not 104 | */ 105 | protected function isValidFormat($format) 106 | { 107 | return in_array($format, array(self::WEBP_FORMAT_SIMPLE, self::WEBP_FORMAT_LOSSLESS, self::WEBP_FORMAT_EXTENDED)); 108 | } 109 | 110 | /** 111 | * Get webp size info depending on format type and set size array values 112 | * 113 | * @param string $data Data string 114 | * @param string $format Format string 115 | */ 116 | protected function getWebpSize($data, $format) 117 | { 118 | switch ($format) 119 | { 120 | case self::WEBP_FORMAT_SIMPLE: 121 | $this->size = unpack('vwidth/vheight', substr($data, 10, 4)); 122 | break; 123 | 124 | case self::WEBP_FORMAT_LOSSLESS: 125 | // Lossless uses 14-bit values so we'll have to use bitwise shifting 126 | $this->size = array( 127 | 'width' => ord($data[5]) + ((ord($data[6]) & 0x3F) << 8) + 1, 128 | 'height' => (ord($data[6]) >> 6) + (ord($data[7]) << 2) + ((ord($data[8]) & 0xF) << 10) + 1, 129 | ); 130 | break; 131 | 132 | case self::WEBP_FORMAT_EXTENDED: 133 | // Extended uses 24-bit values cause 14-bit for lossless wasn't weird enough 134 | $this->size = array( 135 | 'width' => ord($data[8]) + (ord($data[9]) << 8) + (ord($data[10]) << 16) + 1, 136 | 'height' => ord($data[11]) + (ord($data[12]) << 8) + (ord($data[13]) << 16) + 1, 137 | ); 138 | break; 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /lib/Type/TypeTif.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypeTif extends TypeBase 15 | { 16 | /** @var int TIF header size. The header might be larger but the dimensions 17 | * should be in the first 256 kiB bytes */ 18 | const TIF_HEADER_SIZE = 262144; 19 | 20 | /** @var int TIF tag for image height */ 21 | const TIF_TAG_IMAGE_HEIGHT = 257; 22 | 23 | /** @var int TIF tag for image width */ 24 | const TIF_TAG_IMAGE_WIDTH = 256; 25 | 26 | /** @var int TIF tag type for short */ 27 | const TIF_TAG_TYPE_SHORT = 3; 28 | 29 | /** @var int TIF IFD entry size */ 30 | const TIF_IFD_ENTRY_SIZE = 12; 31 | 32 | /** @var string TIF signature of intel type */ 33 | const TIF_SIGNATURE_INTEL = 'II'; 34 | 35 | /** @var string TIF signature of motorola type */ 36 | const TIF_SIGNATURE_MOTOROLA = 'MM'; 37 | 38 | /** @var array Size info array */ 39 | protected $size; 40 | 41 | /** @var string Bit type of long field */ 42 | public $typeLong; 43 | 44 | /** @var string Bit type of short field */ 45 | public $typeShort; 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public function getSize($filename) 51 | { 52 | // Do not force length of header 53 | $data = $this->fastImageSize->getImage($filename, 0, self::TIF_HEADER_SIZE, false); 54 | 55 | $this->size = array(); 56 | 57 | $signature = substr($data, 0, self::SHORT_SIZE); 58 | 59 | if (!in_array($signature, array(self::TIF_SIGNATURE_INTEL, self::TIF_SIGNATURE_MOTOROLA))) 60 | { 61 | return; 62 | } 63 | 64 | // Set byte type 65 | $this->setByteType($signature); 66 | 67 | // Get offset of IFD 68 | list(, $offset) = unpack($this->typeLong, substr($data, self::LONG_SIZE, self::LONG_SIZE)); 69 | 70 | // Get size of IFD 71 | $ifdSizeInfo = substr($data, $offset, self::SHORT_SIZE); 72 | if (empty($ifdSizeInfo)) 73 | { 74 | return; 75 | } 76 | list(, $sizeIfd) = unpack($this->typeShort, $ifdSizeInfo); 77 | 78 | // Skip 2 bytes that define the IFD size 79 | $offset += self::SHORT_SIZE; 80 | 81 | // Ensure size can't exceed data length 82 | $sizeIfd = min($sizeIfd, floor((strlen($data) - $offset) / self::TIF_IFD_ENTRY_SIZE)); 83 | 84 | // Filter through IFD 85 | for ($i = 0; $i < $sizeIfd; $i++) 86 | { 87 | // Get IFD tag 88 | $type = unpack($this->typeShort, substr($data, $offset, self::SHORT_SIZE)); 89 | 90 | // Get field type of tag 91 | $fieldType = unpack($this->typeShort . 'type', substr($data, $offset + self::SHORT_SIZE, self::SHORT_SIZE)); 92 | 93 | // Get IFD entry 94 | $ifdValue = substr($data, $offset + 2 * self::LONG_SIZE, self::LONG_SIZE); 95 | 96 | // Set size of field 97 | $this->setSizeInfo($type[1], $fieldType['type'], $ifdValue); 98 | 99 | $offset += self::TIF_IFD_ENTRY_SIZE; 100 | } 101 | 102 | $this->fastImageSize->setSize($this->size); 103 | } 104 | 105 | /** 106 | * Set byte type based on signature in header 107 | * 108 | * @param string $signature Header signature 109 | */ 110 | public function setByteType($signature) 111 | { 112 | if ($signature === self::TIF_SIGNATURE_INTEL) 113 | { 114 | $this->typeLong = 'V'; 115 | $this->typeShort = 'v'; 116 | $this->size['type'] = IMAGETYPE_TIFF_II; 117 | } 118 | else 119 | { 120 | $this->typeLong = 'N'; 121 | $this->typeShort = 'n'; 122 | $this->size['type'] = IMAGETYPE_TIFF_MM; 123 | } 124 | } 125 | 126 | /** 127 | * Set size info 128 | * 129 | * @param int $dimensionType Type of dimension. Either width or height 130 | * @param int $fieldLength Length of field. Either short or long 131 | * @param string $ifdValue String value of IFD field 132 | */ 133 | protected function setSizeInfo($dimensionType, $fieldLength, $ifdValue) 134 | { 135 | // Set size of field 136 | $fieldSize = $fieldLength === self::TIF_TAG_TYPE_SHORT ? $this->typeShort : $this->typeLong; 137 | 138 | // Get actual dimensions from IFD 139 | if ($dimensionType === self::TIF_TAG_IMAGE_HEIGHT) 140 | { 141 | $this->size = array_merge($this->size, unpack($fieldSize . 'height', $ifdValue)); 142 | } 143 | else if ($dimensionType === self::TIF_TAG_IMAGE_WIDTH) 144 | { 145 | $this->size = array_merge($this->size, unpack($fieldSize . 'width', $ifdValue)); 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /lib/Type/TypeJpeg.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize\Type; 13 | 14 | class TypeJpeg extends TypeBase 15 | { 16 | /** @var int JPEG max header size. Headers can be bigger, but we'll abort 17 | * going through the header after this */ 18 | const JPEG_MAX_HEADER_SIZE = 786432; // = 768 kiB 19 | 20 | /** @var string JPEG header */ 21 | const JPEG_HEADER = "\xFF\xD8"; 22 | 23 | /** @var string Start of frame marker */ 24 | const SOF_START_MARKER = "\xFF"; 25 | 26 | /** @var string End of image (EOI) marker */ 27 | const JPEG_EOI_MARKER = "\xD9"; 28 | 29 | /** @var array JPEG SOF markers */ 30 | protected $sofMarkers = array( 31 | "\xC0", 32 | "\xC1", 33 | "\xC2", 34 | "\xC3", 35 | "\xC5", 36 | "\xC6", 37 | "\xC7", 38 | "\xC9", 39 | "\xCA", 40 | "\xCB", 41 | "\xCD", 42 | "\xCE", 43 | "\xCF" 44 | ); 45 | 46 | /** @var string|bool JPEG data stream */ 47 | protected $data = ''; 48 | 49 | /** @var int Data length */ 50 | protected $dataLength = 0; 51 | 52 | /** 53 | * {@inheritdoc} 54 | */ 55 | public function getSize($filename) 56 | { 57 | // Do not force the data length 58 | $this->data = $this->fastImageSize->getImage($filename, 0, self::JPEG_MAX_HEADER_SIZE, false); 59 | 60 | // Check if file is jpeg 61 | if ($this->data === false || substr($this->data, 0, self::SHORT_SIZE) !== self::JPEG_HEADER) 62 | { 63 | return; 64 | } 65 | 66 | // Look through file for SOF marker 67 | $size = $this->getSizeInfo(); 68 | 69 | $this->fastImageSize->setSize($size); 70 | $this->fastImageSize->setImageType(IMAGETYPE_JPEG); 71 | } 72 | 73 | /** 74 | * Get size info from image data 75 | * 76 | * @return array An array with the image's size info or an empty array if 77 | * size info couldn't be found 78 | */ 79 | protected function getSizeInfo() 80 | { 81 | $size = array(); 82 | // since we check $i + 1 we need to stop one step earlier 83 | $this->dataLength = strlen($this->data) - 1; 84 | 85 | $sofStartRead = true; 86 | 87 | // Look through file for SOF marker 88 | for ($i = 2; $i < $this->dataLength; $i++) 89 | { 90 | $marker = $this->getNextMarker($i, $sofStartRead); 91 | 92 | if (in_array($marker, $this->sofMarkers)) 93 | { 94 | // Extract size info from SOF marker 95 | return $this->extractSizeInfo($i); 96 | } 97 | else 98 | { 99 | // Extract length only 100 | $markerLength = $this->extractMarkerLength($i); 101 | 102 | if ($markerLength < 2) 103 | { 104 | return $size; 105 | } 106 | 107 | $i += $markerLength - 1; 108 | continue; 109 | } 110 | } 111 | 112 | return $size; 113 | } 114 | 115 | /** 116 | * Extract marker length from data 117 | * 118 | * @param int $i Current index 119 | * @return int Length of current marker 120 | */ 121 | protected function extractMarkerLength($i) 122 | { 123 | // Extract length only 124 | list(, $unpacked) = unpack("H*", substr($this->data, $i, self::LONG_SIZE)); 125 | 126 | // Get width and height from unpacked size info 127 | $markerLength = hexdec(substr($unpacked, 0, 4)); 128 | 129 | return $markerLength; 130 | } 131 | 132 | /** 133 | * Extract size info from data 134 | * 135 | * @param int $i Current index 136 | * @return array Size info of current marker 137 | */ 138 | protected function extractSizeInfo($i) 139 | { 140 | // Extract size info from SOF marker 141 | list(, $unpacked) = unpack("H*", substr($this->data, $i - 1 + self::LONG_SIZE, self::LONG_SIZE)); 142 | 143 | // Get width and height from unpacked size info 144 | $size = array( 145 | 'width' => hexdec(substr($unpacked, 4, 4)), 146 | 'height' => hexdec(substr($unpacked, 0, 4)), 147 | ); 148 | 149 | return $size; 150 | } 151 | 152 | /** 153 | * Get next JPEG marker in file 154 | * 155 | * @param int $i Current index 156 | * @param bool $sofStartRead Flag whether SOF start padding was already read 157 | * 158 | * @return string Next JPEG marker in file 159 | */ 160 | protected function getNextMarker(&$i, &$sofStartRead) 161 | { 162 | $this->skipStartPadding($i, $sofStartRead); 163 | 164 | do { 165 | if ($i >= $this->dataLength) 166 | { 167 | return self::JPEG_EOI_MARKER; 168 | } 169 | $marker = $this->data[$i]; 170 | $i++; 171 | } while ($marker == self::SOF_START_MARKER); 172 | 173 | return $marker; 174 | } 175 | 176 | /** 177 | * Skip over any possible padding until we reach a byte without SOF start 178 | * marker. Extraneous bytes might need to require proper treating. 179 | * 180 | * @param int $i Current index 181 | * @param bool $sofStartRead Flag whether SOF start padding was already read 182 | */ 183 | protected function skipStartPadding(&$i, &$sofStartRead) 184 | { 185 | if (!$sofStartRead) 186 | { 187 | while ($this->data[$i] !== self::SOF_START_MARKER) 188 | { 189 | $i++; 190 | } 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /lib/FastImageSize.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace FastImageSize; 13 | 14 | class FastImageSize 15 | { 16 | /** @var array Size info that is returned */ 17 | protected $size = array(); 18 | 19 | /** @var string Data retrieved from remote */ 20 | protected $data = ''; 21 | 22 | /** @var array List of supported image types and associated image types */ 23 | protected $supportedTypes = array( 24 | 'png' => array('png'), 25 | 'gif' => array('gif'), 26 | 'jpeg' => array( 27 | 'jpeg', 28 | 'jpg', 29 | 'jpe', 30 | 'jif', 31 | 'jfif', 32 | 'jfi', 33 | ), 34 | 'jp2' => array( 35 | 'jp2', 36 | 'j2k', 37 | 'jpf', 38 | 'jpg2', 39 | 'jpx', 40 | 'jpm', 41 | ), 42 | 'psd' => array( 43 | 'psd', 44 | 'photoshop', 45 | ), 46 | 'bmp' => array('bmp'), 47 | 'tif' => array( 48 | 'tif', 49 | 'tiff', 50 | ), 51 | 'wbmp' => array( 52 | 'wbm', 53 | 'wbmp', 54 | 'vnd.wap.wbmp', 55 | ), 56 | 'iff' => array( 57 | 'iff', 58 | 'x-iff', 59 | ), 60 | 'ico' => array( 61 | 'ico', 62 | 'vnd.microsoft.icon', 63 | 'x-icon', 64 | 'icon', 65 | ), 66 | 'webp' => array( 67 | 'webp', 68 | ) 69 | ); 70 | 71 | /** @var array Class map that links image extensions/mime types to class */ 72 | protected $classMap; 73 | 74 | /** @var array An array containing the classes of supported image types */ 75 | protected $type; 76 | 77 | /** 78 | * Get image dimensions of supplied image 79 | * 80 | * @param string $file Path to image that should be checked 81 | * @param string $type Mimetype of image 82 | * @return array|bool Array with image dimensions if successful, false if not 83 | */ 84 | public function getImageSize($file, $type = '') 85 | { 86 | // Reset values 87 | $this->resetValues(); 88 | 89 | // Treat image type as unknown if extension or mime type is unknown 90 | if (!preg_match('/\.([a-z0-9]+)$/i', $file, $match) && empty($type)) 91 | { 92 | $this->getImagesizeUnknownType($file); 93 | } 94 | else 95 | { 96 | $extension = (empty($type) && isset($match[1])) ? $match[1] : preg_replace('/.+\/([a-z0-9-.]+)$/i', '$1', $type); 97 | 98 | $this->getImageSizeByExtension($file, $extension); 99 | } 100 | 101 | return sizeof($this->size) > 1 ? $this->size : false; 102 | } 103 | 104 | /** 105 | * Get dimensions of image if type is unknown 106 | * 107 | * @param string $filename Path to file 108 | */ 109 | protected function getImagesizeUnknownType($filename) 110 | { 111 | // Grab the maximum amount of bytes we might need 112 | $data = $this->getImage($filename, 0, Type\TypeJpeg::JPEG_MAX_HEADER_SIZE, false); 113 | 114 | if ($data !== false) 115 | { 116 | $this->loadAllTypes(); 117 | foreach ($this->type as $imageType) 118 | { 119 | $imageType->getSize($filename); 120 | 121 | if (sizeof($this->size) > 1) 122 | { 123 | break; 124 | } 125 | } 126 | } 127 | } 128 | 129 | /** 130 | * Get image size by file extension 131 | * 132 | * @param string $file Path to image that should be checked 133 | * @param string $extension Extension/type of image 134 | */ 135 | protected function getImageSizeByExtension($file, $extension) 136 | { 137 | $extension = strtolower($extension); 138 | $this->loadExtension($extension); 139 | if (isset($this->classMap[$extension])) 140 | { 141 | $this->classMap[$extension]->getSize($file); 142 | } 143 | } 144 | 145 | /** 146 | * Reset values to default 147 | */ 148 | protected function resetValues() 149 | { 150 | $this->size = array(); 151 | $this->data = ''; 152 | } 153 | 154 | /** 155 | * Set mime type based on supplied image 156 | * 157 | * @param int $type Type of image 158 | */ 159 | public function setImageType($type) 160 | { 161 | $this->size['type'] = $type; 162 | } 163 | 164 | /** 165 | * Set size info 166 | * 167 | * @param array $size Array containing size info for image 168 | */ 169 | public function setSize($size) 170 | { 171 | $this->size = $size; 172 | } 173 | 174 | /** 175 | * Get image from specified path/source 176 | * 177 | * @param string $filename Path to image 178 | * @param int $offset Offset at which reading of the image should start 179 | * @param int $length Maximum length that should be read 180 | * @param bool $forceLength True if the length needs to be the specified 181 | * length, false if not. Default: true 182 | * 183 | * @return false|string Image data or false if result was empty 184 | */ 185 | public function getImage($filename, $offset, $length, $forceLength = true) 186 | { 187 | if (empty($this->data)) 188 | { 189 | $this->data = @file_get_contents($filename, null, null, $offset, $length); 190 | } 191 | 192 | // Force length to expected one. Return false if data length 193 | // is smaller than expected length 194 | if ($forceLength === true) 195 | { 196 | return (strlen($this->data) < $length) ? false : substr($this->data, $offset, $length) ; 197 | } 198 | 199 | return empty($this->data) ? false : $this->data; 200 | } 201 | 202 | /** 203 | * Get return data 204 | * 205 | * @return array|bool Size array if dimensions could be found, false if not 206 | */ 207 | protected function getReturnData() 208 | { 209 | return sizeof($this->size) > 1 ? $this->size : false; 210 | } 211 | 212 | /** 213 | * Load all supported types 214 | */ 215 | protected function loadAllTypes() 216 | { 217 | foreach ($this->supportedTypes as $imageType => $extension) 218 | { 219 | $this->loadType($imageType); 220 | } 221 | } 222 | 223 | /** 224 | * Load an image type by extension 225 | * 226 | * @param string $extension Extension of image 227 | */ 228 | protected function loadExtension($extension) 229 | { 230 | if (isset($this->classMap[$extension])) 231 | { 232 | return; 233 | } 234 | foreach ($this->supportedTypes as $imageType => $extensions) 235 | { 236 | if (in_array($extension, $extensions, true)) 237 | { 238 | $this->loadType($imageType); 239 | } 240 | } 241 | } 242 | 243 | /** 244 | * Load an image type 245 | * 246 | * @param string $imageType Mimetype 247 | */ 248 | protected function loadType($imageType) 249 | { 250 | if (isset($this->type[$imageType])) 251 | { 252 | return; 253 | } 254 | 255 | $className = '\FastImageSize\Type\Type' . mb_convert_case(mb_strtolower($imageType), MB_CASE_TITLE); 256 | $this->type[$imageType] = new $className($this); 257 | 258 | // Create class map 259 | foreach ($this->supportedTypes[$imageType] as $ext) 260 | { 261 | /** @var Type\TypeInterface */ 262 | $this->classMap[$ext] = $this->type[$imageType]; 263 | } 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "ae991c268a76a435f29db1ee764914b2", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "doctrine/instantiator", 12 | "version": "1.0.5", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/doctrine/instantiator.git", 16 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 21 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": ">=5.3,<8.0-DEV" 26 | }, 27 | "require-dev": { 28 | "athletic/athletic": "~0.1.8", 29 | "ext-pdo": "*", 30 | "ext-phar": "*", 31 | "phpunit/phpunit": "~4.0", 32 | "squizlabs/php_codesniffer": "~2.0" 33 | }, 34 | "type": "library", 35 | "extra": { 36 | "branch-alias": { 37 | "dev-master": "1.0.x-dev" 38 | } 39 | }, 40 | "autoload": { 41 | "psr-4": { 42 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 43 | } 44 | }, 45 | "notification-url": "https://packagist.org/downloads/", 46 | "license": [ 47 | "MIT" 48 | ], 49 | "authors": [ 50 | { 51 | "name": "Marco Pivetta", 52 | "email": "ocramius@gmail.com", 53 | "homepage": "http://ocramius.github.com/" 54 | } 55 | ], 56 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 57 | "homepage": "https://github.com/doctrine/instantiator", 58 | "keywords": [ 59 | "constructor", 60 | "instantiate" 61 | ], 62 | "time": "2015-06-14T21:17:01+00:00" 63 | }, 64 | { 65 | "name": "phpdocumentor/reflection-docblock", 66 | "version": "2.0.5", 67 | "source": { 68 | "type": "git", 69 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 70 | "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" 71 | }, 72 | "dist": { 73 | "type": "zip", 74 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", 75 | "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", 76 | "shasum": "" 77 | }, 78 | "require": { 79 | "php": ">=5.3.3" 80 | }, 81 | "require-dev": { 82 | "phpunit/phpunit": "~4.0" 83 | }, 84 | "suggest": { 85 | "dflydev/markdown": "~1.0", 86 | "erusev/parsedown": "~1.0" 87 | }, 88 | "type": "library", 89 | "extra": { 90 | "branch-alias": { 91 | "dev-master": "2.0.x-dev" 92 | } 93 | }, 94 | "autoload": { 95 | "psr-0": { 96 | "phpDocumentor": [ 97 | "src/" 98 | ] 99 | } 100 | }, 101 | "notification-url": "https://packagist.org/downloads/", 102 | "license": [ 103 | "MIT" 104 | ], 105 | "authors": [ 106 | { 107 | "name": "Mike van Riel", 108 | "email": "mike.vanriel@naenius.com" 109 | } 110 | ], 111 | "time": "2016-01-25T08:17:30+00:00" 112 | }, 113 | { 114 | "name": "phpspec/prophecy", 115 | "version": "1.8.0", 116 | "source": { 117 | "type": "git", 118 | "url": "https://github.com/phpspec/prophecy.git", 119 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" 120 | }, 121 | "dist": { 122 | "type": "zip", 123 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", 124 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", 125 | "shasum": "" 126 | }, 127 | "require": { 128 | "doctrine/instantiator": "^1.0.2", 129 | "php": "^5.3|^7.0", 130 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", 131 | "sebastian/comparator": "^1.1|^2.0|^3.0", 132 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 133 | }, 134 | "require-dev": { 135 | "phpspec/phpspec": "^2.5|^3.2", 136 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" 137 | }, 138 | "type": "library", 139 | "extra": { 140 | "branch-alias": { 141 | "dev-master": "1.8.x-dev" 142 | } 143 | }, 144 | "autoload": { 145 | "psr-0": { 146 | "Prophecy\\": "src/" 147 | } 148 | }, 149 | "notification-url": "https://packagist.org/downloads/", 150 | "license": [ 151 | "MIT" 152 | ], 153 | "authors": [ 154 | { 155 | "name": "Konstantin Kudryashov", 156 | "email": "ever.zet@gmail.com", 157 | "homepage": "http://everzet.com" 158 | }, 159 | { 160 | "name": "Marcello Duarte", 161 | "email": "marcello.duarte@gmail.com" 162 | } 163 | ], 164 | "description": "Highly opinionated mocking framework for PHP 5.3+", 165 | "homepage": "https://github.com/phpspec/prophecy", 166 | "keywords": [ 167 | "Double", 168 | "Dummy", 169 | "fake", 170 | "mock", 171 | "spy", 172 | "stub" 173 | ], 174 | "time": "2018-08-05T17:53:17+00:00" 175 | }, 176 | { 177 | "name": "phpunit/php-code-coverage", 178 | "version": "2.2.4", 179 | "source": { 180 | "type": "git", 181 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 182 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" 183 | }, 184 | "dist": { 185 | "type": "zip", 186 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", 187 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", 188 | "shasum": "" 189 | }, 190 | "require": { 191 | "php": ">=5.3.3", 192 | "phpunit/php-file-iterator": "~1.3", 193 | "phpunit/php-text-template": "~1.2", 194 | "phpunit/php-token-stream": "~1.3", 195 | "sebastian/environment": "^1.3.2", 196 | "sebastian/version": "~1.0" 197 | }, 198 | "require-dev": { 199 | "ext-xdebug": ">=2.1.4", 200 | "phpunit/phpunit": "~4" 201 | }, 202 | "suggest": { 203 | "ext-dom": "*", 204 | "ext-xdebug": ">=2.2.1", 205 | "ext-xmlwriter": "*" 206 | }, 207 | "type": "library", 208 | "extra": { 209 | "branch-alias": { 210 | "dev-master": "2.2.x-dev" 211 | } 212 | }, 213 | "autoload": { 214 | "classmap": [ 215 | "src/" 216 | ] 217 | }, 218 | "notification-url": "https://packagist.org/downloads/", 219 | "license": [ 220 | "BSD-3-Clause" 221 | ], 222 | "authors": [ 223 | { 224 | "name": "Sebastian Bergmann", 225 | "email": "sb@sebastian-bergmann.de", 226 | "role": "lead" 227 | } 228 | ], 229 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 230 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 231 | "keywords": [ 232 | "coverage", 233 | "testing", 234 | "xunit" 235 | ], 236 | "time": "2015-10-06T15:47:00+00:00" 237 | }, 238 | { 239 | "name": "phpunit/php-file-iterator", 240 | "version": "1.4.5", 241 | "source": { 242 | "type": "git", 243 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 244 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" 245 | }, 246 | "dist": { 247 | "type": "zip", 248 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", 249 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", 250 | "shasum": "" 251 | }, 252 | "require": { 253 | "php": ">=5.3.3" 254 | }, 255 | "type": "library", 256 | "extra": { 257 | "branch-alias": { 258 | "dev-master": "1.4.x-dev" 259 | } 260 | }, 261 | "autoload": { 262 | "classmap": [ 263 | "src/" 264 | ] 265 | }, 266 | "notification-url": "https://packagist.org/downloads/", 267 | "license": [ 268 | "BSD-3-Clause" 269 | ], 270 | "authors": [ 271 | { 272 | "name": "Sebastian Bergmann", 273 | "email": "sb@sebastian-bergmann.de", 274 | "role": "lead" 275 | } 276 | ], 277 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 278 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 279 | "keywords": [ 280 | "filesystem", 281 | "iterator" 282 | ], 283 | "time": "2017-11-27T13:52:08+00:00" 284 | }, 285 | { 286 | "name": "phpunit/php-text-template", 287 | "version": "1.2.1", 288 | "source": { 289 | "type": "git", 290 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 291 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 292 | }, 293 | "dist": { 294 | "type": "zip", 295 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 296 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 297 | "shasum": "" 298 | }, 299 | "require": { 300 | "php": ">=5.3.3" 301 | }, 302 | "type": "library", 303 | "autoload": { 304 | "classmap": [ 305 | "src/" 306 | ] 307 | }, 308 | "notification-url": "https://packagist.org/downloads/", 309 | "license": [ 310 | "BSD-3-Clause" 311 | ], 312 | "authors": [ 313 | { 314 | "name": "Sebastian Bergmann", 315 | "email": "sebastian@phpunit.de", 316 | "role": "lead" 317 | } 318 | ], 319 | "description": "Simple template engine.", 320 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 321 | "keywords": [ 322 | "template" 323 | ], 324 | "time": "2015-06-21T13:50:34+00:00" 325 | }, 326 | { 327 | "name": "phpunit/php-timer", 328 | "version": "1.0.9", 329 | "source": { 330 | "type": "git", 331 | "url": "https://github.com/sebastianbergmann/php-timer.git", 332 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" 333 | }, 334 | "dist": { 335 | "type": "zip", 336 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 337 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 338 | "shasum": "" 339 | }, 340 | "require": { 341 | "php": "^5.3.3 || ^7.0" 342 | }, 343 | "require-dev": { 344 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 345 | }, 346 | "type": "library", 347 | "extra": { 348 | "branch-alias": { 349 | "dev-master": "1.0-dev" 350 | } 351 | }, 352 | "autoload": { 353 | "classmap": [ 354 | "src/" 355 | ] 356 | }, 357 | "notification-url": "https://packagist.org/downloads/", 358 | "license": [ 359 | "BSD-3-Clause" 360 | ], 361 | "authors": [ 362 | { 363 | "name": "Sebastian Bergmann", 364 | "email": "sb@sebastian-bergmann.de", 365 | "role": "lead" 366 | } 367 | ], 368 | "description": "Utility class for timing", 369 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 370 | "keywords": [ 371 | "timer" 372 | ], 373 | "time": "2017-02-26T11:10:40+00:00" 374 | }, 375 | { 376 | "name": "phpunit/php-token-stream", 377 | "version": "1.4.12", 378 | "source": { 379 | "type": "git", 380 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 381 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" 382 | }, 383 | "dist": { 384 | "type": "zip", 385 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", 386 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", 387 | "shasum": "" 388 | }, 389 | "require": { 390 | "ext-tokenizer": "*", 391 | "php": ">=5.3.3" 392 | }, 393 | "require-dev": { 394 | "phpunit/phpunit": "~4.2" 395 | }, 396 | "type": "library", 397 | "extra": { 398 | "branch-alias": { 399 | "dev-master": "1.4-dev" 400 | } 401 | }, 402 | "autoload": { 403 | "classmap": [ 404 | "src/" 405 | ] 406 | }, 407 | "notification-url": "https://packagist.org/downloads/", 408 | "license": [ 409 | "BSD-3-Clause" 410 | ], 411 | "authors": [ 412 | { 413 | "name": "Sebastian Bergmann", 414 | "email": "sebastian@phpunit.de" 415 | } 416 | ], 417 | "description": "Wrapper around PHP's tokenizer extension.", 418 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 419 | "keywords": [ 420 | "tokenizer" 421 | ], 422 | "time": "2017-12-04T08:55:13+00:00" 423 | }, 424 | { 425 | "name": "phpunit/phpunit", 426 | "version": "4.8.36", 427 | "source": { 428 | "type": "git", 429 | "url": "https://github.com/sebastianbergmann/phpunit.git", 430 | "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" 431 | }, 432 | "dist": { 433 | "type": "zip", 434 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", 435 | "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", 436 | "shasum": "" 437 | }, 438 | "require": { 439 | "ext-dom": "*", 440 | "ext-json": "*", 441 | "ext-pcre": "*", 442 | "ext-reflection": "*", 443 | "ext-spl": "*", 444 | "php": ">=5.3.3", 445 | "phpspec/prophecy": "^1.3.1", 446 | "phpunit/php-code-coverage": "~2.1", 447 | "phpunit/php-file-iterator": "~1.4", 448 | "phpunit/php-text-template": "~1.2", 449 | "phpunit/php-timer": "^1.0.6", 450 | "phpunit/phpunit-mock-objects": "~2.3", 451 | "sebastian/comparator": "~1.2.2", 452 | "sebastian/diff": "~1.2", 453 | "sebastian/environment": "~1.3", 454 | "sebastian/exporter": "~1.2", 455 | "sebastian/global-state": "~1.0", 456 | "sebastian/version": "~1.0", 457 | "symfony/yaml": "~2.1|~3.0" 458 | }, 459 | "suggest": { 460 | "phpunit/php-invoker": "~1.1" 461 | }, 462 | "bin": [ 463 | "phpunit" 464 | ], 465 | "type": "library", 466 | "extra": { 467 | "branch-alias": { 468 | "dev-master": "4.8.x-dev" 469 | } 470 | }, 471 | "autoload": { 472 | "classmap": [ 473 | "src/" 474 | ] 475 | }, 476 | "notification-url": "https://packagist.org/downloads/", 477 | "license": [ 478 | "BSD-3-Clause" 479 | ], 480 | "authors": [ 481 | { 482 | "name": "Sebastian Bergmann", 483 | "email": "sebastian@phpunit.de", 484 | "role": "lead" 485 | } 486 | ], 487 | "description": "The PHP Unit Testing framework.", 488 | "homepage": "https://phpunit.de/", 489 | "keywords": [ 490 | "phpunit", 491 | "testing", 492 | "xunit" 493 | ], 494 | "time": "2017-06-21T08:07:12+00:00" 495 | }, 496 | { 497 | "name": "phpunit/phpunit-mock-objects", 498 | "version": "2.3.8", 499 | "source": { 500 | "type": "git", 501 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 502 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" 503 | }, 504 | "dist": { 505 | "type": "zip", 506 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", 507 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", 508 | "shasum": "" 509 | }, 510 | "require": { 511 | "doctrine/instantiator": "^1.0.2", 512 | "php": ">=5.3.3", 513 | "phpunit/php-text-template": "~1.2", 514 | "sebastian/exporter": "~1.2" 515 | }, 516 | "require-dev": { 517 | "phpunit/phpunit": "~4.4" 518 | }, 519 | "suggest": { 520 | "ext-soap": "*" 521 | }, 522 | "type": "library", 523 | "extra": { 524 | "branch-alias": { 525 | "dev-master": "2.3.x-dev" 526 | } 527 | }, 528 | "autoload": { 529 | "classmap": [ 530 | "src/" 531 | ] 532 | }, 533 | "notification-url": "https://packagist.org/downloads/", 534 | "license": [ 535 | "BSD-3-Clause" 536 | ], 537 | "authors": [ 538 | { 539 | "name": "Sebastian Bergmann", 540 | "email": "sb@sebastian-bergmann.de", 541 | "role": "lead" 542 | } 543 | ], 544 | "description": "Mock Object library for PHPUnit", 545 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 546 | "keywords": [ 547 | "mock", 548 | "xunit" 549 | ], 550 | "time": "2015-10-02T06:51:40+00:00" 551 | }, 552 | { 553 | "name": "sebastian/comparator", 554 | "version": "1.2.4", 555 | "source": { 556 | "type": "git", 557 | "url": "https://github.com/sebastianbergmann/comparator.git", 558 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" 559 | }, 560 | "dist": { 561 | "type": "zip", 562 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 563 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 564 | "shasum": "" 565 | }, 566 | "require": { 567 | "php": ">=5.3.3", 568 | "sebastian/diff": "~1.2", 569 | "sebastian/exporter": "~1.2 || ~2.0" 570 | }, 571 | "require-dev": { 572 | "phpunit/phpunit": "~4.4" 573 | }, 574 | "type": "library", 575 | "extra": { 576 | "branch-alias": { 577 | "dev-master": "1.2.x-dev" 578 | } 579 | }, 580 | "autoload": { 581 | "classmap": [ 582 | "src/" 583 | ] 584 | }, 585 | "notification-url": "https://packagist.org/downloads/", 586 | "license": [ 587 | "BSD-3-Clause" 588 | ], 589 | "authors": [ 590 | { 591 | "name": "Jeff Welch", 592 | "email": "whatthejeff@gmail.com" 593 | }, 594 | { 595 | "name": "Volker Dusch", 596 | "email": "github@wallbash.com" 597 | }, 598 | { 599 | "name": "Bernhard Schussek", 600 | "email": "bschussek@2bepublished.at" 601 | }, 602 | { 603 | "name": "Sebastian Bergmann", 604 | "email": "sebastian@phpunit.de" 605 | } 606 | ], 607 | "description": "Provides the functionality to compare PHP values for equality", 608 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 609 | "keywords": [ 610 | "comparator", 611 | "compare", 612 | "equality" 613 | ], 614 | "time": "2017-01-29T09:50:25+00:00" 615 | }, 616 | { 617 | "name": "sebastian/diff", 618 | "version": "1.4.3", 619 | "source": { 620 | "type": "git", 621 | "url": "https://github.com/sebastianbergmann/diff.git", 622 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" 623 | }, 624 | "dist": { 625 | "type": "zip", 626 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", 627 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", 628 | "shasum": "" 629 | }, 630 | "require": { 631 | "php": "^5.3.3 || ^7.0" 632 | }, 633 | "require-dev": { 634 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 635 | }, 636 | "type": "library", 637 | "extra": { 638 | "branch-alias": { 639 | "dev-master": "1.4-dev" 640 | } 641 | }, 642 | "autoload": { 643 | "classmap": [ 644 | "src/" 645 | ] 646 | }, 647 | "notification-url": "https://packagist.org/downloads/", 648 | "license": [ 649 | "BSD-3-Clause" 650 | ], 651 | "authors": [ 652 | { 653 | "name": "Kore Nordmann", 654 | "email": "mail@kore-nordmann.de" 655 | }, 656 | { 657 | "name": "Sebastian Bergmann", 658 | "email": "sebastian@phpunit.de" 659 | } 660 | ], 661 | "description": "Diff implementation", 662 | "homepage": "https://github.com/sebastianbergmann/diff", 663 | "keywords": [ 664 | "diff" 665 | ], 666 | "time": "2017-05-22T07:24:03+00:00" 667 | }, 668 | { 669 | "name": "sebastian/environment", 670 | "version": "1.3.8", 671 | "source": { 672 | "type": "git", 673 | "url": "https://github.com/sebastianbergmann/environment.git", 674 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" 675 | }, 676 | "dist": { 677 | "type": "zip", 678 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", 679 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", 680 | "shasum": "" 681 | }, 682 | "require": { 683 | "php": "^5.3.3 || ^7.0" 684 | }, 685 | "require-dev": { 686 | "phpunit/phpunit": "^4.8 || ^5.0" 687 | }, 688 | "type": "library", 689 | "extra": { 690 | "branch-alias": { 691 | "dev-master": "1.3.x-dev" 692 | } 693 | }, 694 | "autoload": { 695 | "classmap": [ 696 | "src/" 697 | ] 698 | }, 699 | "notification-url": "https://packagist.org/downloads/", 700 | "license": [ 701 | "BSD-3-Clause" 702 | ], 703 | "authors": [ 704 | { 705 | "name": "Sebastian Bergmann", 706 | "email": "sebastian@phpunit.de" 707 | } 708 | ], 709 | "description": "Provides functionality to handle HHVM/PHP environments", 710 | "homepage": "http://www.github.com/sebastianbergmann/environment", 711 | "keywords": [ 712 | "Xdebug", 713 | "environment", 714 | "hhvm" 715 | ], 716 | "time": "2016-08-18T05:49:44+00:00" 717 | }, 718 | { 719 | "name": "sebastian/exporter", 720 | "version": "1.2.2", 721 | "source": { 722 | "type": "git", 723 | "url": "https://github.com/sebastianbergmann/exporter.git", 724 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" 725 | }, 726 | "dist": { 727 | "type": "zip", 728 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", 729 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", 730 | "shasum": "" 731 | }, 732 | "require": { 733 | "php": ">=5.3.3", 734 | "sebastian/recursion-context": "~1.0" 735 | }, 736 | "require-dev": { 737 | "ext-mbstring": "*", 738 | "phpunit/phpunit": "~4.4" 739 | }, 740 | "type": "library", 741 | "extra": { 742 | "branch-alias": { 743 | "dev-master": "1.3.x-dev" 744 | } 745 | }, 746 | "autoload": { 747 | "classmap": [ 748 | "src/" 749 | ] 750 | }, 751 | "notification-url": "https://packagist.org/downloads/", 752 | "license": [ 753 | "BSD-3-Clause" 754 | ], 755 | "authors": [ 756 | { 757 | "name": "Jeff Welch", 758 | "email": "whatthejeff@gmail.com" 759 | }, 760 | { 761 | "name": "Volker Dusch", 762 | "email": "github@wallbash.com" 763 | }, 764 | { 765 | "name": "Bernhard Schussek", 766 | "email": "bschussek@2bepublished.at" 767 | }, 768 | { 769 | "name": "Sebastian Bergmann", 770 | "email": "sebastian@phpunit.de" 771 | }, 772 | { 773 | "name": "Adam Harvey", 774 | "email": "aharvey@php.net" 775 | } 776 | ], 777 | "description": "Provides the functionality to export PHP variables for visualization", 778 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 779 | "keywords": [ 780 | "export", 781 | "exporter" 782 | ], 783 | "time": "2016-06-17T09:04:28+00:00" 784 | }, 785 | { 786 | "name": "sebastian/global-state", 787 | "version": "1.1.1", 788 | "source": { 789 | "type": "git", 790 | "url": "https://github.com/sebastianbergmann/global-state.git", 791 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 792 | }, 793 | "dist": { 794 | "type": "zip", 795 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 796 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 797 | "shasum": "" 798 | }, 799 | "require": { 800 | "php": ">=5.3.3" 801 | }, 802 | "require-dev": { 803 | "phpunit/phpunit": "~4.2" 804 | }, 805 | "suggest": { 806 | "ext-uopz": "*" 807 | }, 808 | "type": "library", 809 | "extra": { 810 | "branch-alias": { 811 | "dev-master": "1.0-dev" 812 | } 813 | }, 814 | "autoload": { 815 | "classmap": [ 816 | "src/" 817 | ] 818 | }, 819 | "notification-url": "https://packagist.org/downloads/", 820 | "license": [ 821 | "BSD-3-Clause" 822 | ], 823 | "authors": [ 824 | { 825 | "name": "Sebastian Bergmann", 826 | "email": "sebastian@phpunit.de" 827 | } 828 | ], 829 | "description": "Snapshotting of global state", 830 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 831 | "keywords": [ 832 | "global state" 833 | ], 834 | "time": "2015-10-12T03:26:01+00:00" 835 | }, 836 | { 837 | "name": "sebastian/recursion-context", 838 | "version": "1.0.5", 839 | "source": { 840 | "type": "git", 841 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 842 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" 843 | }, 844 | "dist": { 845 | "type": "zip", 846 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 847 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 848 | "shasum": "" 849 | }, 850 | "require": { 851 | "php": ">=5.3.3" 852 | }, 853 | "require-dev": { 854 | "phpunit/phpunit": "~4.4" 855 | }, 856 | "type": "library", 857 | "extra": { 858 | "branch-alias": { 859 | "dev-master": "1.0.x-dev" 860 | } 861 | }, 862 | "autoload": { 863 | "classmap": [ 864 | "src/" 865 | ] 866 | }, 867 | "notification-url": "https://packagist.org/downloads/", 868 | "license": [ 869 | "BSD-3-Clause" 870 | ], 871 | "authors": [ 872 | { 873 | "name": "Jeff Welch", 874 | "email": "whatthejeff@gmail.com" 875 | }, 876 | { 877 | "name": "Sebastian Bergmann", 878 | "email": "sebastian@phpunit.de" 879 | }, 880 | { 881 | "name": "Adam Harvey", 882 | "email": "aharvey@php.net" 883 | } 884 | ], 885 | "description": "Provides functionality to recursively process PHP variables", 886 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 887 | "time": "2016-10-03T07:41:43+00:00" 888 | }, 889 | { 890 | "name": "sebastian/version", 891 | "version": "1.0.6", 892 | "source": { 893 | "type": "git", 894 | "url": "https://github.com/sebastianbergmann/version.git", 895 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 896 | }, 897 | "dist": { 898 | "type": "zip", 899 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 900 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 901 | "shasum": "" 902 | }, 903 | "type": "library", 904 | "autoload": { 905 | "classmap": [ 906 | "src/" 907 | ] 908 | }, 909 | "notification-url": "https://packagist.org/downloads/", 910 | "license": [ 911 | "BSD-3-Clause" 912 | ], 913 | "authors": [ 914 | { 915 | "name": "Sebastian Bergmann", 916 | "email": "sebastian@phpunit.de", 917 | "role": "lead" 918 | } 919 | ], 920 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 921 | "homepage": "https://github.com/sebastianbergmann/version", 922 | "time": "2015-06-21T13:59:46+00:00" 923 | }, 924 | { 925 | "name": "symfony/polyfill-ctype", 926 | "version": "v1.10.0", 927 | "source": { 928 | "type": "git", 929 | "url": "https://github.com/symfony/polyfill-ctype.git", 930 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" 931 | }, 932 | "dist": { 933 | "type": "zip", 934 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", 935 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", 936 | "shasum": "" 937 | }, 938 | "require": { 939 | "php": ">=5.3.3" 940 | }, 941 | "suggest": { 942 | "ext-ctype": "For best performance" 943 | }, 944 | "type": "library", 945 | "extra": { 946 | "branch-alias": { 947 | "dev-master": "1.9-dev" 948 | } 949 | }, 950 | "autoload": { 951 | "psr-4": { 952 | "Symfony\\Polyfill\\Ctype\\": "" 953 | }, 954 | "files": [ 955 | "bootstrap.php" 956 | ] 957 | }, 958 | "notification-url": "https://packagist.org/downloads/", 959 | "license": [ 960 | "MIT" 961 | ], 962 | "authors": [ 963 | { 964 | "name": "Symfony Community", 965 | "homepage": "https://symfony.com/contributors" 966 | }, 967 | { 968 | "name": "Gert de Pagter", 969 | "email": "BackEndTea@gmail.com" 970 | } 971 | ], 972 | "description": "Symfony polyfill for ctype functions", 973 | "homepage": "https://symfony.com", 974 | "keywords": [ 975 | "compatibility", 976 | "ctype", 977 | "polyfill", 978 | "portable" 979 | ], 980 | "time": "2018-08-06T14:22:27+00:00" 981 | }, 982 | { 983 | "name": "symfony/yaml", 984 | "version": "v2.8.49", 985 | "source": { 986 | "type": "git", 987 | "url": "https://github.com/symfony/yaml.git", 988 | "reference": "02c1859112aa779d9ab394ae4f3381911d84052b" 989 | }, 990 | "dist": { 991 | "type": "zip", 992 | "url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b", 993 | "reference": "02c1859112aa779d9ab394ae4f3381911d84052b", 994 | "shasum": "" 995 | }, 996 | "require": { 997 | "php": ">=5.3.9", 998 | "symfony/polyfill-ctype": "~1.8" 999 | }, 1000 | "type": "library", 1001 | "extra": { 1002 | "branch-alias": { 1003 | "dev-master": "2.8-dev" 1004 | } 1005 | }, 1006 | "autoload": { 1007 | "psr-4": { 1008 | "Symfony\\Component\\Yaml\\": "" 1009 | }, 1010 | "exclude-from-classmap": [ 1011 | "/Tests/" 1012 | ] 1013 | }, 1014 | "notification-url": "https://packagist.org/downloads/", 1015 | "license": [ 1016 | "MIT" 1017 | ], 1018 | "authors": [ 1019 | { 1020 | "name": "Fabien Potencier", 1021 | "email": "fabien@symfony.com" 1022 | }, 1023 | { 1024 | "name": "Symfony Community", 1025 | "homepage": "https://symfony.com/contributors" 1026 | } 1027 | ], 1028 | "description": "Symfony Yaml Component", 1029 | "homepage": "https://symfony.com", 1030 | "time": "2018-11-11T11:18:13+00:00" 1031 | } 1032 | ], 1033 | "aliases": [], 1034 | "minimum-stability": "stable", 1035 | "stability-flags": [], 1036 | "prefer-stable": false, 1037 | "prefer-lowest": false, 1038 | "platform": { 1039 | "php": ">=5.3.0", 1040 | "ext-mbstring": "*" 1041 | }, 1042 | "platform-dev": [], 1043 | "platform-overrides": { 1044 | "php": "5.4.7" 1045 | } 1046 | } 1047 | --------------------------------------------------------------------------------