firelit / framework
简单的PHP框架和辅助类,适用于Web项目
Requires
- php: >=5.4.0
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: 5.5.*
- squizlabs/php_codesniffer: 2.*
- symfony/console: 3.*
This package is not auto-updated.
Last update: 2024-09-28 21:02:07 UTC
README
Firelit的标准化PHP框架提供了一组有助于开发网站的类。它们被创建并命名空间化,以便可以轻松地与自动加载器一起使用,遵循PSR-4标准。
需求
- PHP版本5.4.0或更高
- 测试PHP版本5.6.0或更高
外部PHP扩展
- OpenSSL扩展(用于
Crypto
和CryptoKey
类) - cURL扩展(用于
HttpRequest
类) - 特定数据库的PDO扩展(例如,
pdo-mysql
,用于Query
类)
如何使用
使用此库的最简单方法是使用Composer,它将自动处理依赖项和自动加载。
以下是如何将此软件包添加到您的composer.json
文件下的require键的示例
"require": { "firelit/framework": "^2.0" }
您也可以从命令行如下添加
php composer.phar require firelit/framework "^2.0"
或者,您可以选择手动方式,设置自己的自动加载器,并将项目文件从lib/
复制到您的项目目录。
MVC架构
此框架包含用于支持使用MVC架构构建应用程序的类。
Firelit\View
类Firelit\Controller
类Firelit\DatabaseObject
(即模型)类Firelit\Router
类(见以下示例)
使用这些类在单个入口Web应用程序中的示例实现
<?php // Setup $resp = Firelit\Response::init(); $reqs = Firelit\Request::init(); $router = Firelit\Router::init($reqs); $router->add('GET', '!^/Hello$!', function() { // Simple route, you'd go to http://example.com/Hello and get this: echo 'World!'; }); $router->add('GET', '!^/redirect$!', function() use ($resp) { // Redirect example $resp->redirect('/to/here'); }); $router->add('POST', '!^/forms!', function() { // Process the POST request in a controller Firelit\Controller::handoff('Controller\Forms', 'process'); }); $router->add('GET', '!^/groups/([^0-9]+)$!', function($matches) { // Match URL parts with regular expressions to extract information echo 'You selected group #'. $matches[0]; }); // You can nest routes to keep things organized $myNestedRoutes = require_once('routes/api.php'); $router->add('GET', '!^/api/!', $myNestedRoutes); $router->defaultRoute(function() use ($resp) { // A default route is a backstop, catching any routes that don't match $resp->code(404); echo 'Sorry, no can do'; }); $router->exceptionHandler(function($e) use ($resp) { $resp->setCode(500); echo $e->getMessage(); exit; }); $router->go();
请注意,此设置被认为是单个入口,因此必须在Web服务器上进行轻微修改,以便强制它对所有HTTP请求使用主脚本(例如,index.php)。以下是来自WordPress项目的示例.htaccess
,它将配置Apache将所有请求路由到单个入口脚本。
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>
包含的类
ApiResponse
API端点的响应处理类。可以处理所有HTTP响应代码和JSON & 有限 XML。设置模板以确保某些字段始终随响应发送。
示例用法
<?php $resp = Firelit\ApiResponse::init('JSON'); $resp->setTemplate(array( 'success' => false, 'message' => '' )); $resp->code(404); $resp->respondAndEnd(array( 'message' => 'Resource could not be located.' ));
缓存
一个缓存类。首先使用php内存缓存(一个全局PHP变量)并可配置为使用memcached第二。在每次缓存检查后设置静态变量$cacheHit
和$cacheMiss
。
示例用法
<?php Firelit\Cache::config(array( 'memcached' => array( 'enabled' => true, 'servers' => array( array( 'host' => 'localhost', 'port' => 11211, 'persistent' => true, 'weight' => 1, 'timeout' => 1 ) /* Multiple servers can be added */ ) ) )); $val = Firelit\Cache::get('randomValue', function() { // If cache miss, this closure will execute this closure, storing the returned value in cache return mt_rand(0, 1000); }); if (Firelit\Cache::$cacheHit) echo 'Cache hit!'; // Set a value to null in order to remove it from cache Firelit\Cache::set('randomValue', null);
控制器
一个用于包装控制器逻辑的最小类。扩展以添加额外的控制器通用方法和静态数据。它还有一个“交接”功能调用,用于简化对控制器对象的调用。
交接语法:Firelit\Controller::handoff(ControllerClassName [, OptionalMethodName [, MethodParameter1 [, ... ]]])
<?php class DashboardController extends Firelit\Controller { public function show($userName) { // This skelton controller method retrieves a view template, populates and renders $data = GetMyData::now(); Firelit\View::quickRender('DashboardView', 'LoggedinLayout', array('name' => $userName)); } } // You could invoke this as you would any class, but the handoff method makes it a one-liner: Firelit\Controller::handoff('DashboardController', 'show', $userName);
加密类
Crypto、CryptoKey和CryptoPackage是使用OpenSSL(基于此文章)的加密/解密辅助类。这些类可以生成加密安全的密钥,并使用行业标准对称加密(RSA)和私钥加密(AES)方案进行加密和解密。
请注意,由于所需处理能力,AES加密不适用于长字符串(80个字符或更多,取决于密钥位数)——它很快变得效率低下。对于较长的字符串,应使用RSA加密明文,并使用AES加密密钥。这正是CryptoPackage在序列化和反序列化主题以快速存储和检索加密存储中任何类型(字符串、对象、数组等)变量时为您所做的。
示例加密/解密用法
<?php $mySecret = 'Super secret!'; // Private key encryption $key = Firelit\CryptoKey::newPrivateKey(); // Can be 1024, 2048 or 3072-bit $crypto = new Firelit\Crypto($key); $ciphertext = $crypto->encrypt($mySecret)->with(Firelit\Crypto::PUBLIC_KEY); $plaintext = $crypto->decrypt($ciphertext)->with(Firelit\Crypto::PRIVATE_KEY); // Symmetric key encryption $key = Firelit\CryptoKey::newSymmetricKey(); // Can be 128, 192 or 256-bit $crypto = new Firelit\Crypto($key); $ciphertext = $crypto->encrypt($mySecret); $plaintext = $crypto->decrypt($ciphertext); // Robust, mixed-type private key encryption $key = Firelit\CryptoKey::newPrivateKey(); // Can be 1024, 2048 or 3072-bit $crypto = new Firelit\CryptoPackage($key); $object = (object) array( 'test' => true, 'string' => $mySecret . $mySecret . $mySecret ); $ciphertext = $crypto->encrypt($object)->with(Firelit\Crypto::PUBLIC_KEY); $objectBack = $crypto->decrypt($ciphertext)->with(Firelit\Crypto::PRIVATE_KEY);
DatabaseObject
这是一个无模式的、类似活动记录的类,用于创建、检索和操作数据库行作为对象。为了设置它,为每个表扩展类,指定主键行和其他特殊值行(例如,序列化行、日期/时间行等),以启用内置的预存储和检索值操作。
<?php class Person extends Firelit\DatabaseObject { protected static $tableName = 'People'; // The table name protected static $primaryKey = 'id'; // The primary key for table (array for multiple keys, false if n/a) // Columns that should be automatically php-serialized when using protected static $colsSerialize = array('nicknames'); // Columns that should be automatically JSON-encoded/decoded when using protected static $colsJson = array(); // Columns that should be a DateTime object when loaded from DB protected static $colsDateTime = array('created'); } // Create a new person $newPerson = Person::create(array( 'name' => 'Sally', 'email' => 'sally@example.com', 'nicknames' => array('Sal'), 'created' => new DateTime() )); // Find by the primary key $person = Person::find(23); // Returns FALSE if not found if (!$person) die('Not found'); // Serialized columns are serialized before being saved and unserialized on retrieval $person->nicknames = array( 'Bill', 'Will', 'William' ); // Easily save to database (uses primary key set during retrieval) $person->save(); // Or find rows by other columns $persons = Person::findBy('email', 'test@test.com'); // DatabaseObject::findBy returns an iterable object (Firelit\QueryIterator) for search results foreach ($persons as $person) { // DateTime columns are converted to DateTime objects on retrieval echo $person->name .' was created '. $person->created->format('n/j/y') . PHP_EOL; }
HttpRequest
一个用于管理对新HTTP请求和网站的类。包括基于文件的cookie支持。
示例用法
<?php Firelit\HttpRequest::config(array( 'userAgent' => 'My little user agent string' )); $http = new Firelit\HttpRequest(); $http->enableCookies(); // 'get', 'post' and 'other' (for put, delete, etc) are also available methods $http->get('http://www.google.com/'); // Hmmm, I wonder what cookies Google sets... echo '<pre>'. file_get_contents($http->cookieFile) .'</pre>';
Query
一个数据库交互类和SQL查询创建器。使数据库连接管理和SQL编写变得稍微容易一些。
示例用法
<?php // One-time connection setup Firelit\Registry::set('database', array( 'type' => 'mysql', 'name' => 'database', 'host' => 'localhost', // Hostname or IP acceptable here 'port' => '3306', // Can be left undefined to use default port 'user' => 'username', 'pass' => 'password' )); // Or specify the DSN string for PDO to connect to other types of databases Firelit\Registry::set('database', array( 'type' => 'other', 'dsn' => 'sqlite::memory:' )); /* Alternatively, database settings can be specified using the following environmental variables: - DB_NAME - DB_HOST - DB_PORT - DB_USER - DB_PASS */ $q = new Firelit\Query(); $q->insert('TableName', array( /* columnName => value */ 'name' => $name, 'state' => $state )); if (!$q->success()) die('It did not work :('); $q->query("SELECT * FROM `TableName` WHERE `name`=:name", array('name' => $name)); while ($row = $q->getRow()) echo $row['name'] .': '. $row['state'] .'<br>';
使用config方法设置数据库连接
config( $configArray );
用于构建和执行查询的方法
query( $sql, [ $dataArray ]);
insert( $tableName, $dataArray );
replace( $tableName, $dataArray );
select( $tableName, [ $selectFieldsArray, [ $whereStatement, [ $whereDataArray, [ $limit, [ $range ]]]]] );
update( $tableName, $dataArray, $whereStatement, [ $whereDataArray, [ $limit, [ $range ]]] );
delete( $tableName, $whereStatement, [ $whereDataArray, [ $limit, [ $range ]]] );
用于获取查询状态和/或结果的方法
getRes();
如果查询成功执行返回truegetRow();
从成功的select查询返回下一行数据getAll();
从成功的select查询返回所有数据行getNewId();
从新插入的数据行返回新IDgetAffected();
返回受查询影响的行数getNumRows();
返回select查询返回的数据行数(对于所有数据库可能不可靠)getError();
返回错误消息getErrorCode();
返回错误代码success();
如果查询成功执行返回truelogError(LogEntry $logger, $file, $line);
是一个辅助方法,用于记录任何查询错误
QueryIterator
一个PHP 迭代器,允许在不实际预检索所有结果的情况下传递Query结果集。QueryIterator对象然后可以在foreach
循环中使用,其中它按需获取所需的下一行。
示例用法
<?php function demo($type) { $q = new Firelit\Query(); $q->query("SELECT * FROM `TableName` WHERE `type`=:type", array('type' => $type)); return new Firelit\QueryIterator($q); } $results = demo('best_ones'); foreach ($results as $index => $value) { // Do something! }
QueryIterator构造函数接受两个参数,第二个是可选的:Query对象和应从中检索表行的对象。
Request
一个类,它捕获传入的HTTP请求作为一个单一的对象,并执行任何必要的初步工作。围绕请求中的所有重要参数提供了一个很好的类包装,并允许轻松清理。
示例用法
<?php $req = new Firelit\Request::init( function(&$val) { // Remove any invalid UTF-8 characters from $_POST, $_GET and $_COOKIE Firelit\Strings::cleanUTF8($val); }); // Filtered $_POST, $_GET and $_COOKIE parameters can then be accessed via the object if ($req->get['page'] == '2') showPageTwo();
示例用法
<?php // Handle JSON body parsing and PUT requests automatically $req = new Firelit\Request::init(false, 'json'); // Filtered $_POST, $_GET and $_COOKIE parameters can then be accessed via the object $newName = $req->put['name'];
可用属性
cli
如果页面是从命令行界面加载的,则返回truecookie
返回所有数据(按指定过滤),最初通过$_COOKIE可用get
返回所有数据(按指定过滤),最初通过$_GET可用headers
返回所有HTTP头部的数组(如果使用Apache作为Web服务器)host
设置为HTTP请求中指定的主机method
设置为HTTP请求方法(例如,'POST'、'PUT'等)path
设置为请求的路径(例如,'/folder/test.php')post
将返回所有通过 $_POST 可用(根据指定过滤)的数据。protocol
将返回请求协议(例如,HTTP 1.0 或 HTTP 1.1)。proxies
将返回一个可能用作代理的 IP 地址数组。put
将返回 HTTP 请求体中所有数据(根据指定过滤)(如果为 PUT 请求)。referer
将返回客户端指定的 HTTP 引用。secure
如果连接是安全的(即,'HTTPS://'),将返回 true。uri
将返回请求的完整 URI,包括 HTTP 或 HTTPS。
响应
一个管理服务器对传入请求的响应的类。默认启用输出缓冲。包括辅助函数,这些函数可以更轻松地更改 HTTP 响应代码和执行重定向。请注意,ApiResponse 类继承自此类,以利用其响应管理。
可用方法
contentType()
可以用来设置响应的内容类型(例如,'application/json')。redirect()
可以用来将访客重定向到另一个 URI。setCallback()
可以用来设置一个回调函数,在发送之前处理服务器输出。setCode()
可以用来设置 HTTP 响应代码(例如,404)。
会话
会话管理类,可以使用 PHP 的原生会话功能(以及可选的数据库存储)。您可以为会话对象设置任何属性名,并动态保存(使用魔法获取器和设置器方法)。实现 PHP 原生的 SessionHandlerInterface 以创建自己的会话处理程序或会话存储引擎。此库提供名为 Firelit\DatabaseSessionHandler 的数据库实现。通过实现 SessionHandlerInterface 并在实例化 Session 对象时使用此类对象来创建自己的会话处理程序。或者,不指定此参数,以简单地使用 PHP 内置的基于 cookie 和文件的会话处理。
请注意,如果您使用 Firelit\DatabaseSessionHandler,会话的过期不是由 session.gc_maxlifetime
控制的,就像您在没有使用会话处理程序的情况下使用 Session 类一样。
示例用法
<?php $sess = new Firelit\Session::init(new Firelit\DatabaseSessionHandler); $sess->loggedIn = true; $sess->userName = 'Peter'; echo '<p>Hello '. htmlentities($sess->userName) .'</p>';
字符串
一组字符串辅助函数封装在一个类中。
示例用法
<?php // Check if an email is valid $valid = Firelit\Strings::validEmail('test@test.com'); // $valid == true // Clean the strings in the array for all valid UTF8 Firelit\Strings::cleanUTF8($_POST); // The parameter is passed by reference and directly filtered // Normalize the formatting on a name or address $out = Firelit\Strings::nameFix('JOHN P. DePrez SR'); // $out == 'John P. DePrez Sr.' $out = Firelit\Strings::addressFix('po box 3484'); // $out == 'PO Box 3484' // Multi-byte HTML and XML escaping $out = Firelit\Strings::html('You & I Rock'); // $out == 'You & I Rock' $out = Firelit\Strings::xml('You & I Rock'); // $out == 'You & I Rock' // Format the string as a CSV cell value (escaping quotes with a second quote) $out = Firelit\Strings::csv('John "Hairy" Smith'); // $out == '"John ""Hairy"" Smith"' // Multi-byte safe string case maniuplation $out = Firelit\Strings::upper('this started lower'); // $out == 'THIS STARTED LOWER' $out = Firelit\Strings::lower('THIS STARTED UPPER'); // $out == 'this started upper' $out = Firelit\Strings::title('this STARTED mixed'); // $out == 'This Started Mixed' $out = Firelit\Strings::ucwords('this STARTED mixed'); // $out == 'This STARTED Mixed'
变量
一个用于管理应用程序级别持久变量的类。Vars 通过魔法设置器和获取器实现,因此您可以使用任何名称为您的变量,并使用任何类型的持久数据存储。存储可以通过创建自定义获取器和设置器函数(例如,用于将值读取/写入文件)自定义定义,或者您可以将其保留为默认设置(将值存储在数据库中)。
示例用法
<?php // Configuration new Firelit\Vars::init(array( 'table' => 'Vars', 'col_name' => 'Name', 'col_value' => 'Value' )); // Later usage $vars = new Firelit\Vars::init(); // Set a persistent application variable with any name accepted by your store $vars->maintenanceMode = true; // Read a persistent application variable if ($vars->maintenanceMode) die('Sorry, under construction.');
视图
一个用于管理视图的类:视图模板、视图布局(包裹视图模板)、部分(用于其他地方使用的视图的一部分)和资产管理(自动将所需资产插入到 HTML 中)。
布局类似于视图模板,其中视图模板位于其中。它们通常包含围绕更具体视图元素的重复 HTML 包装器。布局是一个可选组件。如果没有指定布局,则单独渲染视图模板。
以下是一个布局示例,保存为 views\layouts\main.php
。
<?php if (!is_object($this)) die; ?> <!-- Prevent direct calls to view files --> <html> <head> <title>Example Layout</title> </head> <body> <?php $this->yieldNow(); ?> <!-- Firelit\View::yieldNow() specifies the place for the view template --> </body> </html>
现在是一个视图文件示例,保存为 views\templates\dashboard.php
。
<?php if (!is_object($this)) die; ?> <!-- Prevent direct calls to view files --> <div id="user-info"> <?=htmlentities($name); ?> </div> <div id="main"> <h1>Dashboard</h1> <p>Lorem Ipsum</p> <?php $this->includePart('partials\stuff'); ?> <!-- Firelit\View::includePart() brings in other view templates --> </div>
当调用视图时,使用在视图中使用的数据(如上例中的 $name
所示)通过关联数组指定。
<?php // The view folder can be changed with a static property. The php extension is added if not supplied. $view = new Firelit\View('templates\dashboard', 'layouts\main'); // Here the view is sent to the client // The data to be available in the view is given as an array $view->render(array('name' => 'John'));