Overview

Namespaces

  • Kotchasan
    • Cache
    • Database
    • Http
    • Log
    • Orm
  • None
  • PHP
  • Psr
    • Cache
    • Http
      • Message
    • Log

Classes

  • ArrayIterator
  • DateInterval
  • DOMNode
  • Kotchasan
  • Kotchasan\Accordion
  • Kotchasan\ApiController
  • Kotchasan\ArrayTool
  • Kotchasan\Cache\ApcCache
  • Kotchasan\Cache\Cache
  • Kotchasan\Cache\CacheItem
  • Kotchasan\Cache\FileCache
  • Kotchasan\CKEditor
  • Kotchasan\Collection
  • Kotchasan\Config
  • Kotchasan\Controller
  • Kotchasan\Country
  • Kotchasan\Csv
  • Kotchasan\Curl
  • Kotchasan\Currency
  • Kotchasan\Database
  • Kotchasan\Database\Db
  • Kotchasan\Database\DbCache
  • Kotchasan\Database\Driver
  • Kotchasan\Database\PdoMysqlDriver
  • Kotchasan\Database\Query
  • Kotchasan\Database\QueryBuilder
  • Kotchasan\Database\Schema
  • Kotchasan\Database\Sql
  • Kotchasan\DataTable
  • Kotchasan\Date
  • Kotchasan\DOMNode
  • Kotchasan\DOMParser
  • Kotchasan\Email
  • Kotchasan\File
  • Kotchasan\Files
  • Kotchasan\Form
  • Kotchasan\Grid
  • Kotchasan\Html
  • Kotchasan\Htmldoc
  • Kotchasan\HtmlTable
  • Kotchasan\Http\AbstractMessage
  • Kotchasan\Http\AbstractRequest
  • Kotchasan\Http\Message
  • Kotchasan\Http\NotFound
  • Kotchasan\Http\Request
  • Kotchasan\Http\Response
  • Kotchasan\Http\Stream
  • Kotchasan\Http\UploadedFile
  • Kotchasan\Http\Uri
  • Kotchasan\Image
  • Kotchasan\InputItem
  • Kotchasan\Inputs
  • Kotchasan\KBase
  • Kotchasan\Language
  • Kotchasan\ListItem
  • Kotchasan\Log\AbstractLogger
  • Kotchasan\Log\Logger
  • Kotchasan\Login
  • Kotchasan\Menu
  • Kotchasan\Mime
  • Kotchasan\Model
  • Kotchasan\Number
  • Kotchasan\ObjectTool
  • Kotchasan\Orm\Field
  • Kotchasan\Orm\Recordset
  • Kotchasan\Password
  • Kotchasan\Pdf
  • Kotchasan\Province
  • Kotchasan\Router
  • Kotchasan\Session
  • Kotchasan\Singleton
  • Kotchasan\Tab
  • Kotchasan\TableRow
  • Kotchasan\Template
  • Kotchasan\Text
  • Kotchasan\Validator
  • Kotchasan\View
  • PHPMailer
  • Psr\Log\AbstractLogger
  • Psr\Log\LogLevel
  • Psr\Log\NullLogger
  • SMTP

Interfaces

  • ArrayAccess
  • Countable
  • DateTimeInterface
  • Iterator
  • IteratorAggregate
  • Psr\Cache\CacheItemInterface
  • Psr\Cache\CacheItemPoolInterface
  • Psr\Http\Message\MessageInterface
  • Psr\Http\Message\RequestInterface
  • Psr\Http\Message\ResponseInterface
  • Psr\Http\Message\ServerRequestInterface
  • Psr\Http\Message\StreamInterface
  • Psr\Http\Message\UploadedFileInterface
  • Psr\Http\Message\UriInterface
  • Psr\Log\LoggerAwareInterface
  • Psr\Log\LoggerInterface
  • SeekableIterator
  • Serializable
  • Traversable

Traits

  • Psr\Log\LoggerTrait

Exceptions

  • Exception
  • InvalidArgumentException
  • Kotchasan\ApiException
  • Kotchasan\Cache\Exception
  • Kotchasan\Database\Exception
  • Kotchasan\InputItemException
  • LogicException
  • phpmailerException
  • RuntimeException

