要求PHP>=8.0
<?php
namespace app\controller;
use support\Response;
class UserController
{
public function create(string $name, int $age, float $balance, bool $vip, array $extension): Response
{
return json([
'name' => $name,
'age' => $age,
'balance' => $balance,
'vip' => $vip,
'extension' => $extension,
]);
}
}
訪問 /user/create?name=tom&age=18&balance=100.5&vip=1&extension[foo]=bar
得到結(jié)果
{
"name": "tom",
"age": 18,
"balance": 100.5,
"vip": true,
"extension": {
"foo": "bar"
}
}
同時參數(shù)支持綁定類包括模型,例如
<?php
namespace app\controller;
use app\model\User;
class UserController
{
public function create(User $user): int
{
$user->save();
return $user->id;
}
}
更多參考控制器參數(shù)綁定
<?php
namespace app\controller;
use app\middleware\MiddlewareA;
use app\middleware\MiddlewareB;
use support\Request;
class IndexController
{
protected $middleware = [
MiddlewareA::class,
MiddlewareB::class,
];
public function index(Request $request): string
{
return 'hello';
}
}
正常情況下404請求不會走任何中間件,從1.6.0版本開始可以給4xx請求設(shè)置中間件
Route::fallback(function(){
return json(['code' => 404, 'msg' => '404 not found']);
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
// 禁用主項目默認(rèn)路由,不影響應(yīng)用插件
Route::disableDefaultRoute();
// 禁用主項目的admin應(yīng)用的路由,不影響應(yīng)用插件
Route::disableDefaultRoute('', 'admin');
// 禁用foo插件的默認(rèn)路由,不影響主項目
Route::disableDefaultRoute('foo');
// 禁用foo插件的admin應(yīng)用的默認(rèn)路由,不影響主項目
Route::disableDefaultRoute('foo', 'admin');
// 禁用控制器 [\app\controller\IndexController::class, 'index'] 的默認(rèn)路由
Route::disableDefaultRoute([\app\controller\IndexController::class, 'index']);
$request->get(); // 假設(shè)得到 ['name' => 'tom', 'age' => 18]
$request->setGet(['name' => 'tom']);
$request->get(); // 最終得到 ['name' => 'tom']
// 以下類似
$requset->setPost();
$request->setHeaders();
<?php
namespace app\controller;
use support\Request;
class UserController
{
public function hello(Request $request)
{
// 等價于 return view('user/hello', ['name' => 'webman']);
// 等價于 return view('/app/view/user/hello', ['name' => 'webman']);
return view(['name' => 'webman']);
}
}
如果之前的項目代碼不是很規(guī)范,可能會有一些兼容問題,主要問題如下:
檢查要升級的項目中view()是否有以/
開頭的模板參數(shù),有的話把開頭的/
去掉,例如
return view('/user/index');
// 需要改成
return view('user/index');
Route::any('/user/{name}', function (Request $request, $myname) {
return response($myname);
});
// 需要改成
Route::any('/user/{name}', function (Request $request, $name) {
return response($name);
});
composer global config --unset repos.packagist
composer require workerman/webman-framework ^1.6.6 -W
提示
因為一些composer鏡像更新不及時, 所以可能無法找到最新的webman-framework包, 所以需要運行
composer global config --unset repos.packagist
先把composer代理鏡像設(shè)置去掉
Request類 setPost和setGet 報錯
另外 有什么辦法可以不覆蓋舊數(shù)據(jù)
重現(xiàn)代碼
解決方法 需要將setPost或setGet中的 $this->data['post'] = $post; 改成 _data['post']
public function setGet(array $get): Request
{
$this->isDirty = true;
if (isset($this->data)) {
$this->data['get'] = $get;
} else {
$this->_data['get'] = $get;
}
return $this;
}
/**
* Set post.
* @param array $post
* @return Request
*/
public function setPost(array $post): Request
{
$this->isDirty = true;
if (isset($this->data)) {
$this->data['post'] = $post;
} else {
$this->_data['post'] = $post;
}
return $this;
}
/**
* Set headers.
* @param array $headers
* @return $this
*/
public function setHeaders(array $headers): Request
{
$this->isDirty = true;
if (isset($this->data)) {
$this->data['headers'] = $headers;
} else {
$this->_data['headers'] = $headers;
}
return $this;
}
改成這樣試下
Request setGet setPost 建議加上是否強(qiáng)制覆蓋功能
就是舊的數(shù)據(jù)不清除只是追加數(shù)據(jù) 比如在webman-admin中 insert數(shù)據(jù)的時候 除了表單提交的數(shù)據(jù) 我需要額外追加數(shù)據(jù)
另外 調(diào)用控制器A方法 A方法需要Request接收參數(shù) 這時我就可以在調(diào)用A方法時setParams 進(jìn)行追加參數(shù) ---如下圖
從 Webman-framework v1.5.24 升到1.6.0時出現(xiàn)在vendor/workerman/webman-framework/src/support/App.php
這里的報錯:
如果做如下修改就能解決,好像有個路徑組狀函數(shù)處有問題。
求指點!!
webman-framework/src/support/helpers.php
下的:
/**
* Generate paths based on given information
* @param string $front
* @param string $back
* @return string
*/
function path_combine(string $front, string $back): string
{
return $front . ($back ? (DIRECTORY_SEPARATOR . ltrim($back, DIRECTORY_SEPARATOR)) : $back);
}
好像是這里沒有正確返回。本地PHP環(huán)境為:PHP 8.3.13 (cli) (built: Oct 22 2024 18:39:14) (NTS)
老大,Request報錯了
public function file(?string $name = null): mixed
{
$files = parent::file($name);
if (null === $files) {
return $name === null ? [] : null;
}
if ($name !== null) {
// Multi files
if (is_array(current($files))) {
return $this->parseFiles($files);
}
return $this->parseFile($files);
}
$uploadFiles = [];
foreach ($files as $name => $file) {
// Multi files
if (is_array(current($file))) {
$uploadFiles[$name] = $this->parseFiles($file);
} else {
$uploadFiles[$name] = $this->parseFile($file);
}
}
return $uploadFiles;
}
老大,使用寶塔的php8.1,8.3也復(fù)現(xiàn)這個兄弟的這個問題,我的workerman/webman-framework也升級到5.0.0-rc.3了,按照glitter這個兄弟的代碼修改一下Request.php,確實修復(fù)了
為什么1.6.0后的版本,配置文件server,少了下面紅框里的參數(shù),php start.php start 沒有監(jiān)聽到listen了,如果改監(jiān)聽配置文件process的listen,框架啟動不起來
上面86行,會報造錯,找不到listen的key
config/server.php 里的配置移動到 config/process.php里了,可能你用了composer鏡像,里面包不全,沒更新到最新
執(zhí)行
composer require workerman/webman-framework ^1.6.6 -W
升級到最新
Root composer.json requires workerman/webman-framework 1.6.6 (exact version match: 1.6.6 or 1.6.6.0), found workerman/webman-framework[dev-master, v1.0.0, ..., 1.7.x-dev] but it does not match the constraint.
執(zhí)行
composer require workerman/webman-framework ^1.6.6 -W
報錯,執(zhí)行不到最新
執(zhí)行
composer config --unset repos.packagist
刪除鏡像代理,然后再
composer require workerman/webman-framework ^1.6.6 -W
執(zhí)行
composer config --unset repos.packagist
報錯,我得再研究下
應(yīng)該是php7.4版本對于1.6.6低了
使用composer create-project workerman/webman,創(chuàng)建的項目都是github里最新版本1.6.2,都是有問題的
webman-framework 1.6 需要php8, php7.4用不了
剛買了臺新服務(wù)器測試 php7.4 創(chuàng)建新項目, 會自動使用 workerman/webman-framework v1.5.26, 測試沒有問題
如果你是php7.x, composer require workerman/webman-framework 1.5.26
比如我現(xiàn)在有個疑問:項目目錄下的process目錄(我是幾年前的老項目一直沒動過)與現(xiàn)在社區(qū)github里的app\process的有什么區(qū)別?!如果我想升級到最新應(yīng)該怎么移植!~
composer config --unset repos.packagist
composer require workerman/webman-framework ^1.6.6 -W
./composer.json has been updated
Running composer update workerman/webman-framework --with-all-dependencies
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
Installation failed, reverting ./composer.json and ./composer.lock to their original content.
windown10上全新安裝,啟動不了windows.bat,提示錯誤 v1.6.4
Fatal error: Declaration of Webman\Http\Request::file($name = null) must be compatible with Workerman\Protocols\Http\Request::file(?string $name = null): mixed in D:\webman\vendor\workerman\webman-framework\src\Http\Request.php on line 119
Worker process terminated with ERROR: E_COMPILE_ERROR "Declaration of Webman\Http\Request::file($name = null) must be compatible with Workerman\Protocols\Http\Request::file(?string $name = null): mixed in D:\webman\vendor\workerman\webman-framework\src\Http\Request.php on line 119"
有沒有大佬實現(xiàn)那種類控制器里參數(shù)綁定類后 配合驗證器,可以對傳入?yún)?shù)進(jìn)行校驗。 校驗通過后再進(jìn)入控制器??梢栽陬惱铽@取到對應(yīng)的數(shù)據(jù)。
這樣就省了在控制器里寫驗證器了
1.6版本如何更改覆蓋helpers.php內(nèi)的方法,比如這個方法統(tǒng)一更改使用的 _ 連接符,想保持原路徑和方法的名稱怎么做?如何在加載這個文件前加載一個自定義的文件可以覆蓋里面的方法呢?
if (!function_exists('template_inputs')) {
/**
* Get template vars
* @param mixed $template
* @param array $vars
* @param string|null $app
* @param string|null $plugin
* @return array
*/
function template_inputs(mixed $template, array $vars, ?string $app, ?string $plugin): array
{
$request = \request();
$plugin = $plugin === null ? ($request->plugin ?? '') : $plugin;
if (is_array($template)) {
$vars = $template;
$template = null;
}
if ($template === null && $controller = $request->controller) {
$controllerSuffix = config($plugin ? "plugin.$plugin.app.controller_suffix" : "app.controller_suffix", '');
$controllerName = $controllerSuffix !== '' ? substr($controller, 0, -strlen($controllerSuffix)) : $controller;
$path = str_replace(['controller', 'Controller', '\\'], ['view', 'view', '/'], $controllerName);
$path = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $path));
$action = $request->action;
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
foreach ($backtrace as $backtraceItem) {
if (!isset($backtraceItem['class']) || !isset($backtraceItem['function'])) {
continue;
}
if ($backtraceItem['class'] === App::class) {
break;
}
if (preg_match('/\\\\controller\\\\/i', $backtraceItem['class'])) {
$action = $backtraceItem['function'];
break;
}
}
$actionFileBaseName = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $action));
$template = "/$path/$actionFileBaseName";
}
return [$template, $vars, $app, $plugin];
}
}