xeoncross / acrud
基于模式智能自动验证的自动数据库脚手架(适用于 MySQL、SQLite 及 PostgreSQL)
Requires
- php: >=5.3.0
This package is not auto-updated.
Last update: 2024-09-14 14:46:40 UTC
README
年复一年,我们构建数据库模式、通过模型或 ORM 的 CRUD,以及验证库以确保只有有效数据存储在我们的数据库中。基本上,我们反复写相同的代码。
如果电脑可以直接查看数据库并自行解决怎么办?如果我们能简单地开始将 HTML 表单数据传递到后端并相信它能为我们提供安全保障怎么办?如果我们能请求它并提供一个漂亮的 JSON 结果数组怎么办?
这个项目就是对这个目标的初步尝试。
ACRUD 是一个尝试使用 MySQL、SQLite 和 PostgreSQL* 提供的关于自身的数据在 PHP 中创建自动脚手架系统的尝试。
这使得您可以设计一个模式,并立即开始原型设计和构建您的前端应用程序。当您接近发布并想为您的数据添加更细粒度的控制和验证时,您也可以这样做。
Composer 快速入门
将以下内容添加到您的 composer.json
配置文件中,然后运行 composer install
。
{
"require" : {
"xeoncross/acrud": "dev-master"
}
}
在您的项目中包含 composer 自动加载器。
<?php
require('vendor/autoload.php');
然后只需将 PDO 对象传递给 ACRUD 实例工厂。
$pdo = new PDO(
'sqlite:testdb.db',
0,
0,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ
)
);
$acrud = \ACRUD\Instance::factory($pdo);
$errors = $acrud->validate('user', $_POST['user']);
if($errors) {
die(print_r($errors));
} else {
$acrud->save('user', $_POST['user']);
}
如果您想深入了解更多元数据,这些方法将提供有关您模式更多详细信息。
$tables = $acrud->getTables();
$foreignKeys = $acrud->getForeignKeys();
$columns = $acrud->getColumns();
自包含的 ACRUD API 服务器
假设您有一个类似 http://example.com
的网站(或者如果您知道如何使用虚拟主机,则可以是 http://example.loc
)。将 ACRUD 检出到一个子文件夹,如 http://example.com/acrud
。
设置一个重写规则,将所有流量转发到 acrud.php
。如果您使用 Nginx,以下内容应该适用
location /acrud {
rewrite ^/acrud/(.*)$ /acrud/acrud.php/$1 break;
}
对于所有较旧的 Apache 用户,以下内容可能适用。
.htaccess
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/acrud/(.*)$ acrud/acrud.php [L,QSA]
acrud.php
在 /acrud
文件夹中创建一个名为 acrud.php
的文件,并将以下内容粘贴到其中。
<?php
// If using Composer
require("vendor/autoload.php");
/* Or if you downloaded ACRUD manually and pasted it into that folder
spl_autoload_register(function ($class) {
require __DIR__ . '/acrud/' . str_replace('\\', '/', $class) . '.php';
});
*/
function getACRUD()
{
// Create a new PDO connection
$pdo = new PDO(
'mysql:dbname=croscon_start;host=localhost',
'root',
'',
array(
\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_OBJ,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
)
);
return \ACRUD\Instance::factory($pdo);
}
$router = new \ACRUD\Router('/acrud');
$router->route('tables(/meta)?', function($app_path, $meta = false)
{
$acrud = getACRUD();
$columns = $acrud->getColumns();
if($meta) {
return $columns;
} else {
return array_keys($columns);
}
});
$router->route('fields/(\w+)', function($app_path, $table)
{
$acrud = getACRUD();
$columns = $acrud->getColumns();
if( ! isset($columns[$table])) {
throw new Exception("Table $table doesn't exist");
}
return $columns[$table];
});
$router->route('fetch/(\w+)/(\d+)/(\d+)', function($app_path, $table, $limit, $offset)
{
$acrud = getACRUD();
$columns = $acrud->getColumns();
if( ! isset($columns[$table])) {
throw new Exception("Table $table doesn't exist");
}
return $acrud->fetch("SELECT * FROM $table LIMIT $limit OFFSET $offset");
});
$router->route('save', function($app_path)
{
if(empty($_POST)) {
throw new Exception("No data provided");
}
$acrud = getACRUD();
$columns = $acrud->getColumns();
$validation = array();
$records = array();
foreach($_POST as $table => $rows) {
if( ! isset($columns[$table])) {
throw new Exception("Table $table doesn't exist");
}
$records[$table] = array();
foreach($rows as $i => $row) {
if($errors = $acrud->validate($table, $row, $columns[$table])) {
if( ! isset($validation[$table])) {
$validation[$table] = array();
}
$validation[$table][$i] = $errors;
} else {
$records[$table][$i] = $acrud->save($table, $row, $columns[$table]);
}
}
}
if($validation) {
header('HTTP/1.0 400 Bad Request');
}
return array(
'validation' => $validation,
'records' => $records,
'ok' => ! $validation
);
});
$router->run();
// If we made it this far, we didn't find a matching route
header('HTTP/1.0 404 Not Found');
echo "<h1>404 Not Found</h1>";
echo "The page that you have requested could not be found.";
exit();