Overview

Namespaces

  • Peach
    • DF
    • DT
    • Http
      • Body
      • Header
    • Markup
    • Util

Classes

  • Peach\DF\Base64Codec
  • Peach\DF\CodecChain
  • Peach\DF\JsonCodec
  • Peach\DF\SerializationCodec
  • Peach\DF\Utf8Codec
  • Peach\DT\AbstractTime
  • Peach\DT\Clock
  • Peach\DT\Date
  • Peach\DT\Datetime
  • Peach\DT\DefaultClock
  • Peach\DT\FixedClock
  • Peach\DT\FormatWrapper
  • Peach\DT\HttpDateFormat
  • Peach\DT\OffsetClock
  • Peach\DT\ShiftFormat
  • Peach\DT\SimpleFormat
  • Peach\DT\TimeEquator
  • Peach\DT\Timestamp
  • Peach\DT\TimeWrapper
  • Peach\DT\UnixTimeFormat
  • Peach\DT\Util
  • Peach\DT\W3cDatetimeFormat
  • Peach\Http\Body
  • Peach\Http\Body\CodecRenderer
  • Peach\Http\Body\StringRenderer
  • Peach\Http\DefaultEndpoint
  • Peach\Http\Header\CookieItem
  • Peach\Http\Header\CookieOptions
  • Peach\Http\Header\HttpDate
  • Peach\Http\Header\NoField
  • Peach\Http\Header\QualityValues
  • Peach\Http\Header\Raw
  • Peach\Http\Header\SetCookie
  • Peach\Http\Header\Status
  • Peach\Http\Request
  • Peach\Http\Response
  • Peach\Http\Util
  • Peach\Markup\AbstractHelper
  • Peach\Markup\AbstractRenderer
  • Peach\Markup\BaseHelper
  • Peach\Markup\BreakControlWrapper
  • Peach\Markup\Builder
  • Peach\Markup\Code
  • Peach\Markup\Comment
  • Peach\Markup\ContainerElement
  • Peach\Markup\Context
  • Peach\Markup\DebugBuilder
  • Peach\Markup\DebugContext
  • Peach\Markup\DefaultBreakControl
  • Peach\Markup\DefaultBuilder
  • Peach\Markup\DefaultContext
  • Peach\Markup\Element
  • Peach\Markup\EmptyElement
  • Peach\Markup\HelperObject
  • Peach\Markup\HtmlHelper
  • Peach\Markup\Indent
  • Peach\Markup\MinimalBreakControl
  • Peach\Markup\NameBreakControl
  • Peach\Markup\NameValidator
  • Peach\Markup\NodeList
  • Peach\Markup\None
  • Peach\Markup\SgmlRenderer
  • Peach\Markup\Text
  • Peach\Markup\XmlRenderer
  • Peach\Util\AbstractMapEntry
  • Peach\Util\ArrayMap
  • Peach\Util\ArrayMapEntry
  • Peach\Util\Arrays
  • Peach\Util\DefaultComparator
  • Peach\Util\DefaultEquator
  • Peach\Util\HashMap
  • Peach\Util\HashMapEntry
  • Peach\Util\Strings
  • Peach\Util\Values

