All Projects → naka1205 → phpkoa

naka1205 / phpkoa

Licence: MIT license
PHP异步编程: 基于 PHP 实(chao)现(xi) NODEJS web框架 KOA。

Programming Languages

PHP
23972 projects - #3 most used programming language
HTML
75241 projects
CSS
56736 projects

Projects that are alternatives of or similar to phpkoa

Kvantum
An intellectual (HTTP/HTTPS) web server with support for server side templating (Crush, Apache Velocity and JTwig)
Stars: ✭ 17 (-67.31%)
Mutual labels:  webserver, http-server, https-server
Beetlex
high performance dotnet core socket tcp communication components, support TLS, HTTP, HTTPS, WebSocket, RPC, Redis protocols, custom protocols and 1M connections problem solution
Stars: ✭ 802 (+1442.31%)
Mutual labels:  socket, webserver, http-server
T Io
解决其它网络框架没有解决的用户痛点,让天下没有难开发的网络程序
Stars: ✭ 1,331 (+2459.62%)
Mutual labels:  socket, http-server
EthernetWebServer SSL
Simple TLS/SSL Ethernet WebServer, HTTP Client and WebSocket Client library for for AVR, Portenta_H7, Teensy, SAM DUE, SAMD21, SAMD51, STM32F/L/H/G/WB/MP1, nRF52 and RASPBERRY_PI_PICO boards using Ethernet shields W5100, W5200, W5500, ENC28J60 or Teensy 4.1 NativeEthernet/QNEthernet. It now supports Ethernet TLS/SSL Client. The library supports …
Stars: ✭ 40 (-23.08%)
Mutual labels:  webserver, http-server
Crow
A Fast and Easy to use microframework for the web.
Stars: ✭ 1,718 (+3203.85%)
Mutual labels:  webserver, http-server
Saea
SAEA.Socket is a high-performance IOCP framework TCP based on dotnet standard 2.0; Src contains its application test scenarios, such as websocket,rpc, redis driver, MVC WebAPI, lightweight message server, ultra large file transmission, etc. SAEA.Socket是一个高性能IOCP框架的 TCP,基于dotnet standard 2.0;Src中含有其应用测试场景,例如websocket、rpc、redis驱动、MVC WebAPI、轻量级消息服务器、超大文件传输等
Stars: ✭ 318 (+511.54%)
Mutual labels:  socket, webserver
PuppyProxy
A simple HTTP proxy in C# including support for HTTP CONNECT tunneling
Stars: ✭ 37 (-28.85%)
Mutual labels:  http-server, https-server
Owasp Mth3l3m3nt Framework
OWASP Mth3l3m3nt Framework is a penetration testing aiding tool and exploitation framework. It fosters a principle of attack the web using the web as well as pentest on the go through its responsive interface.
Stars: ✭ 139 (+167.31%)
Mutual labels:  socket, webserver
wine
A lightweight and flexible framework to help build elegant web API
Stars: ✭ 39 (-25%)
Mutual labels:  webserver, http-server
HttpServerLite
TCP-based simple HTTP and HTTPS server, written in C#.
Stars: ✭ 44 (-15.38%)
Mutual labels:  webserver, http-server
Jarvis
APL-based web service framework supporting JSON or REST
Stars: ✭ 17 (-67.31%)
Mutual labels:  webserver, http-server
Router.cr
Minimum High Performance Middleware for Crystal Web Server.
Stars: ✭ 231 (+344.23%)
Mutual labels:  webserver, http-server
Criollo
A powerful Cocoa web framework and HTTP server for macOS, iOS and tvOS.
Stars: ✭ 229 (+340.38%)
Mutual labels:  webserver, http-server
Tinywebserver
🔥 Linux下C++轻量级Web服务器
Stars: ✭ 4,720 (+8976.92%)
Mutual labels:  webserver, http-server
tracetrout
A magical reverse traceroute HTTP(S) server
Stars: ✭ 48 (-7.69%)
Mutual labels:  http-server, https-server
Fiery
A flexible and lightweight web server
Stars: ✭ 203 (+290.38%)
Mutual labels:  webserver, http-server
Rayo.js
Micro framework for Node.js
Stars: ✭ 170 (+226.92%)
Mutual labels:  webserver, http-server
Elli
Simple, robust and performant Erlang web server
Stars: ✭ 194 (+273.08%)
Mutual labels:  webserver, http-server
easy-shell
A pure Python script to easily get a reverse shell
Stars: ✭ 48 (-7.69%)
Mutual labels:  socket, webserver
khudro
Khudro is a very light weight web-server built with C.
Stars: ✭ 19 (-63.46%)
Mutual labels:  socket, webserver

