panada / app
一个同时追求简洁和性能的PHP框架
Requires
- php: >=5.5.0
- panada/cache: dev-master
- panada/database: dev-master
- panada/http: dev-master
- panada/loader: dev-master
- panada/notorm: dev-master
- panada/resource: dev-master
- panada/router: dev-master
- panada/session: dev-master
- panada/utility: dev-master
This package is not auto-updated.
Last update: 2024-09-14 17:32:01 UTC
README
由于几个工作相关的承诺,开发进度有点慢,对此我深表歉意。然而,我在寻找一些很棒的伙伴 🤘,他们可以贡献并帮助我维护这个项目。如果您有任何关于如何贡献的问题,或者您对如何使用应用中的组件有一般性问题 - 欢迎随时发邮件。我会帮您的! 😸
关于Panada
Panada是一个基于PHP 5.5的高性能开发框架,同时简单易用。不仅在使用上下文中,还包括核心系统如何运行。
目前,Panada 2.0正处于非常重的开发阶段,因此其功能将会有很多变化。
要求
Panada仅支持PHP 5.5及以上版本。
安装
composer create-project panada/app --prefer-dist --stability=dev myweb;
php -S localhost:8181 -t myweb/public;
然后在浏览器中打开 https://:8181
快速入门指南
控制器
从版本1开始,Panada使用 HMVC 设计模式。作为HMVC架构的一部分,控制器负责处理请求和生成响应,包括主应用程序控制器和模块控制器。现在让我们在主应用程序中创建一个。
在 src/Controller 文件夹中创建一个名为 Hello.php 的新文件。然后编写一些类
<?php namespace Controller; class Hello { public function index() { return 'Hello world!'; } public function me($firstName = null, $lastName = null) { return 'My name is:'.$name.' '.$lastName; } }
访问控制器
访问控制器的URL格式如下
ControllerName/ActionName
现在在浏览器中打开 https://:8181/hello 或 https://:8181/me/john/doe
在2.0版本中,我们改变了控制器获取控制器辅助方法的方式。要使用此辅助程序,您可以使用 Controller 特性。
<?php namespace Controller; class Hello { use \Panada\Resource\Controller; public function index() { return 'Hello world!'; } }
或者如果您在控制器中使用构造函数,您可以使用
<?php namespace Controller; use Panada; use Panada\Resource\Controller; class Cookies { use Controller { Controller::__construct as private _construct; } public function __construct() { $this->_construct(); $this->session = Panada\Session\Session::getInstance(); } public function index() { $this->response->setHeaders('Content-Type', 'text/html'); if( $this->session->getValue('isLogin') ) return $this->response->redirect('cookies/protectedPage'); return '<a href="'.$this->uri->location('cookies/set').'">Set session</a>'; } public function api() { $this->response->setHeaders('Content-Type', 'application/json'); return json_encode(['foo' => 'bar']); } }
视图
您可以在 views 文件夹中管理分离的HTML模板文件。现在让我们在 src/view 文件夹中创建一个视图文件,命名为 helloWorld.php
<html> <head> <title>Hellow world!</title> </head> <body> Hello world! </body> </html>
要在控制器的方法中显示您的视图文件,请使用控制器中的 $this->output()
方法
<?php namespace Controller; class Hello { use \Panada\Resource\Controller; public function index() { return $this->output('helloWorld'); } }
要从控制器传递一个值到视图,只需在 $this->output()
方法的第二个参数中添加一个数组
<?php namespace Controller; class Hello { use \Panada\Resource\Controller; public function index() { return $this->output('helloWorld', ['name' => 'Panada']); } }
然后在您的视图文件中使用 $name 变量。
<html> <head> <title><?=$name?></title> </head> <body> <?=$name?> </body> </html>
模型
模型是MVC架构的一部分。它们是代表业务数据、规则和逻辑的对象。模型是一个与数据处理直接相关的类,无论是从数据库还是其他存储系统。
创建模型
要创建模型类,请添加新文件并将其放在文件夹 src/Model/ 中,例如 Users.php。
在文件中创建一个具有给定命名空间 "Model" 的 users 类,例如
<?php
namespace Model;
class Users
{
public function __construct()
{
}
}
在模型中加载库
如果您计划在此模型中加载库或另一个类,有两种方法可以做到。首先,如果该类或库的资源将被模型类中的所有方法使用,则检索和初始化可以在构造函数中完成。然而,如果资源只想在特定方法中使用,则初始化和检索可以在相关方法中完成。
在类模型中,最常见的事情之一是加载数据库资源。以下是一个在模型类中加载数据库资源的简单示例
<?php namespace Model; use Panada\Database; class Users { public function __construct() { $this->db = Database\SQL::getInstance(); } }
此外,属性 "$this->db" 可以用于该类中存在的所有方法。以下是一个从数据库获取5条记录的示例
<?php namespace Model; use Panada\Database; class Users { public function __construct() { $this->db = Database\SQL::getInstance(); } public function users() { return $this->db->results("SELECT * FROM table_name ORDER BY id LIMIT 5"); } }
模块
模块是由模型、视图、控制器和其他支持组件组成的子应用程序。与应用程序不同的是,模块不能独立部署,必须位于应用程序中。Panada中的每个模块都位于 Module
文件夹中。
模块中的每个类都应该在其命名空间中添加模块名称。例如
<?php namespace Module\Foo\Controller; class Bar { use \Panada\Resource\Controller; public function index() { return __METHOD__; } public function blog() { return __METHOD__; } }
访问模块
访问模块中的控制器的URL格式如下
ModuleName/ControllerName/ActionName
因此,如果我们有一个名为Foo的模块,该模块有一个名为Bar的控制器的名为blog的方法,则URL为
http://www.mysite.com/foo/bar/blog
或者,如果您没有定义控制器名称和操作名称,它将转到控制器Home的index方法。
路由
路由是一种让您定义某些URL并将其映射到应用程序不同区域的方法。与主控制器或模块不同,路由为您提供了定义URL格式的灵活性。
路由器
在路由器配置文件中必须定义3个实体。
1. 模式
模式定义了URL动态部分的格式。实际上,模式对于定义动态路由是必不可少的。例如,post_id和published_date在URL中将由三个不同的模式检测。
2. 默认值
当我们不想在定义路由或创建链接时每次都提及URL的某个部分时,将使用默认值。
3. 路由
从URL到控制器的映射。
Panada的路由配置位于src/config/routes.php,以下是一些示例
<?php return [ 'pattern' => [ 'year' => '/^[0-9]{4}$/i', 'month' => '/^[0-9]{2}$/i', 'id' => '/^[1-9][0-9]+$/i', 'name' => '/^[a-z][a-z0-9_]+$/i' ], 'defaults' => [ 'method' => 'GET|POST', 'protocol' => 'http', 'subdomain' => '', 'domain' => 'localhost', 'port' => 8081, ], 'route' => [ 'archive' => [ 'url'=>'/news/:year/:month', 'controller'=>'news', 'action'=>'archive' ], 'article' => [ 'url'=>'/post', 'controller'=>'posts', 'action'=>'view' ], 'test1' => [ 'url'=>'/test1', 'controller'=>'Controller\Home', 'action'=>'test1' ], 'blog' => [ 'url'=>'/blog/:name', 'controller'=>'Controller\Hidden\HiddenPage', 'action'=>'index' ] ] ];
请求处理器优先级规则
有时我们有一个与模块名称同名或与路由规则匹配的控制器。在这种情况下,默认情况下,Panada将首先检查主控制器,然后是模块,然后是路由。如果您希望更改其他规则优先级,可以更改 app/src/config/main.php
文件。
'requestHandlerRule' => [ 'controllerHandler', 'moduleHandler', 'routingHandler' ]
数据库
2.0版本采用NotORM,一个用于简单处理数据库数据的库。
您的数据库配置位于 src/config/database.php
<?php return [ 'default' => [ 'dsn' => 'mysql:host=127.0.0.1;dbname=panada;port=3306', 'username' => 'root', 'password' => '', 'options' => [ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', PDO::ATTR_PERSISTENT => true ] ] ];
以下是使用NotORM的示例
<?php namespace Controller; class Testnotorm { public function __construct() { $this->db = \Panada\Notorm\NotORM::getInstance(); // pass config name in getInstance method if you have another config // $this->db = \Panada\Notorm\NotORM::getInstance('mysql'); } public function index() { $r = null; foreach ($this->db->users() as $user) { $r .= $user['email'].'<br>'; } return $r; } public function singleRow() { $r = print_r($this->db->users[1]['id'], true); $r .= '<br>'; $r .= print_r($this->db->users('id = ?', 1)->fetch()['id'], true); } public function insert() { $name = time(); $row = $this->db->users()->insert([ "name" => $name, "email" => $name."@bar.com", ]); return print_r($row['id'], true); } public function update() { $name = time(); $affected = $this->db->users('id = ?', 1)->fetch()->update(['name' => 'update']); return print_r($affected, true); } public function delete() { return var_export($this->db->users[1]->delete(), true); } }
要查看更多如何使用NotORM API的示例,请查看此仓库 https://github.com/panada/notorm
会话
以下是如何使用会话的示例
<?php namespace Controller; use Panada; use Panada\Resource\Controller; class Admin { use Controller { Controller::__construct as private _construct; } public function __construct() { $this->_construct(); $this->session = Panada\Session\Session::getInstance(); // pass config name in getInstance method if you have another session config // $this->session = Panada\Session\Session::getInstance('config2'); } public function index() { if( $this->session->getValue('isLogin') ) return $this->response->redirect('admin/protectedPage'); return '<a href="'.$this->uri->location('admin/set').'">Set session</a>'; } public function protectedPage(){ $echo = $this->session->getValue('name').'<br />'; $echo .= '<a href="'.$this->uri->location('admin/remove').'">Remove session</a>'; return $echo; } public function remove(){ $this->session->destroy(); return $this->response->redirect('admin'); } }
缓存
以下是如何使用缓存的示例
<?php namespace Controller; use Panada; use Panada\Resource\Controller; class Blog { use Controller { Controller::__construct as private _construct; } public function __construct() { $this->_construct(); $this->cache = Panada\Cache\Cache::getInstance(); // pass config name in getInstance method if you have another cache config // $this->cache = Panada\Cache\Cache::getInstance();'config2'); } public function index() { $key = 'foo'; $val = 'bar'; $val2 = 'bar2'; $info; // insert new value by a key $status = $this->cache->setValue($key, $val); $info .= 'Insert status:<br>'.var_export($status, true); // get a value $status = $this->cache->getValue($key); $info .= 'Get status:<br>'.var_export($status, true); // update a value $status = $this->cache->updateValue($key, $val2); $info .= 'Update status:<br>'.var_export($status, true); // get updated value $status = $this->cache->getValue($key); $info .= 'Get updated value status:<br>'.var_export($status, true); // delete a value by it key $status = $this->cache->deleteValue($key); $info .= 'Delete status:<br>'.var_export($status, true); // get deleted value $status = $this->cache->getValue($key); $info .= 'Deleted value status:<br>'.var_export($status, true); return $info; } }
要了解更多关于缓存包的使用,请访问 https://github.com/panada/cache
附加库
Panada 2.0完全支持Composer。安装附加的Panada包或外部库通过Composer处理。
Web服务器
Nginx
Nginx 是一个免费、开源、高性能且极其快速的HTTP服务器。要使其与您的Panada项目一起工作,您可以使用以下示例服务器配置
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# this is the root of your project
root /var/www/public;
index index.php;
location / {
try_files $uri /index.php$request_uri;
}
location ~ \.php(/|$) {
index index.php;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
Apache
在您的公共文件夹中创建一个 .htaccess 文件,然后填写以下内容
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
从版本1.1升级
由于Panada为2.0完全重写,因此1.1和2.0之间存在很多差异。因此,从1.1版本升级不如从次版本升级那么简单。
前端控制器(index.php)
index.php文件的所有内容都完全更改了。在2.0版本中,我们不再使用任何全局常量。因此,如果您使用了以下常量之一:APP、INDEX_FILE或GEAR,请更新它们。
文件夹名称
所有文件夹名称都已更改
- app 更改为 src
- 将/app/Controllers重命名为/src/Controller
- 将/app/views重命名为/src/view
- 将/app/Modules重命名为/src/Module
Panada文件夹现在已移动到vendor/panada。
视图
在版本1.1中,要显示输出,开发者只需像这样简单地echo变量
public function index($id = 0) { echo 'This is the news with ID' . $id; }
或者,使用$this->output()方法从视图文件显示
public function index() { $this->output('helloworldViewFile'); }
但在版本2.0中,您只需返回对象即可,就像这样
public function index($id = 0) { return 'This is the news with ID' . $id; } public function page() { return $this->output('helloworldViewFile'); }
控制器
控制器的命名空间现在变为
<?php namespace Controller;
控制器的父类从
class Home extends \Libraries\Controller { public function __construct() { parent::__construct(); } public function index() { } }
更改为
class Home { use Controller { Controller::__construct as private _construct; } public function __construct() { $this->_construct(); } public function index() { } }
我们支持trait的特性。
别名
控制器功能已被移除,仅支持方法别名。为了适应您的别名功能,您可以使用路由。
如果您需要使用其他名称作为别名方法,您可以在app/src/config/main.php
中更改它。
数据库
从版本2.0开始,Panada使用PDO作为默认数据库驱动程序。我们还移除了Active Recored功能,并替换为NotORM。因此,在版本2.0中,您无法再使用当前的查询。您必须更新所有数据库查询。
然而,我们仍然保留了查询构建器。但您需要更新位于app/src/config/database.php
的文件数据库配置。
版本1的Panada数据库配置看起来像
<?php
return array(
'default' => array(
'driver' => 'mysqli',
'host' => 'localhost',
'port' => 3306,
'user' => 'root',
'password' => '',
'database' => 'panada',
'tablePrefix' => '',
'charset' => 'utf8',
'collate' => 'utf8_general_ci',
'persistent' => false,
);
);
在版本2中应该是
return [
'default' => [
'dsn' => 'mysql:host=127.0.0.1;dbname=mydb1;port=3306',
'username' => 'root',
'password' => '',
'options' => [
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
PDO::ATTR_PERSISTENT => true
]
],
];
更多关于查询构建器请参阅https://github.com/panada/database
完整文档
我们还没有为Panada版本2.X提供完整的文档。如果您认为您可以帮助我们编写一些,那将非常不错。只需在https://github.com/panada/documentation/tree/with-pure.0.5.0的文档分支上进行fork即可。
贡献
Panada 2.0由多个子包组成。为了报告任何错误或进行一些贡献,请前往每个包的repo。