Example #1
0
 /**
  * @return bool
  */
 protected function _destroy()
 {
     // Destroy the current session
     session_destroy();
     // Did destruction work?
     $status = !Base::getHttp()->sessionID();
     if ($status) {
         // Make sure the session cannot be restarted
         Cookie::delete($this->_name);
     }
     return $status;
 }
Example #2
0
 /**
  * 覆盖原workerman流程,实现更多功能
  * 当接收到完整的http请求后的处理逻辑
  *
  * 1、如果请求的是以php为后缀的文件,则尝试加载
  * 2、如果请求的url没有后缀,则尝试加载对应目录的index.php
  * 3、如果请求的是非php为后缀的文件,尝试读取原始数据并发送
  * 4、如果请求的文件不存在,则返回404
  *
  * @param TcpConnection $connection
  * @param mixed         $data
  * @return mixed
  */
 public function onMessage($connection, $data)
 {
     Base::getLog()->debug(__METHOD__ . ' receive http request', ['uri' => $_SERVER['REQUEST_URI'], 'ip' => $connection->getRemoteIp(), 'port' => $connection->getRemotePort(), 'data' => $data]);
     // 请求的文件
     $urlInfo = parse_url($_SERVER['REQUEST_URI']);
     if (!$urlInfo) {
         Base::getHttp()->header('HTTP/1.1 400 Bad Request');
         Base::getLog()->warning(__METHOD__ . ' receive bad request', ['uri' => $_SERVER['REQUEST_URI'], 'ip' => $connection->getRemoteIp(), 'port' => $connection->getRemotePort()]);
         return $connection->close($this->error400);
     }
     $path = $urlInfo['path'];
     $pathInfo = pathinfo($path);
     $extension = isset($pathInfo['extension']) ? $pathInfo['extension'] : '';
     if ($extension === '') {
         $path = ($len = strlen($path)) && $path[$len - 1] === '/' ? $path . $this->indexFile : $path . '/' . $this->indexFile;
         $extension = 'php';
     }
     $serverName = Arr::get($_SERVER, 'SERVER_NAME');
     $rootDir = isset($this->serverRoot[$serverName]) ? $this->serverRoot[$serverName] : current($this->serverRoot);
     $file = "{$rootDir}/{$path}";
     // 对应的php文件不存在,而且支持rewrite
     if (!is_file($file) && $this->rewrite) {
         $file = is_string($this->rewrite) ? $rootDir . '/' . $this->rewrite : $rootDir . '/' . $this->indexFile;
         $extension = 'php';
         $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];
     }
     // 请求的文件存在
     if (is_file($file)) {
         Base::getLog()->debug(__METHOD__ . ' request file existed', ['file' => $file, 'extension' => $extension]);
         // 判断是否是站点目录里的文件
         if (!($requestRealPath = realpath($file)) || !($rootDirRealPath = realpath($rootDir)) || 0 !== strpos($requestRealPath, $rootDirRealPath)) {
             Base::getHttp()->header('HTTP/1.1 400 Bad Request');
             Base::getLog()->warning(__METHOD__ . ' receive bad request', ['uri' => $_SERVER['REQUEST_URI'], 'ip' => $connection->getRemoteIp(), 'port' => $connection->getRemotePort()]);
             return $connection->close('<h1>400 Bad Request</h1>');
         }
         $file = realpath($file);
         // 如果请求的是php文件
         // PHP文件需要include
         if ($extension === 'php') {
             Base::getLog()->debug(__METHOD__ . ' handle request', ['uri' => $_SERVER['REQUEST_URI'], 'ip' => $connection->getRemoteIp(), 'port' => $connection->getRemotePort(), 'file' => $file]);
             Base::getLog()->debug(__METHOD__ . ' clean components - start');
             Base::cleanComponents();
             Base::getLog()->debug(__METHOD__ . ' clean components - end');
             $cwd = getcwd();
             chdir($rootDir);
             ini_set('display_errors', 'off');
             // 缓冲输出
             ob_start();
             // 载入php文件
             try {
                 // $_SERVER变量
                 $_SERVER['HOME'] = $_SERVER['DOCUMENT_ROOT'] = dirname($file);
                 $_SERVER['SCRIPT_FILENAME'] = $file;
                 Base::getLog()->debug(__METHOD__ . ' dispatch client info', ['ip' => $_SERVER['REMOTE_ADDR'], 'port' => $_SERVER['REMOTE_PORT']]);
                 include $file;
             } catch (Exception $e) {
                 Base::getLog()->error($e->getMessage(), ['code' => $e->getCode(), 'file' => $e->getFile(), 'line' => $e->getLine()]);
                 // 如果不是exit
                 if ($e->getMessage() != 'jump_exit') {
                     echo $e;
                 }
             }
             Patch::applyShutdownFunction();
             $content = ob_get_clean();
             ini_set('display_errors', 'on');
             $result = $connection->close($content);
             chdir($cwd);
             return $result;
         } else {
             $contentType = Mime::getMimeFromExtension($extension, self::$defaultMimeType);
             Base::getLog()->debug(__METHOD__ . ' get static file content type', ['extension' => $extension, 'contentType' => $contentType]);
             Base::getHttp()->header('Content-Type: ' . $contentType);
             // 获取文件信息
             $info = stat($file);
             $modifiedTime = $info ? date('D, d M Y H:i:s', Arr::get($info, 'mtime')) . ' GMT' : '';
             // 如果有$_SERVER['HTTP_IF_MODIFIED_SINCE']
             if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $info) {
                 // 文件没有更改则直接304
                 if ($modifiedTime === $_SERVER['HTTP_IF_MODIFIED_SINCE']) {
                     Base::getLog()->debug(__METHOD__ . ' no modified, return 304');
                     // 304
                     Base::getHttp()->header('HTTP/1.1 304 Not Modified');
                     // 发送给客户端
                     return $connection->close('');
                 }
             }
             if ($modifiedTime) {
                 Base::getLog()->debug(__METHOD__ . ' set last modified time', ['time' => $modifiedTime]);
                 Base::getHttp()->header("Last-Modified: {$modifiedTime}");
             }
             // 发送给客户端
             return $connection->close(file_get_contents($file));
         }
     } else {
         Base::getLog()->warning(__METHOD__ . ' requested file not found', ['file' => $file]);
         // 404
         Base::getHttp()->header("HTTP/1.1 404 Not Found");
         return $connection->close($this->error404);
     }
 }