PHPKoa

Latest Stable Version Total Downloads License

PHP异步编程: 基于 PHP 实(chao)现(xi) NODEJS web框架 KOA

说明

偶然间在 GITHUB 上看到有赞官方仓库的 手把手教你实现co与Koa 。由于此前用过 KOA ,对于 KOA 的洋葱模型叹为观止。不由得心血来潮的看完了整个文档,接着 CTRL+CCTRL+V 让代码跑了起来。 文档中是基于 swoole 扩展进行开发,而 swooleWINDOWS 并不友好,向来习惯在 WINDOWS 下开发的我一鼓作气,将Workerman 改写并兼容了此项目。

体验

  1. PHPKoa Demo 是使用 PHPKoa 开发 HTTP SERVER 的一个简单示例!
  2. PHP Krpano PHP 全景图片生成!
  3. PKBook 静态博客发布程序!
  4. H5Make H5编辑器!

建议

欢迎各位大神提交issues

安装

composer require naka1205/phpkoa

使用

Hello World

<?php
require __DIR__ . '/vendor/autoload.php';

use Naka507\Koa\Application;
use Naka507\Koa\Context;

$app = new Application();

$app->υse(function(Context $ctx) {
    $ctx->status = 200;
    $ctx->body = "<h1>Hello World</h1>";
});

$app->listen(3000,function(){
    echo "PHPKoa is listening in 3000\n";
});

Error

<?php
require __DIR__ . '/vendor/autoload.php';

use Naka507\Koa\Application;
use Naka507\Koa\Context;
use Naka507\Koa\Error;
use Naka507\Koa\Timeout;
use Naka507\Koa\Router;
use Naka507\Koa\NotFound;

$app = new Application();

$app->υse(new Error());
$app->υse(new NotFound());
$app->υse(new Timeout(3)); //设置3秒超时

$router = new Router();

//正常访问
$router->get('/hello', function(Context $ctx, $next) {
    $ctx->status = 200;
    $ctx->body = "<h1>Hello World</h1>";
});

//访问超时
$router->get('/timeout', function(Context $ctx, $next) {
    yield async_sleep(5);
});

//访问出错
$router->get('/error', function(Context $ctx, $next) {
    $ctx->thrοw(500, "Internal Error");
    yield;
});

$app->υse($router->routes());

$app->listen(3000);

Router

<?php
require __DIR__ . '/vendor/autoload.php';

define('DS', DIRECTORY_SEPARATOR);

use Naka507\Koa\Application;
use Naka507\Koa\Context;
use Naka507\Koa\Error;
use Naka507\Koa\Timeout;
use Naka507\Koa\Router;

$app = new Application();
$app->υse(new Error());
$app->υse(new Timeout(5));

$router = new Router();
$router->get('/demo1', function(Context $ctx, $next) {
    $ctx->body = "demo1";
});
$router->get('/demo2', function(Context $ctx, $next) {
    $ctx->body = "demo2";
});
$router->get('/demo3/(\d+)', function(Context $ctx, $next, $vars) {
    $ctx->status = 200;
    $ctx->body = "demo3={$vars[0]}";
});
$router->get('/demo4', function(Context $ctx, $next) {
    $ctx->redirect("/demo2");
});

//RESTful API
$router->post('/demo3/(\d+)', function(Context $ctx, $next, $vars) {
    //设置 session
    $ctx->setSession('demo3',$vars[0]);
    //设置 cookie
    $ctx->setCookie('demo3',$vars[0]);
    $ctx->status = 200;
    $ctx->body = "post:demo3={$vars[0]}";
});
$router->put('/demo3/(\d+)', function(Context $ctx, $next, $vars) {

    //获取单个 cookie
    $cookie_demo3 = $ctx->getCookie('demo3');
    //或者
    $cookies = $ctx->cookies['demo3'];

    //获取单个 session
    $session_demo3 = $ctx->getSession('demo3');
    //或者
    $session = $ctx->session['demo3'];

    $ctx->status = 200;
    $ctx->body = "put:demo3={$vars[0]}";
});
$router->delete('/demo3/(\d+)', function(Context $ctx, $next, $vars) {
    //清除所有 cookie
    $ctx->clearCookie();
    //清除所有 session
    $ctx->clearSession();
    $ctx->status = 200;
    $ctx->body = "delete:demo3={$vars[0]}";
});

