同步操作将从 陈某某/duckphp 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
v1.2.8-dev版 作者QQ: 85811616
官方QQ群: 714610448
快速入门 ,快速入门页面。
文档索引页 ,所有文档索引页面,所有文档的集合入口
进入 template 目录
php start_server.php
即可
composer require dvaknheo/duckphp # 用 require
./vendor/bin/duckphp --help # 查看有什么指令
./vendor/bin/duckphp --create # --full # 创建工程,把 template 目录内容复制到当前目录
./vendor/bin/duckphp --start # --host=127.0.0.1 --port=8080 # 开始 web 服务器
不建议使用命令行的 web 服务器, 你把 nginx 或 apache 的 document_root 设置为 public 目录按常规框架调整即可。
DuckPhp 也支持在子目录里使用,同时也支持无 path_info 配置的 web 服务器。
DuckPhp 的名字来源:
Duck Typing
If it walks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
鸭子类型,这东西看起来像鸭子,叫起来像鸭子,所以就是鸭子。
起初,这是是想搞个简单的 PHP Web 简单框架 。现在是使用方式简单,实际方式不简单。
DuckPhp 的版本历程
业务层。通常的 Model,Controller,View 少了一层。而因为这种缺层,导致了很多很糟糕的场景。你会发现很多人在 Contorller 里写一堆代码,或者在 Model 里写一堆代码。
这个层。有人称呼 Service ,有人称呼 Logic 。我最初的时候称呼为 App ,很长时间内我都称为 Service 。现在,我称呼为 Business 业务层。之所以改过来, Business 就是业务的意思啊。不用多想。 而且现在 Service 服务 这个层被用滥了。现在第三方的平台过来的东西才叫 Service ,业务范围之内的,就叫 Business 吧。Service 给人的感觉是业务需要的服务,不能完成一个功能。
所以,Business 按业务走,Model 层按数据库走,Controller 层按 URL 地址走,View 按页面走,这就是 DuckPhp 的理念。
DuckPhp 的最大意义是思想,只要思想在,什么框架你都可以用。 你可以不用 DuckPhp 实现 Controller-Business-Model 架构。 只要有这个思想就是理念成功了。
组合而非继承。这是 DuckPhp 提倡的另一个观点。
功能 | CodeIgniter 4 | ThinkPHP 6 | Laravel 6 | DuckPhp |
---|---|---|---|---|
仅一行关联 | V | |||
堆栈清晰 | V | V | V | |
可热修复,不改源码解决所有问题 | V | |||
可把工程转成插件给第三方用 | V | |||
全覆盖测试 | V | |||
以库引用 | V | |||
单一 composer 框架 | V | |||
无第三方依赖 | V | |||
高性能 | V | V | V | |
代码简洁 | V | V | V | |
非固定全站框架 | V |
DuckPhp 层级关系图
/-> View-->ViewHelper
Controller --> Business ------------------------------ ---> Model
\ \ \ \ / \
\ \ \-> (Business)Lib ----> ExModel----------->ModelHelper
\ \ \
\ ---------------->BusinessHelper
\-->ControllerHelper
如果 Business 业务之间 相互调用怎么办? 添加后缀为 Lib 用于 Business 共享调用,不对外,如 CacheLib.
如果跨表怎么办?,三种解决方案
我真的很需要反馈啊,给我个反馈吧
File: template/public/helloworld.php
<?php declare(strict_types=1);
/**
* DuckPhp
* From this time, you never be alone~
*/
require_once(__DIR__.'/../../autoload.php'); // @DUCKPHP_HEADFILE
class Main
{
public function index()
{
echo "hello world";
}
}
$options = [
'namespace_controller' => "\\", // 本例特殊,设置控制器的命名空间为根,而不是默认的 Controller
];
\DuckPhp\DuckPhp::RunQuickly($options);
工程附带的模板文件 template/public/demo.php
在单一的文件里演示如何使用 DuckPhp
。
需要注意的是,这个样例是为了演示特性把所有东西集中到一个文件,实际编码不会把所有东西全放在同一个文件里。
File: template/public/demo.php
<?php declare(strict_types=1);
/**
* DuckPHP
* From this time, you never be alone~
*/
namespace
{
//自动加载文件
require_once(__DIR__.'/../../autoload.php'); // @DUCKPHP_HEADFILE
}
// 以下部分是核心工程师写。
namespace MySpace\System
{
use DuckPhp\DuckPhp;
use DuckPhp\Ext\CallableView;
use DuckPhp\SingletonEx\SingletonEx;
use MySpace\View\Views;
class App extends DuckPhp
{
// @override
public $options = [
'is_debug' => true,
// 开启调试模式
'path_info_compact_enable' => true,
// 开启单一文件模式,服务器不配置也能运行
'ext' => [
CallableView::class => true,
// 默认的 View 不支持函数调用,我们开启自带扩展 CallableView 代替系统的 View
],
'callable_view_class' => Views::class,
// 替换的 View 类。
];
protected function onInit()
{
//初始化之后在这里运行。
//var_dump($this->options);//查看总共多少选项
}
protected function onRun()
{
//运行期代码在这里
}
}
//服务基类, 为了 Business::G() 可变单例。
class BaseBusiness
{
use SingletonEx;
}
} // end namespace
// 助手类
namespace MySpace\System\Helper
{
class ControllerHelper extends \DuckPhp\Helper\ControllerHelper
{
// 添加你想要的助手函数
}
class BusinessHelper extends \DuckPhp\Helper\BusinessHelper
{
// 添加你想要的助手函数
}
class ModelHelper extends \DuckPhp\Helper\ModelHelper
{
// 添加你想要的助手函数
}
class ViewHelper extends \DuckPhp\Helper\ViewHelper
{
// 添加你想要的助手函数
}
} // end namespace
//------------------------------
// 以下部分由应用工程师编写,不再和 DuckPhp 的类有任何关系。
namespace MySpace\Controller
{
use MySpace\Business\MyBusiness; // 引用助手类
use MySpace\System\Helper\ControllerHelper as C; // 引用相关服务类
class Main
{
public function __construct()
{
// 在构造函数设置页眉页脚。
C::setViewHeadFoot('header', 'footer');
}
public function index()
{
//获取数据
$output = "Hello, now time is " . C::H(MyBusiness::G()->getTimeDesc());
$url_about = C::URL('about/me');
C::Show(get_defined_vars(), 'main_view'); //显示数据
}
}
class about
{
public function me()
{
$url_main = C::URL(''); //默认URL
C::setViewHeadFoot('header', 'footer');
C::Show(get_defined_vars()); // 默认视图 about/me ,可省略
}
}
} // end namespace
namespace MySpace\Business
{
use MySpace\Model\MyModel;
use MySpace\System\BaseBusiness;
use MySpace\System\Helper\BusinessHelper as B;
class MyBusiness extends BaseBusiness
{
public function getTimeDesc()
{
return "<" . MyModel::getTimeDesc() . ">";
}
}
} // end namespace
namespace MySpace\Model
{
use MySpace\Base\Helper\ModelHelper as M;
class MyModel
{
public static function getTimeDesc()
{
return date(DATE_ATOM);
}
}
}
// 把 PHP 代码去掉看,这是可预览的 HTML 结构
namespace MySpace\View {
class Views
{
public static function header($data)
{
extract($data); ?>
<html>
<head>
</head>
<body>
<header style="border:1px gray solid;">I am Header</header>
<?php
}
public static function main_view($data)
{
extract($data); ?>
<h1><?=$output?></h1>
<a href="<?=$url_about?>">go to "about/me"</a>
<?php
}
public static function about_me($data)
{
extract($data); ?>
<h1> OK, go back.</h1>
<a href="<?=$url_main?>">back</a>
<?php
}
public static function footer($data)
{
?>
<footer style="border:1px gray solid;">I am footer</footer>
</body>
</html>
<?php
}
}
} // end namespace
//------------------------------
// 入口,放最后面避免自动加载问题
namespace
{
$options = [
//'override_class' => 'MySpace\System\App', // 你也可以在这里调整选项。
];
\MySpace\System\App::RunQuickly($options);
}
系统架构图
完整应用架构图(缺事件和异常处理部分)
使用它,鼓励我,让我有写下去的动力
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。