Example #3
0
 /**
  * 跳转的助手方法
  *
  * @param  string $uri  要跳转的URI
  * @param  int    $code HTTP状态码
  * @throws HttpException
  */
 public function redirect($uri = '', $code = 302)
 {
     Base::getLog()->debug(__METHOD__ . ' redirect from controller', ['uri' => $uri, 'code' => $code]);
     Base::getHttp()->redirect((string) $uri, $code);
 }
Example #4
0
<?php

use tourze\Base\Base;
Base::getHttp()->setCookie(date('Y-m-d-H-i-s'), microtime(true));
?>
<pre><?php 
print_r($_COOKIE);
?>
</pre>

Example #5
0
<?php

use tourze\Base\Base;
Base::getHttp()->header('Content-Type: application/json');
tourze\Server\Patch\register_shutdown_function(function () {
    echo microtime(true);
});
Example #6
0
<?php

use tourze\Base\Base;
Base::getHttp()->header('Content-Type: text/html');
$str = date('Y-m-d H:i:s');
Base::getSession()->set(date('Y-m-d-H-i'), $str);
echo Base::getSession()->get(date('Y-m-d-H-i'));
echo "<br/>";
echo Base::getSession()->id();
echo "<pre>";
var_dump($_SESSION);
echo "</pre>";
//\tourze\Base\Base::getSession()->destroy();
//Base::getHttp()->end('end.');
Example #7
0
 /**
  * 通过HTTP发送文件,达到下载文件的效果
  *
  *      // 下载一个已经存在的文件
  *      $response->sendFile('media/packages/package.zip');
  *
  *      // 将返回内容当做是下载处理:
  *      $response->body = $content;
  *      $response->sendFile(true, $filename);
  *
  * @param  string $filename 文件名、文件路径,如果设置为`true`则返回当前的response内容
  * @param  string $download 下载文件名,默认为当前要处理的文件名
  * @param  array  $options  其他选项
  * @throws BaseException
  */
 public function sendFile($filename, $download = null, array $options = null)
 {
     // 强制指定了mime
     if (!empty($options['mime_type'])) {
         $mime = $options['mime_type'];
     }
     // 返回当前的响应内容,作为本次下载
     if (true === $filename) {
         if (empty($download)) {
             throw new BaseException('Download name must be provided for streaming files');
         }
         $options['delete'] = false;
         if (!isset($mime)) {
             // 根据扩展名,获取指定的mime类型
             $mime = Mime::getMimeFromExtension(strtolower(pathinfo($download, PATHINFO_EXTENSION)));
         }
         // 将响应内容保存到临时文件
         $fileData = (string) $this->message->body;
         $size = strlen($fileData);
         $file = tmpfile();
         fwrite($file, $fileData);
         unset($fileData);
     } else {
         $filename = realpath($filename);
         if (empty($download)) {
             $download = pathinfo($filename, PATHINFO_BASENAME);
         }
         $size = filesize($filename);
         if (!isset($mime)) {
             $mime = Mime::getMimeFromExtension(pathinfo($download, PATHINFO_EXTENSION));
         }
         $file = fopen($filename, 'rb');
     }
     if (!is_resource($file)) {
         throw new BaseException('Could not read file to send: :file', [':file' => $download]);
     }
     // inline和attachment的区别,主要在于浏览器遇到inline类型的下载时,会尝试直接在浏览器打开,而attachment则不会
     $disposition = Arr::get($options, 'inline') ? 'inline' : 'attachment';
     $temp = $this->_calculateByteRange($size);
     $start = array_shift($temp);
     $end = array_shift($temp);
     if (!empty($options['resumable'])) {
         if ($start > 0 || $end < $size - 1) {
             // Partial Content
             $this->status = 206;
         }
         $this->headers('content-range', 'bytes ' . $start . '-' . $end . '/' . $size);
         $this->headers('accept-ranges', 'bytes');
     }
     $this->headers('content-disposition', $disposition . '; filename="' . $download . '"');
     $this->headers('content-type', $mime);
     $this->headers('content-length', (string) ($end - $start + 1));
     $this->sendHeaders();
     // @notice 此方法在cli环境下可能无效
     while (ob_get_level()) {
         ob_end_flush();
     }
     ignore_user_abort(true);
     $prevTimeLimit = ini_get('max_execution_time');
     @set_time_limit(0);
     // 16K
     $block = 1024 * 16;
     fseek($file, $start);
     while (!feof($file) && ($pos = ftell($file)) <= $end) {
         if (connection_aborted()) {
             break;
         }
         if ($pos + $block > $end) {
             $block = $end - $pos + 1;
         }
         echo fread($file, $block);
         flush();
     }
     fclose($file);
     if (!empty($options['delete'])) {
         try {
             unlink($filename);
         } catch (Exception $e) {
             Base::getLog()->error($e->getMessage(), ['code' => $e->getCode()]);
         }
     }
     // 停止执行
     @set_time_limit($prevTimeLimit);
     Base::getHttp()->end();
 }
Example #8
0
 /**
  * header函数的补丁
  *
  * @param string    $string
  * @param bool|true $replace
  * @param null      $httpResponseCode
  */
 function header($string, $replace = true, $httpResponseCode = null)
 {
     Base::getHttp()->header($string, $replace, $httpResponseCode);
 }
Example #9
0
 /**
  * {@inheritdoc}
  */
 public function start()
 {
     Base::getLog()->debug(__METHOD__ . ' session start');
     Base::getHttp()->sessionStart();
 }
Example #10
0
 /**
  * 删除指定的cookie
  *
  *     Cookie::delete('theme');
  *
  * @param  string $name cookie名
  * @return bool
  */
 public static function delete($name)
 {
     unset($_COOKIE[$name]);
     return Base::getHttp()->setCookie($name, null, -86400, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httpOnly);
 }