Functions

  • createClass
  • debug
  • getClassPath
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * @filesource Kotchasan/Http/Uri.php
  4:  *
  5:  * @copyright 2016 Goragod.com
  6:  * @license http://www.kotchasan.com/license/
  7:  *
  8:  * @see http://www.kotchasan.com/
  9:  */
 10: 
 11: namespace Kotchasan\Http;
 12: 
 13: /**
 14:  * Class สำหรับจัดการ Uri (PSR-7)
 15:  *
 16:  * @author Goragod Wiriya <admin@goragod.com>
 17:  *
 18:  * @since 1.0
 19:  */
 20: class Uri extends \Kotchasan\KBase implements \Psr\Http\Message\UriInterface
 21: {
 22:     /**
 23:      * Uri fragment หลัง  #
 24:      *
 25:      * @var string
 26:      */
 27:     protected $fragment = '';
 28:     /**
 29:      * Uri host
 30:      *
 31:      * @var string
 32:      */
 33:     protected $host = '';
 34:     /**
 35:      * Uri path
 36:      *
 37:      * @var string
 38:      */
 39:     protected $path = '';
 40:     /**
 41:      * Uri port
 42:      *
 43:      * @var int
 44:      */
 45:     protected $port;
 46:     /**
 47:      * Uri query string หลัง ?
 48:      *
 49:      * @var string
 50:      */
 51:     protected $query = '';
 52:     /**
 53:      * Uri scheme
 54:      *
 55:      * @var string
 56:      */
 57:     protected $scheme = '';
 58:     /**
 59:      * Uri user info
 60:      *
 61:      * @var string
 62:      */
 63:     protected $userInfo = '';
 64: 
 65:     /**
 66:      * Create a new Uri
 67:      *
 68:      * @param string $uri
 69:      *
 70:      * @throws \InvalidArgumentException ถ้า Uri ไม่ถูกต้อง
 71:      */
 72:     public function __construct($scheme, $host, $path = '/', $query = '', $port = null, $user = '', $pass = '', $fragment = '')
 73:     {
 74:         $this->scheme = $this->filterScheme($scheme);
 75:         $this->host = $host;
 76:         $this->path = $path;
 77:         $this->query = $this->filterQueryFragment($query);
 78:         $this->port = $this->filterPort($this->scheme, $this->host, $port) ? $port : null;
 79:         $this->userInfo = $user.($pass === '' ? '' : ':'.$pass);
 80:         $this->fragment = $this->filterQueryFragment($fragment);
 81:     }
 82: 
 83:     /**
 84:      * magic function ส่งออกคลาสเป็น String
 85:      *
 86:      * @return string
 87:      */
 88:     public function __toString()
 89:     {
 90:         return self::createUriString(
 91:             $this->scheme,
 92:             $this->getAuthority(),
 93:             $this->path,
 94:             $this->query,
 95:             $this->fragment
 96:         );
 97:     }
 98: 
 99:     /**
100:      * ฟังก์ชั่นสร้าง URL สำหรับส่งต่อ Query string จากหน้าหนึ่งไปยังอีกหน้าหนึ่ง
101:      * เพื่อให้สามารถสร้าง URL ที่สามารถส่งกลับไปยังหน้าเดิมได้โดย ฟังก์ชั่น back()
102:      * ลบรายการที่ เป็น null ออก
103:      *
104:      * @param array $query_string
105:      *
106:      * @return string
107:      */
108:     public function createBackUri($query_string)
109:     {
110:         $query_str = array();
111:         foreach ($this->parseQueryParams($this->query) as $key => $value) {
112:             $key = ltrim($key, '_');
113:             if (key_exists($key, $query_string) && $query_string[$key] === null) {
114:                 continue;
115:             } elseif (preg_match('/((^[0-9]+$)|(.*?(username|password|token|time).*?))/', $key)) {
116:                 continue;
117:             }
118:             if ($value !== null) {
119:                 $query_str['_'.$key] = $value;
120:             }
121:         }
122:         foreach ($query_string as $key => $value) {
123:             if ($value !== null) {
124:                 $query_str[$key] = $value;
125:             }
126:         }
127:         return $this->withQuery($this->paramsToQuery($query_str, true));
128:     }
129: 
130:     /**
131:      * สร้าง Uri จากตัวแปร $_SERVER
132:      *
133:      * @throws \InvalidArgumentException ถ้า Uri ไม่ถูกต้อง
134:      *
135:      * @return \static
136:      */
137:     public static function createFromGlobals()
138:     {
139:         if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
140:             $scheme = $_SERVER['HTTP_X_FORWARDED_PROTO'].'://';
141:         } elseif ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)) {
142:             $scheme = 'https://';
143:         } else {
144:             $scheme = 'http://';
145:         }
146:         if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
147:             $host = trim(current(explode(',', $_SERVER['HTTP_X_FORWARDED_HOST'])));
148:         } elseif (empty($_SERVER['HTTP_HOST'])) {
149:             $host = $_SERVER['SERVER_NAME'];
150:         } else {
151:             $host = $_SERVER['HTTP_HOST'];
152:         }
153:         $pos = strpos($host, ':');
154:         if ($pos !== false) {
155:             $port = (int) substr($host, $pos + 1);
156:             $host = strstr($host, ':', true);
157:         } else {
158:             $port = isset($_SERVER['SERVER_PORT']) ? (int) $_SERVER['SERVER_PORT'] : 80;
159:         }
160:         $path = empty($_SERVER['REQUEST_URI']) ? '/' : parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
161:         $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
162:         $user = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
163:         $pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
164:         return new static($scheme, $host, $path, $query, $port, $user, $pass);
165:     }
166: 
167:     /**
168:      * สร้างคลาสจากลิงค์
169:      *
170:      * @param string $uri
171:      *
172:      * @throws \InvalidArgumentException ถ้า $uri ไม่ถูกต้อง
173:      *
174:      * @return \static
175:      */
176:     public static function createFromUri($uri)
177:     {
178:         $parts = parse_url($uri);
179:         if (false === $parts) {
180:             throw new \InvalidArgumentException('Invalid Uri');
181:         } else {
182:             $scheme = isset($parts['scheme']) ? $parts['scheme'] : '';
183:             $host = isset($parts['host']) ? $parts['host'] : '';
184:             $port = isset($parts['port']) ? $parts['port'] : null;
185:             $user = isset($parts['user']) ? $parts['user'] : '';
186:             $pass = isset($parts['pass']) ? $parts['pass'] : '';
187:             $path = isset($parts['path']) ? $parts['path'] : '';
188:             $query = isset($parts['query']) ? $parts['query'] : '';
189:             $fragment = isset($parts['fragment']) ? $parts['fragment'] : '';
190:             return new static($scheme, $host, $path, $query, $port, $user, $pass, $fragment);
191:         }
192:     }
193: 
194:     /**
195:      * ตืนค่า authority ของ Uri [user-info@]host[:port]
196:      *
197:      * @return string
198:      */
199:     public function getAuthority()
200:     {
201:         return ($this->userInfo ? $this->userInfo.'@' : '').$this->host.($this->port !== null ? ':'.$this->port : '');
202:     }
203: 
204:     /**
205:      * แปลง GET เป็น query string สำหรับการส่งกลับไปหน้าเดิม ที่มาจากการโพสต์ด้วยฟอร์ม
206:      *
207:      * @param string $url          URL ที่ต้องการส่งกลับ เช่น index.php
208:      * @param array  $query_string (option) query string ที่ต้องการส่งกลับไปด้วย array('key' => 'value', ...)
209:      *
210:      * @return string URL+query string
211:      */
212:     public function getBack($url, $query_string = array())
213:     {
214:         return $this->createBack($url, $_GET, $query_string);
215:     }
216: 
217:     /**
218:      * คืนค่า fragment (ข้อมูลหลัง # ใน Uri) ของ Uri
219:      *
220:      * @return string
221:      */
222:     public function getFragment()
223:     {
224:         return $this->fragment;
225:     }
226: 
227:     /**
228:      * คืนค่า Hostname ของ Uri เช่น domain.tld
229:      *
230:      * @return string
231:      */
232:     public function getHost()
233:     {
234:         return $this->host;
235:     }
236: 
237:     /**
238:      * คืนค่า path ของ Uri เช่น /kotchasan
239:      *
240:      * @return string
241:      */
242:     public function getPath()
243:     {
244:         return $this->path;
245:     }
246: 
247:     /**
248:      * คืนค่าหมายเลข Port ของ Uri
249:      * ไม่ระบุหรือเป็น default port (80,433) คืนค่า null
250:      *
251:      * @return null|int
252:      */
253:     public function getPort()
254:     {
255:         return $this->port;
256:     }
257: 
258:     /**
259:      * คืนค่า query string (ข้อมูลหลัง ? ใน Uri) ของ Uri
260:      *
261:      * @return string
262:      */
263:     public function getQuery()
264:     {
265:         return $this->query;
266:     }
267: 
268:     /**
269:      * คืนค่า scheme ของ Uri ไม่รวม :// เช่น http, https.
270:      *
271:      * @return string
272:      */
273:     public function getScheme()
274:     {
275:         return $this->scheme;
276:     }
277: 
278:     /**
279:      * คืนค่าข้อมูล user ของ Uri user[:password]
280:      *
281:      * @return string
282:      */
283:     public function getUserInfo()
284:     {
285:         return $this->userInfo;
286:     }
287: 
288:     /**
289:      * ฟังก์ชั่นแสดงผลตัวแบ่งหน้า
290:      *
291:      * @param int $totalpage จำนวนหน้าทั้งหมด
292:      * @param int $page      หน้าปัจจุบัน
293:      * @param int $maxlink   (optional) จำนวนตัวเลือกแบ่งหน้าสูงสุด ค่าปกติ 9
294:      *
295:      * @return string
296:      */
297:     public function pagination($totalpage, $page, $maxlink = 9)
298:     {
299:         if ($totalpage > $maxlink) {
300:             $start = $page - floor($maxlink / 2);
301:             if ($start < 1) {
302:                 $start = 1;
303:             } elseif ($start + $maxlink > $totalpage) {
304:                 $start = $totalpage - $maxlink + 1;
305:             }
306:         } else {
307:             $start = 1;
308:         }
309:         $url = '<a href="'.$this->withParams(array('page' => ':page'), true).'" title="{LNG_go to page} :page">:page</a>';
310:         $splitpage = ($start > 2) ? str_replace(':page', 1, $url) : '';
311:         for ($i = $start; $i <= $totalpage && $maxlink > 0; ++$i) {
312:             $splitpage .= ($i == $page) ? '<strong title="{LNG_Showing page} '.$i.'">'.$i.'</strong>' : str_replace(':page', $i, $url);
313:             --$maxlink;
314:         }
315:         $splitpage .= ($i < $totalpage) ? str_replace(':page', $totalpage, $url) : '';
316:         return empty($splitpage) ? '<strong>1</strong>' : $splitpage;
317:     }
318: 
319:     /**
320:      * ฟังก์ชั่นแปลง Queryparams เป็น Querystring
321:      *
322:      * @param array $params
323:      * @param bool  $encode false เชื่อม Querystring ด้วย &, true เชื่อม Querystring ด้วย &amp;
324:      *
325:      * @return string
326:      */
327:     public function paramsToQuery($params, $encode)
328:     {
329:         $query_str = array();
330:         foreach ($params as $key => $value) {
331:             if (preg_match('/^[a-zA-Z0-9_\-\[\]]+$/', $key)) {
332:                 if ($value === null) {
333:                     $query_str[$key] = $key;
334:                 } else {
335:                     $query_str[$key] = $key.'='.$this->filterQueryFragment($value);
336:                 }
337:             }
338:         }
339:         return implode($encode ? '&amp;' : '&', $query_str);
340:     }
341: 
342:     /**
343:      * ฟังก์ชั่น แยก Querystring ออกเป็น array
344:      *
345:      * @param string $query
346:      *
347:      * @return array
348:      */
349:     public function parseQueryParams($query = null)
350:     {
351:         $query = $query === null ? $this->query : $query;
352:         $result = array();
353:         if (!empty($query)) {
354:             foreach (explode('&', str_replace('&amp;', '&', $query)) as $item) {
355:                 if (preg_match('/^([a-zA-Z0-9_\-\[\]]+)(=(.*))?$/', $item, $match)) {
356:                     if (isset($match[3])) {
357:                         if (!(preg_match('/^[0-9]+$/', $match[1]) && $match[3] === '')) {
358:                             $result[$match[1]] = $match[3];
359:                         }
360:                     } else {
361:                         $result[$match[1]] = null;
362:                     }
363:                 }
364:             }
365:         }
366:         return $result;
367:     }
368: 
369:     /**
370:      * แปลง POST เป็น query string สำหรับการส่งกลับไปหน้าเดิม ที่มาจากการโพสต์ด้วยฟอร์ม
371:      * คืนค่า URL+query string
372:      *
373:      * @param string $url          URL ที่ต้องการส่งกลับ เช่น index.php
374:      * @param array  $query_string (option) query string ที่ต้องการส่งกลับไปด้วย array('key' => 'value', ...)
375:      *
376:      * @return string
377:      */
378:     public function postBack($url, $query_string = array())
379:     {
380:         return $this->createBack($url, $_POST, $query_string);
381:     }
382: 
383:     /**
384:      * กำหนดค่า fragment
385:      * คืนค่า Object ใหม่
386:      *
387:      * @param string $fragment
388:      *
389:      * @throws \InvalidArgumentException ถ้า fragment ไม่ถูกต้อง
390:      *
391:      * @return \static
392:      */
393:     public function withFragment($fragment)
394:     {
395:         if (!is_string($fragment) && !method_exists($fragment, '__toString')) {
396:             throw new \InvalidArgumentException('Uri fragment must be a string');
397:         }
398:         $fragment = ltrim((string) $fragment, '#');
399:         $clone = clone $this;
400:         $clone->fragment = $this->filterQueryFragment($fragment);
401:         return $clone;
402:     }
403: 
404:     /**
405:      * กำหนดชื่อ host
406:      * คืนค่า Object ใหม่
407:      *
408:      * @param string $host ชื่อ host
409:      *
410:      * @return \static
411:      */
412:     public function withHost($host)
413:     {
414:         $clone = clone $this;
415:         $clone->host = $host;
416:         return $clone;
417:     }
418: 
419:     /**
420:      * ฟังก์ชั่นแทนที่ Query params ลงใน URL
421:      *
422:      * @param array $params
423:      * @param bool  $encode false (default) เชื่อม Querystring ด้วย &, true เชื่อม Querystring ด้วย &amp;
424:      *
425:      * @return \static
426:      */
427:     public function withParams($params, $encode = false)
428:     {
429:         $query_str = array();
430:         foreach ($this->parseQueryParams($this->query) as $key => $value) {
431:             $query_str[$key] = $value;
432:         }
433:         foreach ($params as $key => $value) {
434:             $query_str[$key] = $value;
435:         }
436:         return $this->withQuery($this->paramsToQuery($query_str, $encode));
437:     }
438: 
439:     /**
440:      * ฟังก์ลบ Query params ออกจาก URL
441:      *
442:      * @param string|array $names  ชื่อของ attributes ที่ต้องการลบ
443:      * @param bool         $encode false (default) เชื่อม Querystring ด้วย &, true เชื่อม Querystring ด้วย &amp;
444:      *
445:      * @return \static
446:      */
447:     public function withoutParams($names, $encode = false)
448:     {
449:         $attributes = $this->parseQueryParams($this->query);
450:         if (is_array($names)) {
451:             foreach ($names as $name) {
452:                 unset($attributes[$name]);
453:             }
454:         } else {
455:             unset($attributes[$names]);
456:         }
457:         return $this->withQuery($this->paramsToQuery($attributes, $encode));
458:     }
459: 
460:     /**
461:      * กำหนดชื่อ path
462:      * path ต้องเริ่มต้นด้วย / เช่น /kotchasan
463:      * หรือเป็นค่าว่าง ถ้าเป็นรากของโดเมน
464:      * คืนค่า Object ใหม่
465:      *
466:      * @param string $path ชื่อ path
467:      *
468:      * @return \static
469:      */
470:     public function withPath($path)
471:     {
472:         $clone = clone $this;
473:         $clone->path = $this->filterPath($path);
474:         return $clone;
475:     }
476: 
477:     /**
478:      * กำหนดค่า port
479:      * คืนค่า Object ใหม่
480:      *
481:      * @param null|int $port หมายเลข port 1- 65535 หรือ null
482:      *
483:      * @throws \InvalidArgumentException ถ้า port ไม่ถูกต้อง
484:      *
485:      * @return \static
486:      */
487:     public function withPort($port)
488:     {
489:         $clone = clone $this;
490:         $clone->port = $this->filterPort($this->scheme, $this->host, $port);
491:         return $clone;
492:     }
493: 
494:     /**
495:      * กำหนดค่า query string
496:      * คืนค่า Object ใหม่
497:      *
498:      * @param string $query
499:      *
500:      * @throws \InvalidArgumentException ถ้า query string ไม่ถูกต้อง
501:      *
502:      * @return \static
503:      */
504:     public function withQuery($query)
505:     {
506:         if (!is_string($query) && !method_exists($query, '__toString')) {
507:             throw new \InvalidArgumentException('Uri query must be a string');
508:         }
509:         $query = ltrim((string) $query, '?');
510:         $clone = clone $this;
511:         $clone->query = $this->filterQueryFragment($query);
512:         return $clone;
513:     }
514: 
515:     /**
516:      * ลบ query string
517:      * คืนค่า Object ใหม่
518:      *
519:      * @param array $query array('q1' => 'value1', 'q2' => 'value2')
520:      *
521:      * @return \static
522:      */
523:     public function withoutQuery($query)
524:     {
525:         $clone = clone $this;
526:         $queries = array();
527:         foreach (explode('&', $clone->query) as $item) {
528:             $queries[$item] = $item;
529:         }
530:         foreach ($query as $k => $v) {
531:             unset($queries[$k.'='.$v]);
532:         }
533:         $clone->query = implode('&', $queries);
534:         return $clone;
535:     }
536: 
537:     /**
538:      * กำหนดค่า scheme ของ Uri
539:      * คืนค่า Object ใหม่
540:      *
541:      * @param string $scheme http หรือ https หรือค่าว่าง
542:      *
543:      * @throws \InvalidArgumentException ถ้าไม่ใช่ ค่าว่าง http หรือ https
544:      *
545:      * @return \static
546:      */
547:     public function withScheme($scheme)
548:     {
549:         $clone = clone $this;
550:         $clone->scheme = $this->filterScheme($scheme);
551:         return $clone;
552:     }
553: 
554:     /**
555:      * กำหนดข้อมูล user ของ Uri
556:      * คืนค่า Object ใหม่
557:      *
558:      * @param string $user
559:      * @param string $password
560:      *
561:      * @return \static
562:      */
563:     public function withUserInfo($user, $password = null)
564:     {
565:         $clone = clone $this;
566:         $clone->userInfo = $user.($password ? ':'.$password : '');
567:         return $clone;
568:     }
569: 
570:     /**
571:      * แปลง POST เป็น query string สำหรับการส่งกลับไปหน้าเดิม ที่มาจากการโพสต์ด้วยฟอร์ม
572:      * คืนค่า URL+query string
573:      *
574:      * @param string $url          URL ที่ต้องการส่งกลับ เช่น index.php
575:      * @param array  $source       query string จาก $_POST หรือ $_GET
576:      * @param array  $query_string query string ที่ต้องการส่งกลับไปด้วย array('key' => 'value', ...)
577:      *
578:      * @return string
579:      */
580:     private function createBack($url, $source, $query_string)
581:     {
582:         foreach ($source as $key => $value) {
583:             if ($value !== '' && !preg_match('/.*?(username|password|token|time).*?/', $key) && preg_match('/^_{1,}(.*)$/', $key, $match)) {
584:                 if (!isset($query_string[$match[1]])) {
585:                     $query_string[$match[1]] = $value;
586:                 }
587:             }
588:         }
589:         if (isset($query_string['time'])) {
590:             $query_string['time'] = time();
591:         }
592:         $query_str = array();
593:         foreach ($query_string as $key => $value) {
594:             if ($value !== null) {
595:                 $query_str[$key] = $value;
596:             }
597:         }
598:         return $url.(strpos($url, '?') === false ? '?' : '&').$this->paramsToQuery($query_str, false);
599:     }
600: 
601:     /**
602:      * สร้าง Uri
603:      * เช่น http://domain.tld/
604:      *
605:      * @param string $scheme
606:      * @param string $authority
607:      * @param string $path
608:      * @param string $query
609:      * @param string $fragment
610:      *
611:      * @return string
612:      */
613:     private static function createUriString($scheme, $authority, $path, $query, $fragment)
614:     {
615:         $uri = '';
616:         if (!empty($scheme)) {
617:             $uri .= $scheme.'://';
618:         }
619:         if (!empty($authority)) {
620:             $uri .= $authority;
621:         }
622:         if ($path != null) {
623:             if ($uri && substr($path, 0, 1) !== '/') {
624:                 $uri .= '/';
625:             }
626:             $uri .= $path;
627:         }
628:         if ($query != '') {
629:             $uri .= '?'.$query;
630:         }
631:         if ($fragment != '') {
632:             $uri .= '#'.$fragment;
633:         }
634:         return $uri;
635:     }
636: 
637:     /**
638:      * ตรวจสอบ path
639:      *
640:      * @param  $path
641:      *
642:      * @return string
643:      */
644:     private function filterPath($path)
645:     {
646:         return preg_replace_callback('/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/', function ($match) {
647:             return rawurlencode($match[0]);
648:         }, $path);
649:     }
650: 
651:     /**
652:      * ตรวจสอบ port
653:      *
654:      * @param string $scheme
655:      * @param string $host
656:      * @param int    $port
657:      *
658:      * @throws \InvalidArgumentException ถ้า port ไม่ถูกต้อง
659:      *
660:      * @return int|null
661:      */
662:     private function filterPort($scheme, $host, $port)
663:     {
664:         if (null !== $port) {
665:             $port = (int) $port;
666:             if (1 > $port || 0xffff < $port) {
667:                 throw new \InvalidArgumentException('Port number must be between 1 and 65535');
668:             }
669:         }
670:         return $this->isNonStandardPort($scheme, $host, $port) ? $port : null;
671:     }
672: 
673:     /**
674:      * ตรวจสอบ query และ fragment
675:      *
676:      * @param  $str
677:      *
678:      * @return string
679:      */
680:     private function filterQueryFragment($str)
681:     {
682:         return preg_replace_callback('/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/', function ($match) {
683:             return rawurlencode($match[0]);
684:         }, $str);
685:     }
686: 
687:     /**
688:      * ตรวจสอบ scheme
689:      *
690:      * @param string $scheme
691:      *
692:      * @throws \InvalidArgumentException ถ้าไม่ใช่ ค่าว่าง http หรือ https
693:      *
694:      * @return string
695:      */
696:     private function filterScheme($scheme)
697:     {
698:         $schemes = array('' => '', 'http' => 'http', 'https' => 'https');
699:         $scheme = rtrim(strtolower($scheme), ':/');
700:         if (isset($schemes[$scheme])) {
701:             return $scheme;
702:         } else {
703:             throw new \InvalidArgumentException('Uri scheme must be http, https or empty string');
704:         }
705:     }
706: 
707:     /**
708:      * ตรวจสอบว่าเป็น port มาตรฐานหรือไม่
709:      * เช่น http เป็น 80 หรือ https เป็น 433
710:      *
711:      * @param string $scheme
712:      * @param string $host
713:      * @param int    $port
714:      *
715:      * @return bool
716:      */
717:     private function isNonStandardPort($scheme, $host, $port)
718:     {
719:         if (!$scheme && $port) {
720:             return true;
721:         }
722:         if (!$host || !$port) {
723:             return false;
724:         }
725:         return ($scheme != 'http' && $scheme != 'https') || ($port != 80 && $port != 443);
726:     }
727: }
728: 
Kotchasan API documentation generated by ApiGen