Interfaces

  • Peach\DF\Codec
  • Peach\DT\Format
  • Peach\DT\Time
  • Peach\Http\BodyRenderer
  • Peach\Http\Endpoint
  • Peach\Http\HeaderField
  • Peach\Http\MultiHeaderField
  • Peach\Http\SingleHeaderField
  • Peach\Markup\BreakControl
  • Peach\Markup\Component
  • Peach\Markup\Container
  • Peach\Markup\Helper
  • Peach\Markup\Node
  • Peach\Markup\Renderer
  • Peach\Util\Comparable
  • Peach\Util\Comparator
  • Peach\Util\Equator
  • Peach\Util\Map
  • Peach\Util\MapEntry
  • Overview
  • Namespace
  • Class
  1: <?php
  2: /*
  3:  * Copyright (c) 2015 @trashtoy
  4:  * https://github.com/trashtoy/
  5:  * 
  6:  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  7:  * this software and associated documentation files (the "Software"), to deal in
  8:  * the Software without restriction, including without limitation the rights to use,
  9:  * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 10:  * Software, and to permit persons to whom the Software is furnished to do so,
 11:  * subject to the following conditions:
 12:  * 
 13:  * The above copyright notice and this permission notice shall be included in all
 14:  * copies or substantial portions of the Software.
 15:  * 
 16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 18:  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 19:  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 20:  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 21:  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 22:  */
 23: /**
 24:  * PHP class file.
 25:  * @auhtor trashtoy
 26:  * @since  2.1.0
 27:  */
 28: namespace Peach\Markup;
 29: 
 30: /**
 31:  * XML の仕様書で定義されている以下の EBNF に基づいて,
 32:  * 要素名や属性名などのバリデーションを行います.
 33:  * 
 34:  * <pre>
 35:  * NameStartChar       ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] |
 36:  *                         [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] |
 37:  *                         [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
 38:  * NameChar            ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
 39:  * Name                ::= NameStartChar (NameChar)*
 40:  * </pre>
 41:  * 
 42:  * 参考文献: {@link http://www.w3.org/TR/REC-xml/ Extensible Markup Language (XML) 1.0 (Fifth Edition)}
 43:  */
 44: class NameValidator
 45: {
 46:     /**
 47:      * このクラスはインスタンス化できません.
 48:      */
 49:     private function __construct() {}
 50:     
 51:     /**
 52:      * 指定された文字列が XML で定義されている Name のネーミングルールに合致するかどうか調べます.
 53:      * 
 54:      * @param  string $name 検査対象の文字列
 55:      * @return bool         指定された文字列が Name として妥当な場合のみ true
 56:      */
 57:     public static function validate($name)
 58:     {
 59:         if (self::validateFast($name)) {
 60:             return true;
 61:         }
 62:         
 63:         $utf8Codec  = new \Peach\DF\Utf8Codec();
 64:         $codepoints = $utf8Codec->decode($name);
 65:         if (!count($codepoints)) {
 66:             return false;
 67:         }
 68:         $start = array_shift($codepoints);
 69:         if (!self::validateNameStartChar($start)) {
 70:             return false;
 71:         }
 72:         foreach ($codepoints as $c) {
 73:             if (!self::validateNameChar($c)) {
 74:                 return false;
 75:             }
 76:         }
 77:         return true;
 78:     }
 79:     
 80:     /**
 81:      * 使用頻度の高い Name 文字列 (例えば HTML タグなど) について,
 82:      * 簡易な正規表現を使って検査します.
 83:      * 
 84:      * @param  string $name 検査対象の文字列
 85:      * @return bool         "h1", "img" など, ASCII 文字から成る妥当な Name 文字列の場合のみ true
 86:      */
 87:     private static function validateFast($name)
 88:     {
 89:         $firstNameCharClass = "[a-zA-Z_:]";
 90:         $nameCharClass      = "[a-zA-Z0-9_:\\.\\-]";
 91:         $pattern            = "/\\A{$firstNameCharClass}{$nameCharClass}*\\z/";
 92:         return (0 < preg_match($pattern, $name));
 93:     }
 94:     
 95:     /**
 96:      * 指定された Unicode 符号点が NameStartChar の範囲に適合するかどうかを調べます.
 97:      * 
 98:      * @param  int $codepoint Unicode 符号点
 99:      * @return bool           引数が NameStartChar である場合のみ true
100:      */
101:     private static function validateNameStartChar($codepoint)
102:     {
103:         // @codeCoverageIgnoreStart
104:         static $range = null;
105:         if ($range === null) {
106:             $first = new NameValidator_Range(0x61, 0x7A); // a-z
107:             $range = $first
108:                     ->add(0x41, 0x5A)->add(0x3A)->add(0x5F) // A-Z, ":", "_"
109:                     ->add(0xC0, 0xD6)->add(0xD8, 0xF6)->add(0xF8, 0x2FF)
110:                     ->add(0x370, 0x37D)->add(0x37F, 0x1FFF)->add(0x200C, 0x200D)
111:                     ->add(0x2070, 0x218F)->add(0x2C00, 0x2FEF)->add(0x3001, 0xD7FF)
112:                     ->add(0xF900, 0xFDCF)->add(0xFDF0, 0xFFFD)->add(0x10000, 0xEFFFF);
113:         }
114:         // @codeCoverageIgnoreEnd
115:         
116:         return $range->validate($codepoint);
117:     }
118:     
119:     /**
120:      * 指定された Unicode 符号点が NameChar の範囲に適合するかどうかを調べます.
121:      * 
122:      * @param  int $codepoint Unicode 符号点
123:      * @return bool           引数が NameChar である場合のみ true
124:      */
125:     private static function validateNameChar($codepoint)
126:     {
127:         // @codeCoverageIgnoreStart
128:         static $range = null;
129:         if ($range === null) {
130:             $first = new NameValidator_Range(0x30, 0x39); // 0-9
131:             $range = $first
132:                     ->add(0x2D, 0x2E)->add(0xB7) // "-", ".", MIDDLE DOT
133:                     ->add(0x0300, 0x036F)->add(0x203F, 0x2040);
134:         }
135:         // @codeCoverageIgnoreEnd
136:         
137:         return self::validateNameStartChar($codepoint) || $range->validate($codepoint);
138:     }
139: }
140: 
141: /**
142:  * 指定された Unicode 符号点が, 特定の範囲内に存在するかどうかを確認します.
143:  * @ignore
144:  */
145: class NameValidator_Range
146: {
147:     /**
148:      * 範囲の最小値です.
149:      * @var int
150:      */
151:     private $min;
152:     
153:     /**
154:      * 範囲の最大値です.
155:      * @var int
156:      */
157:     private $max;
158:     
159:     /**
160:      * 検査対象の Unicode 符号点がこのオブジェクトの
161:      * $min と $max の範囲内になかった場合に使用される次の Range オブジェクトです.
162:      * 
163:      * @var NameValidator_Range
164:      */
165:     private $next;
166:     
167:     /**
168:      * 指定された Unicode 符号点の範囲を持つ NameValidator_Range オブジェクトを構築します.
169:      * 
170:      * @param int $min 範囲の最小値
171:      * @param int $max 範囲の最大値
172:      * @param NameValidator_Range $next 次の Range オブジェクト (add が使用します)
173:      * @codeCoverageIgnore
174:      */
175:     public function __construct($min, $max, NameValidator_Range $next = null)
176:     {
177:         $this->min  = $min;
178:         $this->max  = ($max === null) ? $min : $max;
179:         $this->next = $next;
180:     }
181:     
182:     /**
183:      * このオブジェクトを次の Range オブジェクトとして設定した新しい Range オブジェクトを返します.
184:      * 
185:      * @param  int $min 範囲の最小値
186:      * @param  int $max 範囲の最大値 (単一の値を指定する場合は省略可)
187:      * @return NameValidator_Range
188:      * @codeCoverageIgnore
189:      */
190:     public function add($min, $max = null)
191:     {
192:         return new self($min, $max, $this);
193:     }
194:     
195:     /**
196:      * 指定された Unicode 符号点がこのオブジェクトが示す範囲内に存在するかどうか調べます.
197:      * 次の Range オブジェクトが設定されている場合, 再帰的に validate() を実行した結果を返します.
198:      * 
199:      * @param  int  $codepoint Unicode 符号点
200:      * @return bool            引数が範囲内に存在する場合のみ true
201:      */
202:     public function validate($codepoint)
203:     {
204:         return
205:             ($this->min <= $codepoint && $codepoint <= $this->max) ||
206:             ($this->next !== null && $this->next->validate($codepoint));
207:     }
208: }
209: 
PEACH2 API documentation generated by ApiGen