CrossPHP
  • Namespace
  • Class
  • Download

Namespaces

  • Cross
    • Auth
    • Cache
      • Driver
      • Request
    • Core
    • DB
      • Connecter
      • Drivers
      • SQLAssembler
    • Exception
    • Http
    • I
    • Lib
      • Document
    • Module
    • MVC
    • Runtime
  • None

Classes

  • Cross\Auth\CookieAuth
  • Cross\Auth\SessionAuth
  • Cross\Cache\Driver\FileCacheDriver
  • Cross\Cache\Driver\MemcacheDriver
  • Cross\Cache\Driver\RedisDriver
  • Cross\Cache\Request\FileCache
  • Cross\Cache\Request\Memcache
  • Cross\Cache\Request\RedisCache
  • Cross\Cache\RequestCache
  • Cross\Core\Annotate
  • Cross\Core\Application
  • Cross\Core\ArrayMap
  • Cross\Core\Config
  • Cross\Core\CrossArray
  • Cross\Core\Delegate
  • Cross\Core\FrameBase
  • Cross\Core\Helper
  • Cross\Core\HttpAuth
  • Cross\Core\Loader
  • Cross\Core\Rest
  • Cross\Core\Router
  • Cross\DB\Connecter\BaseConnecter
  • Cross\DB\Connecter\MySQLConnecter
  • Cross\DB\Connecter\PgSQLConnecter
  • Cross\DB\Connecter\SQLiteConnecter
  • Cross\DB\DBFactory
  • Cross\DB\Drivers\CouchDriver
  • Cross\DB\Drivers\MongoDriver
  • Cross\DB\Drivers\PDOSqlDriver
  • Cross\DB\SQLAssembler\MySQLAssembler
  • Cross\DB\SQLAssembler\PgSQLAssembler
  • Cross\DB\SQLAssembler\SQLAssembler
  • Cross\DB\SQLAssembler\SQLiteAssembler
  • Cross\Http\Request
  • Cross\Http\Response
  • Cross\Lib\Array2XML
  • Cross\Lib\Document\CallTree
  • Cross\Lib\Document\CallTreeToHTML
  • Cross\Lib\Document\HTML
  • Cross\Lib\StringToPHPStream
  • Cross\Module\SQLModule
  • Cross\MVC\Controller
  • Cross\MVC\Module
  • Cross\MVC\View
  • Cross\Runtime\ClosureContainer

Interfaces

  • Cross\I\CacheInterface
  • Cross\I\HttpAuthInterface
  • Cross\I\PDOConnecter
  • Cross\I\RequestCacheInterface
  • Cross\I\RouterInterface
  • Cross\I\SqlInterface

Exceptions

  • Cross\Exception\CacheException
  • Cross\Exception\CoreException
  • Cross\Exception\CrossException
  • Cross\Exception\FrontException

