SimplePie: PHP-based RSS and Atom feed handling
 
  • Overview
  • Demo
  • Blog
  • Download
  • Documentation
  • API Docs
  • Support
  • Issue Tracker
  • FAQ
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated

Packages

  • SimplePie
    • API
    • Caching
    • HTTP
    • Parsing

Classes

  • SimplePie_Content_Type_Sniffer
  • SimplePie_File
  • SimplePie_gzdecode
  • SimplePie_HTTP_Parser
  • SimplePie_IRI
  • SimplePie_Net_IPv6
  1: <?php
  2: /**
  3:  * SimplePie
  4:  *
  5:  * A PHP-Based RSS and Atom Feed Framework.
  6:  * Takes the hard work out of managing a complete RSS/Atom solution.
  7:  *
  8:  * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
  9:  * All rights reserved.
 10:  *
 11:  * Redistribution and use in source and binary forms, with or without modification, are
 12:  * permitted provided that the following conditions are met:
 13:  *
 14:  *  * Redistributions of source code must retain the above copyright notice, this list of
 15:  *    conditions and the following disclaimer.
 16:  *
 17:  *  * Redistributions in binary form must reproduce the above copyright notice, this list
 18:  *    of conditions and the following disclaimer in the documentation and/or other materials
 19:  *    provided with the distribution.
 20:  *
 21:  *  * Neither the name of the SimplePie Team nor the names of its contributors may be used
 22:  *    to endorse or promote products derived from this software without specific prior
 23:  *    written permission.
 24:  *
 25:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 26:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 27:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
 28:  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 29:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 30:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 31:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 32:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 33:  * POSSIBILITY OF SUCH DAMAGE.
 34:  *
 35:  * @package SimplePie
 36:  * @version 1.3
 37:  * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
 38:  * @author Ryan Parman
 39:  * @author Geoffrey Sneddon
 40:  * @author Ryan McCue
 41:  * @link http://simplepie.org/ SimplePie
 42:  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
 43:  */
 44: 
 45: 
 46: /**
 47:  * Class to validate and to work with IPv6 addresses.
 48:  *
 49:  * @package SimplePie
 50:  * @subpackage HTTP
 51:  * @copyright 2003-2005 The PHP Group
 52:  * @license http://www.opensource.org/licenses/bsd-license.php
 53:  * @link http://pear.php.net/package/Net_IPv6
 54:  * @author Alexander Merz <alexander.merz@web.de>
 55:  * @author elfrink at introweb dot nl
 56:  * @author Josh Peck <jmp at joshpeck dot org>
 57:  * @author Geoffrey Sneddon <geoffers@gmail.com>
 58:  */
 59: class SimplePie_Net_IPv6
 60: {
 61:     /**
 62:      * Uncompresses an IPv6 address
 63:      *
 64:      * RFC 4291 allows you to compress concecutive zero pieces in an address to
 65:      * '::'. This method expects a valid IPv6 address and expands the '::' to
 66:      * the required number of zero pieces.
 67:      *
 68:      * Example:  FF01::101   ->  FF01:0:0:0:0:0:0:101
 69:      *           ::1         ->  0:0:0:0:0:0:0:1
 70:      *
 71:      * @author Alexander Merz <alexander.merz@web.de>
 72:      * @author elfrink at introweb dot nl
 73:      * @author Josh Peck <jmp at joshpeck dot org>
 74:      * @copyright 2003-2005 The PHP Group
 75:      * @license http://www.opensource.org/licenses/bsd-license.php
 76:      * @param string $ip An IPv6 address
 77:      * @return string The uncompressed IPv6 address
 78:      */
 79:     public static function uncompress($ip)
 80:     {
 81:         $c1 = -1;
 82:         $c2 = -1;
 83:         if (substr_count($ip, '::') === 1)
 84:         {
 85:             list($ip1, $ip2) = explode('::', $ip);
 86:             if ($ip1 === '')
 87:             {
 88:                 $c1 = -1;
 89:             }
 90:             else
 91:             {
 92:                 $c1 = substr_count($ip1, ':');
 93:             }
 94:             if ($ip2 === '')
 95:             {
 96:                 $c2 = -1;
 97:             }
 98:             else
 99:             {
100:                 $c2 = substr_count($ip2, ':');
101:             }
102:             if (strpos($ip2, '.') !== false)
103:             {
104:                 $c2++;
105:             }
106:             // ::
107:             if ($c1 === -1 && $c2 === -1)
108:             {
109:                 $ip = '0:0:0:0:0:0:0:0';
110:             }
111:             // ::xxx
112:             else if ($c1 === -1)
113:             {
114:                 $fill = str_repeat('0:', 7 - $c2);
115:                 $ip = str_replace('::', $fill, $ip);
116:             }
117:             // xxx::
118:             else if ($c2 === -1)
119:             {
120:                 $fill = str_repeat(':0', 7 - $c1);
121:                 $ip = str_replace('::', $fill, $ip);
122:             }
123:             // xxx::xxx
124:             else
125:             {
126:                 $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
127:                 $ip = str_replace('::', $fill, $ip);
128:             }
129:         }
130:         return $ip;
131:     }
132: 
133:     /**
134:      * Compresses an IPv6 address
135:      *
136:      * RFC 4291 allows you to compress concecutive zero pieces in an address to
137:      * '::'. This method expects a valid IPv6 address and compresses consecutive
138:      * zero pieces to '::'.
139:      *
140:      * Example:  FF01:0:0:0:0:0:0:101   ->  FF01::101
141:      *           0:0:0:0:0:0:0:1        ->  ::1
142:      *
143:      * @see uncompress()
144:      * @param string $ip An IPv6 address
145:      * @return string The compressed IPv6 address
146:      */
147:     public static function compress($ip)
148:     {
149:         // Prepare the IP to be compressed
150:         $ip = self::uncompress($ip);
151:         $ip_parts = self::split_v6_v4($ip);
152: 
153:         // Replace all leading zeros
154:         $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
155: 
156:         // Find bunches of zeros
157:         if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
158:         {
159:             $max = 0;
160:             $pos = null;
161:             foreach ($matches[0] as $match)
162:             {
163:                 if (strlen($match[0]) > $max)
164:                 {
165:                     $max = strlen($match[0]);
166:                     $pos = $match[1];
167:                 }
168:             }
169: 
170:             $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
171:         }
172: 
173:         if ($ip_parts[1] !== '')
174:         {
175:             return implode(':', $ip_parts);
176:         }
177:         else
178:         {
179:             return $ip_parts[0];
180:         }
181:     }
182: 
183:     /**
184:      * Splits an IPv6 address into the IPv6 and IPv4 representation parts
185:      *
186:      * RFC 4291 allows you to represent the last two parts of an IPv6 address
187:      * using the standard IPv4 representation
188:      *
189:      * Example:  0:0:0:0:0:0:13.1.68.3
190:      *           0:0:0:0:0:FFFF:129.144.52.38
191:      *
192:      * @param string $ip An IPv6 address
193:      * @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
194:      */
195:     private static function split_v6_v4($ip)
196:     {
197:         if (strpos($ip, '.') !== false)
198:         {
199:             $pos = strrpos($ip, ':');
200:             $ipv6_part = substr($ip, 0, $pos);
201:             $ipv4_part = substr($ip, $pos + 1);
202:             return array($ipv6_part, $ipv4_part);
203:         }
204:         else
205:         {
206:             return array($ip, '');
207:         }
208:     }
209: 
210:     /**
211:      * Checks an IPv6 address
212:      *
213:      * Checks if the given IP is a valid IPv6 address
214:      *
215:      * @param string $ip An IPv6 address
216:      * @return bool true if $ip is a valid IPv6 address
217:      */
218:     public static function check_ipv6($ip)
219:     {
220:         $ip = self::uncompress($ip);
221:         list($ipv6, $ipv4) = self::split_v6_v4($ip);
222:         $ipv6 = explode(':', $ipv6);
223:         $ipv4 = explode('.', $ipv4);
224:         if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
225:         {
226:             foreach ($ipv6 as $ipv6_part)
227:             {
228:                 // The section can't be empty
229:                 if ($ipv6_part === '')
230:                     return false;
231: 
232:                 // Nor can it be over four characters
233:                 if (strlen($ipv6_part) > 4)
234:                     return false;
235: 
236:                 // Remove leading zeros (this is safe because of the above)
237:                 $ipv6_part = ltrim($ipv6_part, '0');
238:                 if ($ipv6_part === '')
239:                     $ipv6_part = '0';
240: 
241:                 // Check the value is valid
242:                 $value = hexdec($ipv6_part);
243:                 if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
244:                     return false;
245:             }
246:             if (count($ipv4) === 4)
247:             {
248:                 foreach ($ipv4 as $ipv4_part)
249:                 {
250:                     $value = (int) $ipv4_part;
251:                     if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
252:                         return false;
253:                 }
254:             }
255:             return true;
256:         }
257:         else
258:         {
259:             return false;
260:         }
261:     }
262: 
263:     /**
264:      * Checks if the given IP is a valid IPv6 address
265:      *
266:      * @codeCoverageIgnore
267:      * @deprecated Use {@see SimplePie_Net_IPv6::check_ipv6()} instead
268:      * @see check_ipv6
269:      * @param string $ip An IPv6 address
270:      * @return bool true if $ip is a valid IPv6 address
271:      */
272:     public static function checkIPv6($ip)
273:     {
274:         return self::check_ipv6($ip);
275:     }
276: }
277: 

Show some love! Wishlists for Geoffrey, Ryan P., and Ryan M.

SimplePie is © 2004–2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue and contributors. Licensed under the BSD License. Hosted thanks to Matt Mullenweg, API documentation generated by ApiGen 2.6.1. Variation on the Feed Icon by Wolfgang Bartelme.