//文件上传
$router->post('/files/(\d+)', function(Context $ctx, $next, $vars) {
    $upload_path = __DIR__ . DS .  "uploads" . DS;
    if ( !is_dir($upload_path) ) {
        mkdir ($upload_path , 0777, true);
    }
    $files = [];
    foreach ( $ctx->request->files as $key => $value) {
        if ( !$value['file_name'] || !$value['file_data'] ) {
            continue;
        }
        $file_path = $upload_path . $value['file_name'];
        file_put_contents($file_path, $value['file_data']);
        $value['file_path'] = $file_path;
        $files[] = $value;
    }

    $ctx->status = 200;
    $ctx->body = json_encode($files);
});


$app->υse($router->routes());

$app->listen(3000);
<?php
//此处已省略 ... 

//使用第三方 HTTP 客户端类库,方便测试
use GuzzleHttp\Client;

$router = new Router();

//路由分组 
//http://127.0.0.1:5000/curl/get
//http://127.0.0.1:5000/curl/post
//http://127.0.0.1:5000/curl/put
//http://127.0.0.1:5000/curl/delete
$router->mount('/curl', function() use ($router) {
    $client = new Client();
    $router->get('/get', function( Context $ctx, $next ) use ($client) {
        $r = (yield $client->request('GET', 'http://127.0.0.1:3000/demo3/1'));
        $ctx->status = $r->getStatusCode();
        $ctx->body = $r->getBody();
    });

    $router->get('/post', function(Context $ctx, $next ) use ($client){
        $r = (yield $client->request('POST', 'http://127.0.0.1:3000/demo3/2'));
        $ctx->status = $r->getStatusCode();
        $ctx->body = $r->getBody();
    });

    $router->get('/put', function( Context $ctx, $next ) use ($client){
        $r = (yield $client->request('PUT', 'http://127.0.0.1:3000/demo3/3'));
        $ctx->status = $r->getStatusCode();
        $ctx->body = $r->getBody();
    });

    $router->get('/delete', function( Context $ctx, $next ) use ($client){
        $r = (yield $client->request('DELETE', 'http://127.0.0.1:3000/demo3/4'));
        $ctx->status = $r->getStatusCode();
        $ctx->body = $r->getBody();
    });
});

//http://127.0.0.1:5000/files
$router->get('/files', function(Context $ctx, $next ) {
    $client = new Client();
    $r = ( yield $client->request('POST', 'http://127.0.0.1:3000/files/2', [
        'multipart' => [
            [
                'name'     => 'file_name',
                'contents' => fopen( __DIR__ . '/file.txt', 'r')
            ],
            [
                'name'     => 'other_file',
                'contents' => 'hello',
                'filename' => 'filename.txt',
                'headers'  => [
                    'X-Foo' => 'this is an extra header to include'
                ]
            ]
        ]
    ]));
    
    $ctx->status = $r->getStatusCode();
    $ctx->body = $r->getBody();
});

// $router->get('/curl/(\w+)', function(Context $ctx, $next, $vars) {
//     $method = strtoupper($vars[0]);
//     $client = new Client();
//     $r = (yield $client->request($method, 'http://127.0.0.1:3000/demo3/123'));
//     $ctx->status = $r->getStatusCode();
//     $ctx->body = $r->getBody();
// });

$app->υse($router->routes());
$app->listen(5000);

Template

<body>
    <h1>{title}</h1>
    <p>{time}</p>
</body>
<?php
require __DIR__ . '/vendor/autoload.php';

use Naka507\Koa\Application;
use Naka507\Koa\Context;
use Naka507\Koa\Error;
use Naka507\Koa\Timeout;
use Naka507\Koa\Router;

$app = new Application();
$app->υse(new Error());
$app->υse(new Timeout(5));

$router = new Router();
$router->get('/hello', function(Context $ctx) {
    $ctx->status = 200;
    $ctx->state["title"] = "HELLO WORLD";
    $ctx->state["time"] = date("Y-m-d H:i:s", time());;
    yield $ctx->render(__DIR__ . "/hello.html");
});
$app->υse($router->routes());

