xeoncross/acrud

基于模式智能自动验证的自动数据库脚手架(适用于 MySQL、SQLite 及 PostgreSQL)

dev-master 2016-09-01 15:33 UTC

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();

开始测试吧!