first commit

This commit is contained in:
2022-07-06 10:00:16 +08:00
committed by jhx
commit 54e265dd61
56 changed files with 7491 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
/.idea
/.vscode
/vendor
*.log
.env
/tests/tmp
/tests/.phpunit.result.cache
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 walkor<walkor@workerman.net> and contributors (see https://github.com/walkor/webman/contributors)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+1
View File
@@ -0,0 +1 @@
ipcheck
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace app\controller;
use itbdw\Ip\IpLocation;
use support\Request;
class Index
{
public function index(Request $request)
{
$ip = $request->getRealIp();
$location = IpLocation::getLocation($ip);
return json(['ip' => $ip, 'location' => $location]);
}
}
+4
View File
@@ -0,0 +1,4 @@
<?php
/**
* Here is your custom functions.
*/
+42
View File
@@ -0,0 +1,42 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace app\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
/**
* Class StaticFile
* @package app\middleware
*/
class StaticFile implements MiddlewareInterface
{
public function process(Request $request, callable $next): Response
{
// Access to files beginning with. Is prohibited
if (strpos($request->path(), '/.') !== false) {
return response('<h1>403 forbidden</h1>', 403);
}
/** @var Response $response */
$response = $next($request);
// Add cross domain HTTP header
/*$response->withHeaders([
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Credentials' => 'true',
]);*/
return $response;
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace app\model;
use support\Model;
class Test extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'test';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
}
+14
View File
@@ -0,0 +1,14 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="/favicon.ico"/>
<title>webman</title>
</head>
<body>
hello <?=htmlspecialchars($name)?>
</body>
</html>
+55
View File
@@ -0,0 +1,55 @@
{
"name": "workerman/webman",
"type": "project",
"keywords": [
"high performance",
"http service"
],
"homepage": "http://www.workerman.net",
"license": "MIT",
"description": "High performance HTTP Service Framework.",
"authors": [
{
"name": "walkor",
"email": "walkor@workerman.net",
"homepage": "http://www.workerman.net",
"role": "Developer"
}
],
"support": {
"email": "walkor@workerman.net",
"issues": "https://github.com/walkor/webman/issues",
"forum": "http://wenda.workerman.net/",
"wiki": "http://workerman.net/doc/webman",
"source": "https://github.com/walkor/webman"
},
"require": {
"php": ">=7.2",
"workerman/webman-framework": "^1.3.14",
"monolog/monolog": "^2.0",
"itbdw/ip-database": "^3.0"
},
"suggest": {
"ext-event": "For better performance. "
},
"autoload": {
"psr-4": {
"": "./",
"App\\": "./app"
},
"files": [
"./support/helpers.php"
]
},
"scripts": {
"post-package-install": [
"support\\Plugin::install"
],
"post-package-update": [
"support\\Plugin::install"
],
"pre-package-uninstall": [
"support\\Plugin::uninstall"
]
}
}
Generated
+483
View File
@@ -0,0 +1,483 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "05019fd09e654743cacfa48bd34bd029",
"packages": [
{
"name": "itbdw/ip-database",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/itbdw/ip-database.git",
"reference": "1bcd17b78e8cd5366f068c4cdd19717ca52fe6f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/itbdw/ip-database/zipball/1bcd17b78e8cd5366f068c4cdd19717ca52fe6f6",
"reference": "1bcd17b78e8cd5366f068c4cdd19717ca52fe6f6",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-iconv": "*",
"ext-json": "*",
"ext-mbstring": "*",
"php": "~5.4|~7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"itbdw\\Ip\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "马秉尧"
},
{
"name": "itbdw",
"email": "itbudaoweng@gmail.com",
"homepage": "http://github.com/itbdw",
"role": "Developer"
}
],
"description": "IP位置数据库(解析为国家、省、市、县、运营商)",
"keywords": [
"China",
"Chinese",
"IP",
"database",
"location",
"位置",
"地区",
"数据库",
"纯真"
],
"support": {
"issues": "https://github.com/itbdw/ip-database/issues",
"source": "https://github.com/itbdw/ip-database/tree/3.0.0"
},
"funding": [
{
"url": "https://wx1.sinaimg.cn/large/6b94a2e5ly1gjoqqrkup8j20u00u0wh1.jpg",
"type": "custom"
}
],
"time": "2021-04-09T16:22:33+00:00"
},
{
"name": "monolog/monolog",
"version": "2.7.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "5579edf28aee1190a798bfa5be8bc16c563bd524"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/5579edf28aee1190a798bfa5be8bc16c563bd524",
"reference": "5579edf28aee1190a798bfa5be8bc16c563bd524",
"shasum": ""
},
"require": {
"php": ">=7.2",
"psr/log": "^1.0.1 || ^2.0 || ^3.0"
},
"provide": {
"psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
"doctrine/couchdb": "~1.0@dev",
"elasticsearch/elasticsearch": "^7 || ^8",
"ext-json": "*",
"graylog2/gelf-php": "^1.4.2",
"guzzlehttp/guzzle": "^7.4",
"guzzlehttp/psr7": "^2.2",
"mongodb/mongodb": "^1.8",
"php-amqplib/php-amqplib": "~2.4 || ^3",
"php-console/php-console": "^3.1.3",
"phpspec/prophecy": "^1.15",
"phpstan/phpstan": "^0.12.91",
"phpunit/phpunit": "^8.5.14",
"predis/predis": "^1.1",
"rollbar/rollbar": "^1.3 || ^2 || ^3",
"ruflin/elastica": "^7",
"swiftmailer/swiftmailer": "^5.3|^6.0",
"symfony/mailer": "^5.4 || ^6",
"symfony/mime": "^5.4 || ^6"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
"ext-mbstring": "Allow to work properly with unicode symbols",
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
"ext-openssl": "Required to send log messages using SSL",
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"php-console/php-console": "Allow sending log messages to Google Chrome",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "https://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "https://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
"source": "https://github.com/Seldaek/monolog/tree/2.7.0"
},
"funding": [
{
"url": "https://github.com/Seldaek",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
"type": "tidelift"
}
],
"time": "2022-06-09T08:59:12+00:00"
},
{
"name": "nikic/fast-route",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/FastRoute.git",
"reference": "181d480e08d9476e61381e04a71b34dc0432e812"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812",
"reference": "181d480e08d9476e61381e04a71b34dc0432e812",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35|~5.7"
},
"type": "library",
"autoload": {
"files": [
"src/functions.php"
],
"psr-4": {
"FastRoute\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Nikita Popov",
"email": "nikic@php.net"
}
],
"description": "Fast request router for PHP",
"keywords": [
"router",
"routing"
],
"support": {
"issues": "https://github.com/nikic/FastRoute/issues",
"source": "https://github.com/nikic/FastRoute/tree/master"
},
"time": "2018-02-13T20:26:39+00:00"
},
{
"name": "psr/container",
"version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
"shasum": ""
},
"require": {
"php": ">=7.4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
"source": "https://github.com/php-fig/container/tree/2.0.2"
},
"time": "2021-11-05T16:47:00+00:00"
},
{
"name": "psr/log",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/1.1.4"
},
"time": "2021-05-03T11:20:27+00:00"
},
{
"name": "workerman/webman-framework",
"version": "v1.3.19",
"source": {
"type": "git",
"url": "https://github.com/walkor/webman-framework.git",
"reference": "58d342cdde767e79313db45f35a80a13b18f71f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/walkor/webman-framework/zipball/58d342cdde767e79313db45f35a80a13b18f71f6",
"reference": "58d342cdde767e79313db45f35a80a13b18f71f6",
"shasum": ""
},
"require": {
"nikic/fast-route": "^1.3",
"php": ">=7.2",
"psr/container": ">=1.0",
"workerman/workerman": "^4.0.4"
},
"suggest": {
"ext-event": "For better performance. "
},
"type": "library",
"autoload": {
"psr-4": {
"Webman\\": "./src",
"Support\\": "./src/support",
"support\\": "./src/support",
"Support\\View\\": "./src/support/view",
"Support\\Bootstrap\\": "./src/support/bootstrap",
"Support\\Exception\\": "./src/support/exception"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "walkor",
"email": "walkor@workerman.net",
"homepage": "http://www.workerman.net",
"role": "Developer"
}
],
"description": "High performance HTTP Service Framework.",
"homepage": "http://www.workerman.net",
"keywords": [
"High Performance",
"http service"
],
"support": {
"email": "walkor@workerman.net",
"forum": "http://wenda.workerman.net/",
"issues": "https://github.com/walkor/webman/issues",
"source": "https://github.com/walkor/webman-framework",
"wiki": "http://doc.workerman.net/"
},
"funding": [
{
"url": "https://opencollective.com/walkor",
"type": "open_collective"
},
{
"url": "https://www.patreon.com/walkor",
"type": "patreon"
}
],
"time": "2022-06-30T15:10:24+00:00"
},
{
"name": "workerman/workerman",
"version": "v4.0.39",
"source": {
"type": "git",
"url": "https://github.com/walkor/workerman.git",
"reference": "97ff0d0d3d20ce9abfd0f3c87e5e3481d3bf16d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/walkor/workerman/zipball/97ff0d0d3d20ce9abfd0f3c87e5e3481d3bf16d9",
"reference": "97ff0d0d3d20ce9abfd0f3c87e5e3481d3bf16d9",
"shasum": ""
},
"require": {
"php": ">=5.4"
},
"suggest": {
"ext-event": "For better performance. "
},
"type": "library",
"autoload": {
"psr-4": {
"Workerman\\": "./"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "walkor",
"email": "walkor@workerman.net",
"homepage": "http://www.workerman.net",
"role": "Developer"
}
],
"description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
"homepage": "http://www.workerman.net",
"keywords": [
"asynchronous",
"event-loop"
],
"support": {
"email": "walkor@workerman.net",
"forum": "http://wenda.workerman.net/",
"issues": "https://github.com/walkor/workerman/issues",
"source": "https://github.com/walkor/workerman",
"wiki": "http://doc.workerman.net/"
},
"funding": [
{
"url": "https://opencollective.com/workerman",
"type": "open_collective"
},
{
"url": "https://www.patreon.com/walkor",
"type": "patreon"
}
],
"time": "2022-06-16T14:11:47+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=7.2"
},
"platform-dev": [],
"plugin-api-version": "2.3.0"
}
+24
View File
@@ -0,0 +1,24 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use support\Request;
return [
'debug' => true,
'default_timezone' => 'Asia/Shanghai',
'request_class' => Request::class,
'public_path' => base_path() . DIRECTORY_SEPARATOR . 'public',
'runtime_path' => base_path(false) . DIRECTORY_SEPARATOR . 'runtime',
'controller_suffix' => '',
];
+21
View File
@@ -0,0 +1,21 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
'files' => [
base_path() . '/app/functions.php',
base_path() . '/support/Request.php',
base_path() . '/support/Response.php',
]
];
+18
View File
@@ -0,0 +1,18 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
support\bootstrap\Session::class,
support\bootstrap\LaravelDb::class,
];
+15
View File
@@ -0,0 +1,15 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return new Webman\Container;
+15
View File
@@ -0,0 +1,15 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [];
+15
View File
@@ -0,0 +1,15 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [];
+17
View File
@@ -0,0 +1,17 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
'' => support\exception\Handler::class,
];
+32
View File
@@ -0,0 +1,32 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
'default' => [
'handlers' => [
[
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
runtime_path() . '/logs/webman.log',
7, //$maxFiles
Monolog\Logger::DEBUG,
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [null, 'Y-m-d H:i:s', true],
],
]
],
],
];
+15
View File
@@ -0,0 +1,15 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [];
+37
View File
@@ -0,0 +1,37 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
// File update detection and automatic reload
'monitor' => [
'handler' => process\Monitor::class,
'reloadable' => false,
'constructor' => [
// Monitor these directories
'monitor_dir' => [
app_path(),
config_path(),
base_path() . '/process',
base_path() . '/support',
base_path() . '/resource',
base_path() . '/.env',
],
// Files with these suffixes will be monitored
'monitor_extensions' => [
'php', 'html', 'htm', 'env'
]
]
]
];
+22
View File
@@ -0,0 +1,22 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
'default' => [
'host' => '127.0.0.1',
'password' => null,
'port' => 6379,
'database' => 0,
],
];
+23
View File
@@ -0,0 +1,23 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use Webman\Route;
Route::any('/', [\app\controller\Index::class, 'index']);
+31
View File
@@ -0,0 +1,31 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
'listen' => 'http://0.0.0.0:8000',
'transport' => 'tcp',
'context' => [],
'name' => 'webman',
'count' => cpu_count() * 2,
'user' => '',
'group' => '',
'reusePort' => false,
'event_loop' => '',
'stop_timeout' => 2,
'pid_file' => runtime_path() . '/webman.pid',
'status_file' => runtime_path() . '/webman.status',
'stdout_file' => runtime_path() . '/logs/stdout.log',
'log_file' => runtime_path() . '/logs/workerman.log',
'max_package_size' => 10 * 1024 * 1024
];
+61
View File
@@ -0,0 +1,61 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
'type' => 'file', // or redis or redis_cluster
'handler' => Webman\FileSessionHandler::class,
'config' => [
'file' => [
'save_path' => runtime_path() . '/sessions',
],
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'auth' => '',
'timeout' => 2,
'database' => '',
'prefix' => 'redis_session_',
],
'redis_cluster' => [
'host' => ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7001'],
'timeout' => 2,
'auth' => '',
'prefix' => 'redis_session_',
]
],
'session_name' => 'PHPSID',
'auto_update_timestamp' => false,
'lifetime' => 7*24*60*60,
'cookie_lifetime' => 365*24*60*60,
'cookie_path' => '/',
'domain' => '',
'http_only' => true,
'secure' => false,
'same_site' => '',
'gc_probability' => [1, 1000],
];
+23
View File
@@ -0,0 +1,23 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Static file settings
*/
return [
'enable' => true,
'middleware' => [ // Static file Middleware
//app\middleware\StaticFile::class,
],
];
+25
View File
@@ -0,0 +1,25 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Multilingual configuration
*/
return [
// Default language
'locale' => 'zh_CN',
// Fallback language
'fallback_locale' => ['zh_CN', 'en'],
// Folder where language files are stored
'path' => base_path() . '/resource/translations',
];
+22
View File
@@ -0,0 +1,22 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use support\view\Raw;
use support\view\Twig;
use support\view\Blade;
use support\view\ThinkPHP;
return [
'handler' => Raw::class
];
+4
View File
@@ -0,0 +1,4 @@
/data
/docker-compose.yaml
/redis/config
.env
+78
View File
@@ -0,0 +1,78 @@
FROM php:7.4-cli-alpine3.13
# Set working dir.
ARG CONTAINER_APP_DIR
WORKDIR ${CONTAINER_APP_DIR}
ARG timezone
ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \
APP_ENV=prod \
SCAN_CACHEABLE=(true)
# Change alpinelinux source.
# Reference: https://github.com/laradock/laradock
ARG CHANGE_AlPINE_SOURCE
ARG CONTAINER_PACKAGE_URL
RUN if [ $CHANGE_AlPINE_SOURCE ] ; then sed -i "s/dl-cdn.alpinelinux.org/${CONTAINER_PACKAGE_URL}/g" /etc/apk/repositories ; fi
RUN uname -a && \
apk update
RUN docker-php-ext-install sockets pcntl && \
docker-php-ext-install pdo_mysql
RUN apk add --no-cache pcre-dev $PHPIZE_DEPS && \
pecl install redis && \
docker-php-ext-enable redis
ARG INSTALL_LIB_EVENT
RUN if [ ${INSTALL_LIB_EVENT} = true ]; then \
apk add libevent-dev openssl-dev libressl-dev && \
pecl install event && \
echo extension=event.so > /usr/local/etc/php/conf.d/event.ini \
;fi
# update
RUN set -ex \
# show php version and extensions
&& php -v \
&& php -m \
# ---------- some config ----------
&& cd /usr/local/etc/php \
# - config PHP
&& { \
echo "upload_max_filesize=128M"; \
echo "post_max_size=128M"; \
echo "memory_limit=1G"; \
echo "date.timezone=${TIMEZONE}"; \
} | tee conf.d/99_overrides.ini \
# - config timezone
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
&& echo "${TIMEZONE}" > /etc/timezone \
# ---------- clear works ----------
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man \
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
# Install composer and set mirror.
# Reference: https://pkg.phpcomposer.com/#how-to-install-composer
# Referencr: https://developer.aliyun.com/composer
ARG INSTALL_COMPOSER
ARG COMPOSER_INSTALLER
ARG COMPOSER_MIRROR
RUN if [ ${INSTALL_COMPOSER} = true ]; then \
php -r "copy('${COMPOSER_INSTALLER}', 'composer-setup.php');" && \
php composer-setup.php && \
php -r "unlink('composer-setup.php');" && \
mv composer.phar /usr/local/bin/composer && \
composer config -g repo.packagist composer ${COMPOSER_MIRROR} \
;fi
RUN apk add git zip vim bash
RUN apk add openssh
# Expose port
ARG CONTAINER_PORT
EXPOSE ${CONTAINER_PORT}
+24
View File
@@ -0,0 +1,24 @@
# Set environment variables
Copy file **env-example** to **.env**, and change the item what you need.
Change the **HOST_APP_DIR** env item, ensure where your webman app is.
# Build image
Ensure you have install docker and docker-compose first.
You can build you image by execute follow command:
> **docker-compose up -d webman**
# Run
Enter the container:
> **docker-compose exec webman bash**
If you havn't init composer, you can run this command:
> **composer install**
Run in front:
> **php start.php start**
Run in backend:
> **php start.php start -d**
+52
View File
@@ -0,0 +1,52 @@
version: '3'
services:
machine_server:
build:
context: ./
args:
- CONTAINER_PORT=${CONTAINER_PORT}
- CONTAINER_APP_DIR=${CONTAINER_APP_DIR}
- INSTALL_COMPOSER=${INSTALL_COMPOSER}
- COMPOSER_INSTALLER=${COMPOSER_INSTALLER}
- COMPOSER_MIRROR=${COMPOSER_MIRROR}
- INSTALL_LIB_EVENT=${INSTALL_LIB_EVENT}
- CONTAINER_PACKAGE_URL=${CONTAINER_PACKAGE_URL}
- CHANGE_AlPINE_SOURCE=${CHANGE_AlPINE_SOURCE}
ports:
- "${HOST_PORT_1}:${CONTAINER_PORT_1}"
- "${HOST_PORT_2}:${CONTAINER_PORT_2}"
volumes:
- ${HOST_APP_DIR}:${CONTAINER_APP_DIR}
- ./id_rsa:/root/.ssh/id_rsa:ro
- ./known_hosts:/root/.ssh/known_hosts:ro
container_name: ${CONTAINER_NAME}
stdin_open: true
tty: true
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- machine_network
#restart: always
#entrypoint: [ "php", "/usr/src/myapp/main.php", "start" ]
machine_redis_server:
build:
context: ./redis
args:
REDIS_VERSION: ${REDIS_VERSION}
container_name: ${CONTAINER_NAME}-redis
ports:
- "${REDIS_HOST_PORT}:6379"
volumes:
- ${REDIS_CONF_FILE}:/etc/redis.conf:ro
- ${DATA_DIR}/redis:/data/:rw
restart: always
entrypoint: [ "redis-server", "/etc/redis.conf" ]
environment:
TZ: "$TZ"
networks:
- machine_network
networks:
machine_network:
+37
View File
@@ -0,0 +1,37 @@
# base
CONTAINER_NAME=center
# port
HOST_PORT_1=8000
CONTAINER_PORT_1=8000
HOST_PORT_2=3000
CONTAINER_PORT_2=3000
REDIS_HOST_PORT=63790
### set local app dir there #######
HOST_APP_DIR=../
CONTAINER_APP_DIR=/usr/src/myapp
INSTALL_COMPOSER=true
COMPOSER_INSTALLER=https://install.phpcomposer.com/installer
COMPOSER_MIRROR=https://mirrors.aliyun.com/composer/
INSTALL_LIB_EVENT=true
CHANGE_AlPINE_SOURCE=true
CONTAINER_PACKAGE_URL=mirrors.aliyun.com
DATA_DIR=./data
#
# Container Timezone
#
TZ=Asia/Shanghai
# redis
REDIS_VERSION=6.2-alpine
REDIS_CONF_FILE=./redis/config/redis-6.conf
#apidoc
APIDOC_HOST_PORT=4000
APIDOC_NGINX_CONFD_DIR=./apidoc/nginx/conf.d
Binary file not shown.
+38
View File
@@ -0,0 +1,38 @@
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
+1
View File
@@ -0,0 +1 @@
gitee.com,180.97.125.228 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMuEoYdx6to5oxR60IWj8uoe1aI0X1fKOHWOtLqTg1tsLT1iFwXV5JmFjU46EzeMBV/6EmI1uaRI6HiEPtPtJHE=
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
config
+3
View File
@@ -0,0 +1,3 @@
ARG REDIS_VERSION
FROM redis:${REDIS_VERSION}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
#!/bin/bash
# Reference: https://github.com/laradock/laradock
set -xe;
if type "tee" 2>/dev/null && [ -n "${UBUNTU_SOURCE}" ]; then
SOURCE_PATH="/etc/apt/sources.list"
cp ${SOURCE_PATH} ${SOURCE_PATH}.bak && rm -rf ${SOURCE_PATH}
case "${UBUNTU_SOURCE}" in
"aliyun")
tee ${SOURCE_PATH} <<-'EOF'
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
EOF
;;
"tsinghua")
tee ${SOURCE_PATH} <<-'EOF'
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
EOF
;;
*)
echo "There is no ubuntu source detected!"
exit 1;;
esac
fi
+195
View File
@@ -0,0 +1,195 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace process;
use Workerman\Timer;
use Workerman\Worker;
/**
* Class FileMonitor
* @package process
*/
class Monitor
{
/**
* @var array
*/
protected $_paths = [];
/**
* @var array
*/
protected $_extensions = [];
/**
* FileMonitor constructor.
* @param $monitor_dir
* @param $monitor_extensions
* @param $memory_limit
*/
public function __construct($monitor_dir, $monitor_extensions, $memory_limit = null)
{
$this->_paths = (array)$monitor_dir;
$this->_extensions = $monitor_extensions;
if (!Worker::getAllWorkers()) {
return;
}
$disable_functions = explode(',', ini_get('disable_functions'));
if (in_array('exec', $disable_functions, true)) {
echo "\nMonitor file change turned off because exec() has been disabled by disable_functions setting in " . PHP_CONFIG_FILE_PATH . "/php.ini\n";
} else {
if (!Worker::$daemonize) {
Timer::add(1, function () {
$this->checkAllFilesChange();
});
}
}
$memory_limit = $this->getMemoryLimit($memory_limit);
if ($memory_limit && DIRECTORY_SEPARATOR === '/') {
Timer::add(60, [$this, 'checkMemory'], [$memory_limit]);
}
}
/**
* @param $monitor_dir
*/
public function checkFilesChange($monitor_dir)
{
static $last_mtime, $too_many_files_check;
if (!$last_mtime) {
$last_mtime = time();
}
clearstatcache();
if (!is_dir($monitor_dir)) {
if (!is_file($monitor_dir)) {
return;
}
$iterator = [new \SplFileInfo($monitor_dir)];
} else {
// recursive traversal directory
$dir_iterator = new \RecursiveDirectoryIterator($monitor_dir, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS);
$iterator = new \RecursiveIteratorIterator($dir_iterator);
}
$count = 0;
foreach ($iterator as $file) {
$count ++;
/** var SplFileInfo $file */
if (is_dir($file)) {
continue;
}
// check mtime
if ($last_mtime < $file->getMTime() && in_array($file->getExtension(), $this->_extensions, true)) {
$var = 0;
exec(PHP_BINARY . " -l " . $file, $out, $var);
if ($var) {
$last_mtime = $file->getMTime();
continue;
}
$last_mtime = $file->getMTime();
echo $file . " update and reload\n";
// send SIGUSR1 signal to master process for reload
if (DIRECTORY_SEPARATOR === '/') {
posix_kill(posix_getppid(), SIGUSR1);
} else {
return true;
}
break;
}
}
if (!$too_many_files_check && $count > 1000) {
echo "Monitor: There are too many files ($count files) in $monitor_dir which makes file monitoring very slow\n";
$too_many_files_check = 1;
}
}
/**
* @return bool
*/
public function checkAllFilesChange()
{
foreach ($this->_paths as $path) {
if ($this->checkFilesChange($path)) {
return true;
}
}
return false;
}
/**
* @param $memory_limit
* @return void
*/
public function checkMemory($memory_limit)
{
$ppid = posix_getppid();
$children_file = "/proc/$ppid/task/$ppid/children";
if (!is_file($children_file) || !($children = file_get_contents($children_file))) {
return;
}
foreach (explode(' ', $children) as $pid) {
$pid = (int)$pid;
$status_file = "/proc/$pid/status";
if (!is_file($status_file) || !($status = file_get_contents($status_file))) {
continue;
}
$mem = 0;
if (preg_match('/VmRSS\s*?:\s*?(\d+?)\s*?kB/', $status, $match)) {
$mem = $match[1];
}
$mem = (int)($mem / 1024);
if ($mem >= $memory_limit) {
posix_kill($pid, SIGINT);
}
}
}
/**
* Get memory limit
* @return float
*/
protected function getMemoryLimit($memory_limit)
{
if ($memory_limit === 0) {
return 0;
}
$use_php_ini = false;
if (!$memory_limit) {
$memory_limit = ini_get('memory_limit');
$use_php_ini = true;
}
if ($memory_limit == -1) {
return 0;
}
$unit = $memory_limit[strlen($memory_limit) - 1];
if ($unit == 'G') {
$memory_limit = 1024 * (int)$memory_limit;
} else if ($unit == 'M') {
$memory_limit = (int)$memory_limit;
} else if ($unit == 'K') {
$memory_limit = (int)($memory_limit / 1024);
} else {
$memory_limit = (int)($memory_limit / (1024 * 1024));
}
if ($memory_limit < 30) {
$memory_limit = 30;
}
if ($use_php_ini) {
$memory_limit = (int)(0.8 * $memory_limit);
}
return $memory_limit;
}
}
+12
View File
@@ -0,0 +1,12 @@
<html>
<head>
<title>404 Not Found - webman</title>
</head>
<body>
<center>
<h1>404 Not Found</h1>
</center>
<hr>
<center><a href="https://www.workerman.net">webman</a></center>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