Functions

  • ascLogo
  • line
  • tBody
  • th
  • tHead
  1 <?php
  2 /**
  3  * Cross - a micro PHP 5 framework
  4  *
  5  * @link        http://www.crossphp.com
  6  * @license     MIT License
  7  */
  8 
  9 namespace Cross\Http;
 10 
 11 /**
 12  * @author wonli <wonli@live.com>
 13  * Class Response
 14  * @package Cross\Core
 15  */
 16 class Response
 17 {
 18     /**
 19      * http头
 20      *
 21      * @var array
 22      */
 23     protected $header;
 24 
 25     /**
 26      * cookie
 27      *
 28      * @var array
 29      */
 30     protected $cookie;
 31 
 32     /**
 33      * cookie配置
 34      *
 35      * @var array
 36      */
 37     protected $cookie_config;
 38 
 39     /**
 40      * 返回头http类型
 41      *
 42      * @var string
 43      */
 44     protected $content_type;
 45 
 46     /**
 47      * http 状态代码
 48      *
 49      * @var int
 50      */
 51     protected $response_status;
 52 
 53     /**
 54      * 停止发送标识
 55      *
 56      * @var bool
 57      */
 58     protected $is_end_flush = false;
 59 
 60     /**
 61      * Response instance
 62      *
 63      * @var object
 64      */
 65     static $instance;
 66 
 67     private function __construct()
 68     {
 69 
 70     }
 71 
 72     /**
 73      * 单例模式
 74      *
 75      * @return Response
 76      */
 77     static function getInstance()
 78     {
 79         if (!self::$instance) {
 80             self::$instance = new Response();
 81         }
 82 
 83         return self::$instance;
 84     }
 85 
 86     /**
 87      * @param int $status
 88      * @return $this
 89      */
 90     function setResponseStatus($status = 200)
 91     {
 92         $this->response_status = $status;
 93         return $this;
 94     }
 95 
 96     /**
 97      * @return int
 98      */
 99     function getResponseStatus()
100     {
101         if (!$this->response_status) {
102             $this->setResponseStatus();
103         }
104 
105         return $this->response_status;
106     }
107 
108     /**
109      * 设置header信息
110      *
111      * @param $header
112      * @return $this
113      */
114     function setHeader($header)
115     {
116         if (is_array($header)) {
117             foreach ($header as $key => $value) {
118                 $this->header[] = "{$key}: {$value}";
119             }
120         } else {
121             $this->header[] = $header;
122         }
123 
124         return $this;
125     }
126 
127     /**
128      * 获取要发送到header信息
129      */
130     function getHeader()
131     {
132         return $this->header;
133     }
134 
135     /**
136      * 添加cookie
137      *
138      * @param mixed $name
139      * @param string $value
140      * @param int $expire
141      * @return $this
142      */
143     function setCookie($name, $value = '', $expire = 0)
144     {
145         $this->cookie[$name] = array(
146             $name,
147             $value,
148             $expire,
149             $this->getCookieConfig('path'),
150             $this->getCookieConfig('domain'),
151             $this->getCookieConfig('secure'),
152             $this->getCookieConfig('httponly')
153         );
154 
155         return $this;
156     }
157 
158     /**
159      * 获取cookie
160      *
161      * @return array
162      */
163     function getCookie()
164     {
165         return $this->cookie;
166     }
167 
168     /**
169      * 删除cookie
170      *
171      * @param string $name
172      * @return $this
173      */
174     function deleteCookie($name)
175     {
176         $this->setCookie($name, null, -1);
177         return $this;
178     }
179 
180     /**
181      * 设置cookie参数默认值
182      * <pre>
183      * 参数为一个数组, 支持以下参数
184      *
185      * path 默认为空字符串
186      * domain 默认为空字符串
187      * secure 默认为false
188      * httponly 默认为true
189      * </pre>
190      *
191      * @param array $config
192      * @return $this
193      */
194     function cookieConfig(array $config)
195     {
196         $this->cookie_config = $config;
197         return $this;
198     }
199 
200     /**
201      * 获取cookie参数默认值
202      *
203      * @param null $key
204      * @return array|mixed
205      */
206     function getCookieConfig($key = null)
207     {
208         $default = array('path' => '/', 'domain' => '', 'secure' => false, 'httponly' => true);
209         if ($key && isset($default[$key])) {
210             if (isset($this->cookie_config[$key])) {
211                 return $this->cookie_config[$key];
212             }
213 
214             return $default[$key];
215         }
216 
217         return null;
218     }
219 
220     /**
221      * 设置返回头类型
222      *
223      * @param string $content_type
224      * @return $this
225      */
226     function setContentType($content_type = 'html')
227     {
228         $this->content_type = strtolower($content_type);
229         return $this;
230     }
231 
232     /**
233      * 返回ContentType
234      *
235      * @return mixed
236      */
237     function getContentType()
238     {
239         if (!$this->content_type) {
240             $this->setContentType();
241         }
242         return $this->content_type;
243     }
244 
245     /**
246      * basic authentication
247      *
248      * @param array $users ['user' => 'password']
249      * @param array $options
250      */
251     function basicAuth(array $users, $options = array())
252     {
253         $user = &$_SERVER['PHP_AUTH_USER'];
254         $password = &$_SERVER['PHP_AUTH_PW'];
255         if (isset($users[$user]) && (0 === strcmp($password, $users[$user]))) {
256             $_SERVER['CP_AUTH_USER'] = $user;
257             return;
258         }
259 
260         $realm = &$options['realm'];
261         if (null === $realm) {
262             $realm = 'CP Login Required';
263         }
264 
265         $message = &$options['fail_msg'];
266         if (null === $message) {
267             $message = self::$statusDescriptions[401];
268         }
269 
270         $this->setResponseStatus(401)
271             ->setHeader('WWW-Authenticate: Basic realm="' . $realm . '"')
272             ->displayOver($message);
273     }
274 
275     /**
276      * digest authentication
277      *
278      * @param array $users ['user' => 'password']
279      * @param array $options
280      */
281     function digestAuth(array $users, array $options = array())
282     {
283         $realm = &$options['realm'];
284         if (null === $realm) {
285             $realm = 'CP Login Required';
286         }
287 
288         $digest = &$_SERVER['PHP_AUTH_DIGEST'];
289         if ($digest) {
290             $data = $this->httpDigestParse($digest);
291             if (isset($data['username']) && isset($users[$data['username']])) {
292                 $A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
293                 $A2 = md5($_SERVER['REQUEST_METHOD'] . ':' . $data['uri']);
294                 $valid_response = md5($A1 . ':' . $data['nonce'] . ':' . $data['nc'] . ':' . $data['cnonce'] . ':' . $data['qop'] . ':' . $A2);
295                 if (0 === strcmp($valid_response, $data['response'])) {
296                     $_SERVER['CP_AUTH_USER'] = $data['username'];
297                     return;
298                 }
299             }
300         }
301 
302         $message = &$options['fail_msg'];
303         if (null === $message) {
304             $message = self::$statusDescriptions[401];
305         }
306 
307         $nonce = &$options['nonce'];
308         if (null === $nonce) {
309             $nonce = uniqid();
310         }
311 
312         $this->setResponseStatus(401)
313             ->setHeader('WWW-Authenticate: Digest realm="' . $realm .
314                 '",qop="auth",nonce="' . $nonce . '",opaque="' . md5($realm) . '"')
315             ->displayOver($message);
316     }
317 
318     /**
319      * 发送http 状态码
320      *
321      * @param int $code
322      * @param string $descriptions
323      */
324     function sendResponseStatus($code = 200, $descriptions = '')
325     {
326         if ($descriptions == '' && isset(self::$statusDescriptions[$code])) {
327             $descriptions = self::$statusDescriptions[$code];
328         }
329         header("HTTP/1.1 {$code} {$descriptions}");
330     }
331 
332     /**
333      * 发送ContentType
334      */
335     function sendContentType()
336     {
337         $content_type_name = $this->getContentType();
338         if (isset(self::$mime_types [$content_type_name])) {
339             $content_type = self::$mime_types [$content_type_name];
340         } elseif ($content_type_name) {
341             $content_type = $content_type_name;
342         } else {
343             $content_type = self::$mime_types ['html'];
344         }
345 
346         header("Content-Type: {$content_type}; charset=utf-8");
347     }
348 
349     /**
350      * 发送header
351      *
352      * @return $this
353      */
354     private function sendHeader()
355     {
356         $contents = $this->getHeader();
357         if (!empty($contents)) {
358             if (!is_array($contents)) {
359                 $contents = array($contents);
360             }
361 
362             foreach ($contents as $content) {
363                 header($content);
364             }
365         }
366 
367         return $this;
368     }
369 
370     /**
371      * 发送cookie
372      *
373      * @return $this
374      */
375     private function sendCookie()
376     {
377         if (!empty($this->cookie)) {
378             foreach ($this->cookie as $cookie) {
379                 call_user_func_array('setcookie', $cookie);
380             }
381         }
382 
383         return $this;
384     }
385 
386     /**
387      * 发送Response头
388      */
389     private function sendResponseHeader()
390     {
391         $this->sendContentType();
392         $this->sendHeader();
393     }
394 
395     /**
396      * 输出内容
397      *
398      * @param string $message
399      * @param string $tpl
400      * @return bool
401      */
402     private function flushContent($message, $tpl = '')
403     {
404         if (null !== $tpl && is_file($tpl)) {
405             require $tpl;
406         } else {
407             echo $message;
408         }
409 
410         return true;
411     }
412 
413     /**
414      * 标识停止输出
415      */
416     function setEndFlush()
417     {
418         $this->is_end_flush = true;
419         return $this;
420     }
421 
422     /**
423      * 获取标识状态,是否终止输出
424      *
425      * @return bool
426      */
427     function isEndFlush()
428     {
429         return $this->is_end_flush;
430     }
431 
432     /**
433      * 重定向
434      *
435      * @param string $url
436      * @param int $status
437      */
438     function redirect($url, $status = 302)
439     {
440         $this->setResponseStatus($status)->setHeader("Location: {$url}")->displayOver();
441         exit(0);
442     }
443 
444     /**
445      * 调用模板输出信息
446      *
447      * @param string $content
448      * @param string $tpl
449      */
450     function display($content = '', $tpl = '')
451     {
452         if (!headers_sent() && PHP_SAPI != 'cli') {
453             $code = $this->getResponseStatus();
454             $this->sendResponseStatus($code);
455             $this->sendResponseHeader();
456             $this->sendCookie();
457         }
458 
459         $this->flushContent($content, $tpl);
460     }
461 
462     /**
463      * 输出当前内容并结束
464      *
465      * @param string $content
466      * @param string $tpl
467      */
468     function displayOver($content = '', $tpl = '')
469     {
470         $this->setEndFlush();
471         $this->display($content, $tpl);
472     }
473 
474     /**
475      * parse digest authentication string
476      *
477      * @param string $txt
478      * @return array|bool
479      */
480     private function httpDigestParse($txt)
481     {
482         $data = array();
483         $needed_parts = array('nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1);
484         $keys = implode('|', array_keys($needed_parts));
485 
486         preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
487         foreach ($matches as $m) {
488             $data[$m[1]] = $m[3] ? $m[3] : $m[4];
489             unset($needed_parts[$m[1]]);
490         }
491 
492         return $needed_parts ? false : $data;
493     }
494 
495     /**
496      * @var array $statusDescriptions
497      */
498     static public $statusDescriptions = array(
499         100 => 'Continue',
500         101 => 'Switching Protocols',
501         200 => 'OK',
502         201 => 'Created',
503         202 => 'Accepted',
504         203 => 'Non-Authoritative Information',
505         204 => 'No Content',
506         205 => 'Reset Content',
507         206 => 'Partial Content',
508         300 => 'Multiple Choices',
509         301 => 'Moved Permanently',
510         302 => 'Found',
511         303 => 'See Other',
512         304 => 'Not Modified',
513         305 => 'Use Proxy',
514         307 => 'Temporary Redirect',
515         400 => 'Bad Request',
516         401 => 'Unauthorized',
517         403 => 'Forbidden',
518         404 => 'Not Found',
519         405 => 'Method Not Allowed',
520         406 => 'Not Acceptable',
521         407 => 'Proxy Authentication Required',
522         408 => 'Request Timeout',
523         409 => 'Conflict',
524         410 => 'Gone',
525         411 => 'Length Required',
526         412 => 'Precondition Failed',
527         413 => 'Request Entity Too Large',
528         414 => 'Request-URI Too Long',
529         415 => 'Unsupported Media Type',
530         416 => 'Requested Range Not Satisfiable',
531         417 => 'Expectation Failed',
532         500 => 'Internal Server Error',
533         501 => 'Not Implemented',
534         502 => 'Bad Gateway',
535         503 => 'Service Unavailable',
536         504 => 'Gateway Timeout',
537         505 => 'HTTP Version Not Supported'
538     );
539 
540     /**
541      * @var array $mime_types
542      */
543     static public $mime_types = array(
544         'ez' => 'application/andrew-inset',
545         'hqx' => 'application/mac-binhex40',
546         'cpt' => 'application/mac-compactpro',
547         'doc' => 'application/msword',
548         'bin' => 'application/octet-stream',
549         'dms' => 'application/octet-stream',
550         'lha' => 'application/octet-stream',
551         'lzh' => 'application/octet-stream',
552         'exe' => 'application/octet-stream',
553         'class' => 'application/octet-stream',
554         'so' => 'application/octet-stream',
555         'dll' => 'application/octet-stream',
556         'oda' => 'application/oda',
557         'pdf' => 'application/pdf',
558         'ai' => 'application/postscript',
559         'eps' => 'application/postscript',
560         'ps' => 'application/postscript',
561         'smi' => 'application/smil',
562         'smil' => 'application/smil',
563         'mif' => 'application/vnd.mif',
564         'xls' => 'application/vnd.ms-excel',
565         'ppt' => 'application/vnd.ms-powerpoint',
566         'wbxml' => 'application/vnd.wap.wbxml',
567         'wmlc' => 'application/vnd.wap.wmlc',
568         'wmlsc' => 'application/vnd.wap.wmlscriptc',
569         'bcpio' => 'application/x-bcpio',
570         'vcd' => 'application/x-cdlink',
571         'pgn' => 'application/x-chess-pgn',
572         'cpio' => 'application/x-cpio',
573         'csh' => 'application/x-csh',
574         'dcr' => 'application/x-director',
575         'dir' => 'application/x-director',
576         'dxr' => 'application/x-director',
577         'dvi' => 'application/x-dvi',
578         'spl' => 'application/x-futuresplash',
579         'gtar' => 'application/x-gtar',
580         'hdf' => 'application/x-hdf',
581         'js' => 'application/x-javascript',
582         'json' => 'application/json',
583         'skp' => 'application/x-koan',
584         'skd' => 'application/x-koan',
585         'skt' => 'application/x-koan',
586         'skm' => 'application/x-koan',
587         'latex' => 'application/x-latex',
588         'nc' => 'application/x-netcdf',
589         'cdf' => 'application/x-netcdf',
590         'sh' => 'application/x-sh',
591         'shar' => 'application/x-shar',
592         'swf' => 'application/x-shockwave-flash',
593         'sit' => 'application/x-stuffit',
594         'sv4cpio' => 'application/x-sv4cpio',
595         'sv4crc' => 'application/x-sv4crc',
596         'tar' => 'application/x-tar',
597         'tcl' => 'application/x-tcl',
598         'tex' => 'application/x-tex',
599         'texinfo' => 'application/x-texinfo',
600         'texi' => 'application/x-texinfo',
601         't' => 'application/x-troff',
602         'tr' => 'application/x-troff',
603         'roff' => 'application/x-troff',
604         'man' => 'application/x-troff-man',
605         'me' => 'application/x-troff-me',
606         'ms' => 'application/x-troff-ms',
607         'ustar' => 'application/x-ustar',
608         'src' => 'application/x-wais-source',
609         'xhtml' => 'application/xhtml+xml',
610         'xht' => 'application/xhtml+xml',
611         'zip' => 'application/zip',
612         'au' => 'audio/basic',
613         'snd' => 'audio/basic',
614         'mid' => 'audio/midi',
615         'midi' => 'audio/midi',
616         'kar' => 'audio/midi',
617         'mpga' => 'audio/mpeg',
618         'mp2' => 'audio/mpeg',
619         'mp3' => 'audio/mpeg',
620         'aif' => 'audio/x-aiff',
621         'aiff' => 'audio/x-aiff',
622         'aifc' => 'audio/x-aiff',
623         'm3u' => 'audio/x-mpegurl',
624         'ram' => 'audio/x-pn-realaudio',
625         'rm' => 'audio/x-pn-realaudio',
626         'rpm' => 'audio/x-pn-realaudio-plugin',
627         'ra' => 'audio/x-realaudio',
628         'wav' => 'audio/x-wav',
629         'pdb' => 'chemical/x-pdb',
630         'xyz' => 'chemical/x-xyz',
631         'bmp' => 'image/bmp',
632         'gif' => 'image/gif',
633         'ief' => 'image/ief',
634         'jpeg' => 'image/jpeg',
635         'jpg' => 'image/jpeg',
636         'jpe' => 'image/jpeg',
637         'png' => 'image/png',
638         'tiff' => 'image/tiff',
639         'tif' => 'image/tiff',
640         'djvu' => 'image/vnd.djvu',
641         'djv' => 'image/vnd.djvu',
642         'wbmp' => 'image/vnd.wap.wbmp',
643         'ras' => 'image/x-cmu-raster',
644         'pnm' => 'image/x-portable-anymap',
645         'pbm' => 'image/x-portable-bitmap',
646         'pgm' => 'image/x-portable-graymap',
647         'ppm' => 'image/x-portable-pixmap',
648         'rgb' => 'image/x-rgb',
649         'xbm' => 'image/x-xbitmap',
650         'xpm' => 'image/x-xpixmap',
651         'xwd' => 'image/x-xwindowdump',
652         'igs' => 'model/iges',
653         'iges' => 'model/iges',
654         'msh' => 'model/mesh',
655         'mesh' => 'model/mesh',
656         'silo' => 'model/mesh',
657         'wrl' => 'model/vrml',
658         'vrml' => 'model/vrml',
659         'css' => 'text/css',
660         'html' => 'text/html',
661         'htm' => 'text/html',
662         'asc' => 'text/plain',
663         'txt' => 'text/plain',
664         'rtx' => 'text/richtext',
665         'rtf' => 'text/rtf',
666         'sgml' => 'text/sgml',
667         'sgm' => 'text/sgml',
668         'tsv' => 'text/tab-separated-values',
669         'wml' => 'text/vnd.wap.wml',
670         'wmls' => 'text/vnd.wap.wmlscript',
671         'etx' => 'text/x-setext',
672         'xsl' => 'text/xml',
673         'xml' => 'text/xml',
674         'mpeg' => 'video/mpeg',
675         'mpg' => 'video/mpeg',
676         'mpe' => 'video/mpeg',
677         'qt' => 'video/quicktime',
678         'mov' => 'video/quicktime',
679         'mxu' => 'video/vnd.mpegurl',
680         'avi' => 'video/x-msvideo',
681         'movie' => 'video/x-sgi-movie',
682         'ice' => 'x-conference/x-cooltalk',
683     );
684 }
685 
686 
CrossPHP API documentation generated by ApiGen