$app->listen(3000);
<body>
    <p>{title}</p>
    <table border=1>
      <tr><td>Name</td><td>Age</td></tr>
  
      <!-- BEGIN INFO -->
      <tr>
        <td> {name} </td>
        <td> {age} </td>
      </tr>
      <!-- END INFO -->
  
    </table>
</body>
<?php
//此处已省略 ... 

//一维数组
$router->get('/info', function(Context $ctx) {
    $info = array("name" => "小明", "age" => 15);
    $ctx->status = 200;
    $ctx->state["title"] = "这是一个学生信息";
    $ctx->state["info"] = $info;
    yield $ctx->render(__DIR__ . "/info.html");
});
<body>
    <p>{title}</p>
    <table border=1>
      <tr><td>Name</td><td>Age</td></tr>
  
      <!-- BEGIN TABLE -->
      <tr>
        <td> {name} </td>
        <td> {age} </td>
      </tr>
      <!-- END TABLE -->
  
    </table>
</body>
<?php
//此处已省略 ... 

//二维数组
$router->get('/table', function(Context $ctx) {
    $table = array(
        array("name" => "小明", "age" => 15),
        array("name" => "小花", "age" => 13),
        array("name" => "小刚", "age" => 17)
    );
    $ctx->status = 200;
    $ctx->state["title"] = "这是一个学生名单";
    $ctx->state["table"] = $table;
    yield $ctx->render(__DIR__ . "/table.html");
});

中间件

静态文件处理 中间件 PHPKoa Static

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PHPkoa Static</title>
    <link rel="stylesheet" href="/css/default.css">
</head>
<body>
    <img src="/images/20264902.jpg" />
</body>
</html>
<?php
require __DIR__ . '/vendor/autoload.php';

defined('DS') or define('DS', DIRECTORY_SEPARATOR);

use Naka507\Koa\Application;
use Naka507\Koa\Context;
use Naka507\Koa\Error;
use Naka507\Koa\Timeout;
use Naka507\Koa\NotFound;
use Naka507\Koa\Router;
//静态文件处理 中间件
use Naka507\Koa\StaticFiles; 

$app = new Application();
$app->υse(new Error());
$app->υse(new Timeout(5));
$app->υse(new NotFound()); 
$app->υse(new StaticFiles(__DIR__ . DS .  "static" )); 

$router = new Router();

$router->get('/index', function(Context $ctx, $next) {
    $ctx->status = 200;
    yield $ctx->render(__DIR__ . "/index.html");
});

$app->υse($router->routes());

$app->listen(3000);

使用 第三方ORM

composer require topthink/think-orm

创建 MYSQL 数据表

CREATE TABLE `too_user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `account` varchar(64) NOT NULL DEFAULT '' COMMENT '账号',
  `password` char(32) NOT NULL DEFAULT '' COMMENT '登录密码',
  `nickname` varchar(32) NOT NULL DEFAULT '' COMMENT '用户昵称',
  `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态',
  `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
  `update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

自定义数据模型

<?php
namespace Models;
use think\Model;
class User extends Model
{
}

自定义 JSON响应 中间件 中间件会根据是否存在数据 响应不同的数据 并进行JSON格式化

<?php
namespace Middlewares;
use Naka507\Koa\Middleware;
use Naka507\Koa\Context;
class BodyJson implements Middleware
{
    public function __construct(){
    }
    public function __invoke(Context $ctx, $next){
        yield $next;
        $pos = strpos($ctx->accept,'json');
        if ( $pos !== false ) {
            $ctx->type = 'application/json';
            $result = [ "code" => 0,  "msg" => '操作失败'];
            $data = $ctx->body;
            if ( $data ) {
                $result['code'] = 200;
                $result['msg'] = '操作成功';
                $result['data'] = $data;
            }
            $ctx->body = json_encode( $result );
        }

    }
}

动态模板 使用JQ 进行AJAX 请求

<body>
    <h1>/api/user/{id}</h1>
    <p id="user"></p>
</body>
<script type="text/javascript">
var id = {id};
$.ajax({
    type: "GET",
    url: "/api/user/" + id,
    dataType: "json",
    success: function(res){
        if( res.code == 200 ){
            $("#user").html(JSON.stringify(res.data))
        }else{
            $("#user").html(res.msg)
        }
        
    }
});
</script>
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].