+4
View File
@@ -0,0 +1,4 @@
*
!logs
!views
!.gitignore
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore
+117
View File
@@ -0,0 +1,117 @@
#!/usr/bin/env php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Protocols\Http;
use Workerman\Connection\TcpConnection;
use Webman\App;
use Webman\Config;
use Webman\Route;
use Webman\Middleware;
use Dotenv\Dotenv;
use support\Request;
use support\Log;
use support\Container;
ini_set('display_errors', 'on');
error_reporting(E_ALL);
if (class_exists('Dotenv\Dotenv') && file_exists(base_path() . '/.env')) {
if (method_exists('Dotenv\Dotenv', 'createUnsafeImmutable')) {
Dotenv::createUnsafeImmutable(base_path())->load();
} else {
Dotenv::createMutable(base_path())->load();
}
}
Config::load(config_path(), ['route', 'container']);
$error_reporting = config('app.error_reporting');
if (isset($error_reporting)) {
error_reporting($error_reporting);
}
if ($timezone = config('app.default_timezone')) {
date_default_timezone_set($timezone);
}
$runtime_logs_path = runtime_path() . DIRECTORY_SEPARATOR . 'logs';
if ( !file_exists($runtime_logs_path) || !is_dir($runtime_logs_path) ) {
if (!mkdir($runtime_logs_path,0777,true)) {
throw new \RuntimeException("Failed to create runtime logs directory. Please check the permission.");
}
}
$runtime_views_path = runtime_path() . DIRECTORY_SEPARATOR . 'views';
if ( !file_exists($runtime_views_path) || !is_dir($runtime_views_path) ) {
if (!mkdir($runtime_views_path,0777,true)) {
throw new \RuntimeException("Failed to create runtime views directory. Please check the permission.");
}
}
Worker::$onMasterReload = function () {
if (function_exists('opcache_get_status')) {
if ($status = opcache_get_status()) {
if (isset($status['scripts']) && $scripts = $status['scripts']) {
foreach (array_keys($scripts) as $file) {
opcache_invalidate($file, true);
}
}
}
}
};
$config = config('server');
Worker::$pidFile = $config['pid_file'];
Worker::$stdoutFile = $config['stdout_file'];
Worker::$logFile = $config['log_file'];
Worker::$eventLoopClass = $config['event_loop'] ?? '';
TcpConnection::$defaultMaxPackageSize = $config['max_package_size'] ?? 10 * 1024 * 1024;
if (property_exists(Worker::class, 'statusFile')) {
Worker::$statusFile = $config['status_file'] ?? '';
}
if (property_exists(Worker::class, 'stopTimeout')) {
Worker::$stopTimeout = $config['stop_timeout'] ?? 2;
}
if ($config['listen']) {
$worker = new Worker($config['listen'], $config['context']);
$property_map = [
'name',
'count',
'user',
'group',
'reusePort',
'transport',
'protocol'
];
foreach ($property_map as $property) {
if (isset($config[$property])) {
$worker->$property = $config[$property];
}
}
$worker->onWorkerStart = function ($worker) {
require_once base_path() . '/support/bootstrap.php';
$app = new App($worker, Container::instance(), Log::channel('default'), app_path(), public_path());
Http::requestClass(config('app.request_class', config('server.request_class', Request::class)));
$worker->onMessage = [$app, 'onMessage'];
};
}
// Windows does not support custom processes.
if (\DIRECTORY_SEPARATOR === '/') {
foreach (config('process', []) as $process_name => $config) {
worker_start($process_name, $config);
}
foreach (config('plugin', []) as $firm => $projects) {
foreach ($projects as $name => $project) {
foreach ($project['process'] ?? [] as $process_name => $config) {
worker_start("plugin.$firm.$name.$process_name", $config);
}
}
}
}
Worker::runAll();
+55
View File
@@ -0,0 +1,55 @@
<?php
namespace support;
class Plugin
{
public static function install($event)
{
static::findHepler();
$operation = $event->getOperation();
$autoload = method_exists($operation, 'getPackage') ? $operation->getPackage()->getAutoload() : $operation->getTargetPackage()->getAutoload();
if (!isset($autoload['psr-4'])) {
return;
}
$namespace = key($autoload['psr-4']);
$install_function = "\\{$namespace}Install::install";
$plugin_const = "\\{$namespace}Install::WEBMAN_PLUGIN";
if (defined($plugin_const) && is_callable($install_function)) {
$install_function();
}
}
public static function update($event)
{
static::install($event);
}
public static function uninstall($event)
{
static::findHepler();
$autoload = $event->getOperation()->getPackage()->getAutoload();
if (!isset($autoload['psr-4'])) {
return;
}
$namespace = key($autoload['psr-4']);
$uninstall_function = "\\{$namespace}Install::uninstall";
$plugin_const = "\\{$namespace}Install::WEBMAN_PLUGIN";
if (defined($plugin_const) && is_callable($uninstall_function)) {
$uninstall_function();
}
}
protected static function findHepler()
{
// Plugin.php in vendor
$file = __DIR__ . '/../../../../../support/helpers.php';
if (is_file($file)) {
require_once $file;
return;
}
// Plugin.php in webman
require_once __DIR__ . '/helpers.php';
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace support;
/**
* Class Request
* @package support
*/
class Request extends \Webman\Http\Request
{
}
+24
View File
@@ -0,0 +1,24 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace support;
/**
* Class Response
* @package support
*/
class Response extends \Webman\Http\Response
{
}
+90
View File
@@ -0,0 +1,90 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use Dotenv\Dotenv;
use support\Container;
use Webman\Config;
use Webman\Route;
use Webman\Middleware;
$worker = $worker ?? null;
if ($timezone = config('app.default_timezone')) {
date_default_timezone_set($timezone);
}
set_error_handler(function ($level, $message, $file = '', $line = 0, $context = []) {
if (error_reporting() & $level) {
throw new ErrorException($message, 0, $level, $file, $line);
}
});
if ($worker) {
register_shutdown_function(function ($start_time) {
if (time() - $start_time <= 1) {
sleep(1);
}
}, time());
}
if (class_exists('Dotenv\Dotenv') && file_exists(base_path() . '/.env')) {
if (method_exists('Dotenv\Dotenv', 'createUnsafeImmutable')) {
Dotenv::createUnsafeImmutable(base_path())->load();
} else {
Dotenv::createMutable(base_path())->load();
}
}
Config::reload(config_path(), ['route', 'container']);
foreach (config('plugin', []) as $firm => $projects) {
foreach ($projects as $name => $project) {
foreach ($project['autoload']['files'] ?? [] as $file) {
include_once $file;
}
}
}
foreach (config('autoload.files', []) as $file) {
include_once $file;
}
$container = Container::instance();
Route::container($container);
Middleware::container($container);
Middleware::load(config('middleware', []));
foreach (config('plugin', []) as $firm => $projects) {
foreach ($projects as $name => $project) {
Middleware::load($project['middleware'] ?? []);
}
}
Middleware::load(['__static__' => config('static.middleware', [])]);
foreach (config('bootstrap', []) as $class_name) {
/** @var \Webman\Bootstrap $class_name */
$class_name::start($worker);
}
foreach (config('plugin', []) as $firm => $projects) {
foreach ($projects as $name => $project) {
foreach ($project['bootstrap'] ?? [] as $class_name) {
/** @var \Webman\Bootstrap $class_name */
$class_name::start($worker);
}
}
}
Route::load(config_path());
+480
View File
@@ -0,0 +1,480 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use support\Request;
use support\Response;
use support\Translation;
use support\Container;
use support\view\Raw;
use support\view\Blade;
use support\view\ThinkPHP;
use support\view\Twig;
use Workerman\Worker;
use Webman\App;
use Webman\Config;
use Webman\Route;
// Phar support.
if (is_phar()) {
define('BASE_PATH', dirname(__DIR__));
} else {
define('BASE_PATH', realpath(__DIR__ . '/../'));
}
define('WEBMAN_VERSION', '1.3.0');
/**
* @param $return_phar
* @return false|string
*/
function base_path($return_phar = true)
{
static $real_path = '';
if (!$real_path) {
$real_path = is_phar() ? dirname(Phar::running(false)) : BASE_PATH;
}
return $return_phar ? BASE_PATH : $real_path;
}
/**
* @return string
*/
function app_path()
{
return BASE_PATH . DIRECTORY_SEPARATOR . 'app';
}
/**
* @return string
*/
function public_path()
{
static $path = '';
if (!$path) {
$path = config('app.public_path', BASE_PATH . DIRECTORY_SEPARATOR . 'public');
}
return $path;
}
/**
* @return string
*/
function config_path()
{
return BASE_PATH . DIRECTORY_SEPARATOR . 'config';
}
/**
* Phar support.
* Compatible with the 'realpath' function in the phar file.
*
* @return string
*/
function runtime_path()
{
static $path = '';
if (!$path) {
$path = config('app.runtime_path', BASE_PATH . DIRECTORY_SEPARATOR . 'runtime');
}
return $path;
}
/**
* @param int $status
* @param array $headers
* @param string $body
* @return Response
*/
function response($body = '', $status = 200, $headers = array())
{
return new Response($status, $headers, $body);
}
/**
* @param $data
* @param int $options
* @return Response
*/
function json($data, $options = JSON_UNESCAPED_UNICODE)
{
return new Response(200, ['Content-Type' => 'application/json'], json_encode($data, $options));
}
/**
* @param $xml
* @return Response
*/
function xml($xml)
{
if ($xml instanceof SimpleXMLElement) {
$xml = $xml->asXML();
}
return new Response(200, ['Content-Type' => 'text/xml'], $xml);
}
/**
* @param $data
* @param string $callback_name
* @return Response
*/
function jsonp($data, $callback_name = 'callback')
{
if (!is_scalar($data) && null !== $data) {
$data = json_encode($data);
}
return new Response(200, [], "$callback_name($data)");
}
/**
* @param $location
* @param int $status
* @param array $headers
* @return Response
*/
function redirect($location, $status = 302, $headers = [])
{
$response = new Response($status, ['Location' => $location]);
if (!empty($headers)) {
$response->withHeaders($headers);
}
return $response;
}
/**
* @param $template
* @param array $vars
* @param null $app
* @return Response
*/
function view($template, $vars = [], $app = null)
{
static $handler;
if (null === $handler) {
$handler = config('view.handler');
}
return new Response(200, [], $handler::render($template, $vars, $app));
}
/**
* @param $template
* @param array $vars
* @param null $app
* @return Response
*/
function raw_view($template, $vars = [], $app = null)
{
return new Response(200, [], Raw::render($template, $vars, $app));
}
/**
* @param $template
* @param array $vars
* @param null $app
* @return Response
*/
function blade_view($template, $vars = [], $app = null)
{
return new Response(200, [], Blade::render($template, $vars, $app));
}
/**
* @param $template
* @param array $vars
* @param null $app
* @return Response
*/
function think_view($template, $vars = [], $app = null)
{
return new Response(200, [], ThinkPHP::render($template, $vars, $app));
}
/**
* @param $template
* @param array $vars
* @param null $app
* @return Response
*/
function twig_view($template, $vars = [], $app = null)
{
return new Response(200, [], Twig::render($template, $vars, $app));
}
/**
* @return Request
*/
function request()
{
return App::request();
}
/**
* @param $key
* @param null $default
* @return mixed
*/
function config($key = null, $default = null)
{
return Config::get($key, $default);
}
/**
* @param $name
* @param ...$parameters
* @return string
*/
function route($name, ...$parameters)
{
$route = Route::getByName($name);
if (!$route) {
return '';
}
if (!$parameters) {
return $route->url();
}
if (is_array(current($parameters))) {
$parameters = current($parameters);
}
return $route->url($parameters);
}
/**
* @param mixed $key
* @param mixed $default
* @return mixed
*/
function session($key = null, $default = null)
{
$session = request()->session();
if (null === $key) {
return $session;
}
if (\is_array($key)) {
$session->put($key);
return null;
}
if (\strpos($key, '.')) {
$key_array = \explode('.', $key);
$value = $session->all();
foreach ($key_array as $index) {
if (!isset($value[$index])) {
return $default;
}
$value = $value[$index];
}
return $value;
}
return $session->get($key, $default);
}
/**
* @param null|string $id
* @param array $parameters
* @param string|null $domain
* @param string|null $locale
* @return string
*/
function trans(string $id, array $parameters = [], string $domain = null, string $locale = null)
{
$res = Translation::trans($id, $parameters, $domain, $locale);
return $res === '' ? $id : $res;
}
/**
* @param null|string $locale
* @return string
*/
function locale(string $locale = null)
{
if (!$locale) {
return Translation::getLocale();
}
Translation::setLocale($locale);
}
/**
* 404 not found
*
* @return Response
*/
function not_found()
{
return new Response(404, [], file_get_contents(public_path() . '/404.html'));
}
/**
* Copy dir.
* @param $source
* @param $dest
* @param bool $overwrite
* @return void
*/
function copy_dir($source, $dest, $overwrite = false)
{
if (is_dir($source)) {
if (!is_dir($dest)) {
mkdir($dest);
}
$files = scandir($source);
foreach ($files as $file) {
if ($file !== "." && $file !== "..") {
copy_dir("$source/$file", "$dest/$file");
}
}
} else if (file_exists($source) && ($overwrite || !file_exists($dest))) {
copy($source, $dest);
}
}
/**
* Remove dir.
* @param $dir
* @return bool
*/
function remove_dir($dir)
{
if (is_link($dir) || is_file($dir)) {
return unlink($dir);
}
$files = array_diff(scandir($dir), array('.', '..'));
foreach ($files as $file) {
(is_dir("$dir/$file") && !is_link($dir)) ? remove_dir("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
/**
* @param $worker
* @param $class
*/
function worker_bind($worker, $class)
{
$callback_map = [
'onConnect',
'onMessage',
'onClose',
'onError',
'onBufferFull',
'onBufferDrain',
'onWorkerStop',
'onWebSocketConnect'
];
foreach ($callback_map as $name) {
if (method_exists($class, $name)) {
$worker->$name = [$class, $name];
}
}
if (method_exists($class, 'onWorkerStart')) {
call_user_func([$class, 'onWorkerStart'], $worker);
}
}
/**
* @param $process_name
* @param $config
* @return void
*/
function worker_start($process_name, $config)
{
$worker = new Worker($config['listen'] ?? null, $config['context'] ?? []);
$property_map = [
'count',
'user',
'group',
'reloadable',
'reusePort',
'transport',
'protocol',
];
$worker->name = $process_name;
foreach ($property_map as $property) {
if (isset($config[$property])) {
$worker->$property = $config[$property];
}
}
$worker->onWorkerStart = function ($worker) use ($config) {
require_once base_path() . '/support/bootstrap.php';
foreach ($config['services'] ?? [] as $server) {
if (!class_exists($server['handler'])) {
echo "process error: class {$server['handler']} not exists\r\n";
continue;
}
$listen = new Worker($server['listen'] ?? null, $server['context'] ?? []);
if (isset($server['listen'])) {
echo "listen: {$server['listen']}\n";
}
$instance = Container::make($server['handler'], $server['constructor'] ?? []);
worker_bind($listen, $instance);
$listen->listen();
}
if (isset($config['handler'])) {
if (!class_exists($config['handler'])) {
echo "process error: class {$config['handler']} not exists\r\n";
return;
}
$instance = Container::make($config['handler'], $config['constructor'] ?? []);
worker_bind($worker, $instance);
}
};
}
/**
* Phar support.
* Compatible with the 'realpath' function in the phar file.
*
* @param string $file_path
* @return string
*/
function get_realpath(string $file_path): string
{
if (strpos($file_path, 'phar://') === 0) {
return $file_path;
} else {
return realpath($file_path);
}
}
/**
* @return bool
*/
function is_phar()
{
return class_exists(\Phar::class, false) && Phar::running();
}
/**
* @return int
*/
function cpu_count()
{
// Windows does not support the number of processes setting.
if (\DIRECTORY_SEPARATOR === '\\') {
return 1;
}
$count = 4;
if (is_callable('shell_exec')) {
if (strtolower(PHP_OS) === 'darwin') {
$count = (int)shell_exec('sysctl -n machdep.cpu.core_count');
} else {
$count = (int)shell_exec('nproc');
}
}
return $count > 0 ? $count : 4;
}
+3
View File
@@ -0,0 +1,3 @@
CHCP 65001
php windows.php
pause
+114
View File
@@ -0,0 +1,114 @@
<?php
/**
* Start file for windows
*/
require_once __DIR__ . '/vendor/autoload.php';
use process\Monitor;
use Workerman\Worker;
use Webman\Config;
ini_set('display_errors', 'on');
error_reporting(E_ALL);
Config::load(config_path(), ['route', 'container']);
$runtime_process_path = runtime_path() . DIRECTORY_SEPARATOR . '/windows';
if (!is_dir($runtime_process_path)) {
mkdir($runtime_process_path);
}
$process_files = [
__DIR__ . DIRECTORY_SEPARATOR . 'start.php'
];
foreach (config('process', []) as $process_name => $config) {
$file_content = <<<EOF
<?php
require_once __DIR__ . '/../../vendor/autoload.php';
use Workerman\Worker;
use Webman\Config;
ini_set('display_errors', 'on');
error_reporting(E_ALL);
if (is_callable('opcache_reset')) {
opcache_reset();
}
Config::load(config_path(), ['route', 'container']);
worker_start('$process_name', config('process')['$process_name']);
if (DIRECTORY_SEPARATOR != "/") {
Worker::\$logFile = config('server')['log_file'] ?? Worker::\$logFile;
}
Worker::runAll();
EOF;
$process_file = $runtime_process_path . DIRECTORY_SEPARATOR . "start_$process_name.php";
$process_files[] = $process_file;
file_put_contents($process_file, $file_content);
}
foreach (config('plugin', []) as $firm => $projects) {
foreach ($projects as $name => $project) {
foreach ($project['process'] ?? [] as $process_name => $config) {
$file_content = <<<EOF
<?php
require_once __DIR__ . '/../../vendor/autoload.php';
use Workerman\Worker;
use Webman\Config;
ini_set('display_errors', 'on');
error_reporting(E_ALL);
if (is_callable('opcache_reset')) {
opcache_reset();
}
Config::load(config_path(), ['route', 'container']);
worker_start("plugin.$firm.$name.$process_name", config("plugin.$firm.$name.process")['$process_name']);
if (DIRECTORY_SEPARATOR != "/") {
Worker::\$logFile = config('server')['log_file'] ?? Worker::\$logFile;
}
Worker::runAll();
EOF;
$process_file = $runtime_process_path . DIRECTORY_SEPARATOR . "start_$process_name.php";
$process_files[] = $process_file;
file_put_contents($process_file, $file_content);
}
}
}
$monitor = new Monitor(...array_values(config('process.monitor.constructor')));
function popen_processes($process_files)
{
$cmd = "php " . implode(' ', $process_files);
$descriptorspec = [STDIN, STDOUT, STDOUT];
$resource = proc_open($cmd, $descriptorspec, $pipes);
if (!$resource) {
exit("Can not execute $cmd\r\n");
}
return $resource;
}
$resource = popen_processes($process_files);
echo "\r\n";
while (1) {
sleep(1);
if ($monitor->checkAllFilesChange()) {
$status = proc_get_status($resource);
$pid = $status['pid'];
shell_exec("taskkill /F /T /PID $pid");
proc_close($resource);
$resource = popen_processes($process_files);
}
}