aalfiann/filebase

一个简单但强大的平面文件数据库存储。

1.0.16 2019-03-12 19:23 UTC

This package is auto-updated.

Last update: 2024-09-13 10:31:57 UTC


README

Version Total Downloads License

此项目是从filebase/Filebase分叉而来,基于核心版本1.0.20,我没有为原始项目做出贡献,因为我有其他的计划,需要重构并且可能会破坏原始项目。

这个项目的计划是什么?

  • 重构代码以实现高性能和低内存占用
  • 专注于优化大数据量中的数据
  • 仅更新安全补丁或关键错误
  • 新功能将遵循原始项目

版本号已更改

我从核心版本1.0.20开始重构filebase/Filebase,然后我再次发布新版本1.0.0

一个简单但强大的平面文件数据库存储。无需MySQL或昂贵的SQL服务器,实际上,你只需要你的当前网站或应用程序设置。所有数据库条目都存储在文件中(格式化成你喜欢的样子)。

你甚至可以直接修改文件中的原始数据,而无需使用API。更好的是,你可以将所有文件放在版本控制中,并传递给团队,而无需同步SQL数据库。

这难道听起来不酷吗?

使用Filebase,你可以完全控制。按你想要的方式设计你的数据结构。像你在PHP中一样使用数组和对象。使用版本控制更新和与他人共享你的数据。只需记住,升级你的Web/Apache服务器要比数据库服务器便宜得多。

支持PHP 5.6PHP 7+

特性

Filebase设计简单,但具有足够的功能来满足更高级的需求。

安装

使用Composer安装包。

运行composer require aalfiann/Filebase:^1.0

如果你不想使用composer,下载文件,并在你的应用程序中包含它,它没有任何依赖,你只需要保持它与未来的发布保持更新。

用法

// setting the access and configration to your database
$database = new \Filebase\Database([
    'dir' => 'path/to/database/dir'
]);

// in this example, you would search an exact user name
// it would technically be stored as user_name.json in the directories
// if user_name.json doesn't exists get will return new empty Document
$item = $database->get('kingslayer');

// display property values
echo $item->first_name;
echo $item->last_name;
echo $item->email;

// change existing or add new properties
$item->email = 'example@example.com';
$item->tags  = ['php','developer','html5'];

// need to save? thats easy!
$item->save();


// check if a record exists and do something if it does or does not
if ($database->has('kingslayer'))
{
    // do some action
}


// Need to find all the users that have a tag for "php" ?
$users = $db->query()->where('tags','IN','php')->results();

// Need to search for all the users who use @yahoo.com email addresses?
$users = $db->query()->where('email','LIKE','@yahoo.com')->results();

(1) 配置选项

在定义你的数据库时,配置是必需的。选项是可选的,因为它们有默认值。

用法示例(所有选项)

$db = new \Filebase\Database([
    'dir'            => 'path/to/database/dir',
    'backupLocation' => 'path/to/database/backup/dir',
    'format'         => \Filebase\Format\Json::class,
    'cache'          => true,
    'cache_expires'  => 60,
    'pretty'         => false,
    'safe_filename'  => true,
    'read_only'      => false,
    'validate' => [
        'name'   => [
            'valid.type' => 'string',
            'valid.required' => true
        ]
    ]
]);

(2) 格式化

格式类定义了数据库文件中数据的编码和解码。

你可以编写自己的或者更改配置中的现有格式类。类中的方法必须是静态的,并且类必须实现\Filebase\Format\FormatInterface

默认格式类:JSON

\Filebase\Format\Json::class

其他格式类:YAML

\Filebase\Format\Yaml::class

(3) GET(和方法)

在加载了数据库配置之后,你可以使用get()方法检索单个数据文档。

如果文档不存在,它将为您创建一个空对象来存储数据。然后您可以调用 save() 方法,它会创建文档(或更新现有文档)。

// my user id
$userId = '92832711';

// get the user information by id
$item = $db->get($userId);

get() 返回 \Filebase\Document 对象,并具有您可以使用自己的方法。

示例

// get the timestamp when the user was created
echo $db->get($userId)->createdAt();

// grabbing a specific field "tags" within the user
// in this case, tags might come back as an array ["php","html","javascript"]
$user_tags = $db->get($userId)->field('tags');

// or if "tags" is nested in the user data, such as about[tags]
$user_tags = $db->get($userId)->field('about.tags');

// and of course you can do this as well for getting "tags"
$user = $db->get($userId);
$user_tags = $user->tags;
$user_tags = $user->about['tags'];

(4) 创建 | 更新 | 删除

如上例所示,它非常简单。使用 $item->save(),默认情况下,save() 方法将创建或更新现有文档。它将通过 createdAtupdatedAt 记录所有更改。如果您想替换单个文档中的所有数据,请在 save($data) 方法中传递新数据,否则不要传递任何数据以允许它保存当前实例。

// SAVE or CREATE
// this will save the current data and any changed variables
// but it will leave existing variables that you did not modify unchanged.
// This will also create a document if none exist.
$item->title = 'My Document';
$item->save()

// This will replace all data within the document
// Allows you to reset the document and put in fresh data
// Ignoring any above changes or changes to variables, since
// This sets its own within the save method.
$item->save([
    'title' => 'My Document'
]);

// DELETE
// This will delete the current document
// This action can not be undone.
$item->delete();

(5) 数据库方法

$db = new \Filebase\Database($config);

以下是您可以在数据库类上使用的列表。

示例

$users = new \Filebase\Database([
    'dir' => '/storage/users',
]);

// displays number of users in the database
echo $users->count();


// Find All Users and display their email addresses

$results = $users->findAll();
foreach($results as $user)
{
    echo $user->email;

    // you can also run GET methods on each user (document found)
    // Displays when the user was created.
    echo $user->createdAt();
}


// deletes all users in the database
// this action CAN NOT be undone (be warned)
$users->flush(true);

(6) 验证(可选)

调用 save() 方法时,将检查文档的验证规则(如果已设置)。这些规则必须通过,文档才能保存。

$db = new \Filebase\Database([
    'dir' => '/path/to/database/dir',
    'validate' => [
        'name'   => [
            'valid.type' => 'string',
            'valid.required' => true
        ],
        'description' => [
            'valid.type' => 'string',
            'valid.required' => false
        ],
        'emails' => [
            'valid.type'     => 'array',
            'valid.required' => true
        ],
        'config' => [
            'settings' => [
                'valid.type'     => 'array',
                'valid.required' => true
            ]
        ]
    ]
]);

在上面的示例中,namedescriptionemailsconfig 数组键将替换为您自己的键,这些键与您的数据匹配。注意,config 有一个嵌套数组 settings,是的,您可以对验证进行嵌套。

验证规则

(7) 自定义过滤器

注意:自定义过滤器仅在单个文档上运行

项目过滤器允许您自定义结果,并在同一文档中进行简单的查询。如果您在一个文档中有项目数组,这些过滤器非常棒。比如说,您将“用户”存储在 users.json 中的数组,那么您可以创建一个过滤器来显示所有具有特定标签或字段匹配特定值的用户。

此示例将输出所有被阻止的用户电子邮件。

// Use [data] for all items within the document
// But be sure that each array item uses the same format (otherwise except isset errors)

$users = $db->get('users')->filter('data','blocked',function($item, $status) {
    return (($item['status']==$status) ? $item['email'] : false);
});

// Nested Arrays?
// This uses NESTED properties. If the users array was stored as an array inside [list]
// You can also use `.` dot delimiter to get arrays from nested arrays

$users = $db->get('users')->filter('list.users','blocked',function($item, $status) {
    return (($item['status']==$status) ? $item['email'] : false);
});

(8) 查询

查询允许您搜索多个文档,并只返回符合您标准的结果。

如果启用了缓存,查询将使用 findAll() 并将结果缓存起来以供下次运行。

// Simple (equal to) Query
// return all the users that are blocked.
$users = $db->query()->where(['status' => 'blocked'])->results();

// Stackable WHERE clauses
// return all the users who are blocked,
// AND have "php" within the tag array
$users = $db->query()
    ->where('status','=','blocked')
    ->andWhere('tag','IN','php')
    ->results();

// You can also use `.` dot delimiter to use on nested keys
$users = $db->query()->where('status.language.english','=','blocked')->results();

// Limit Example: Same query as above, except we only want to limit the results to 10
$users = $db->query()->where('status.language.english','=','blocked')->limit(10)->results();



// Query LIKE Example: how about find all users that have a gmail account?
$usersWithGmail = $db->query()->where('email','LIKE','@gmail.com')->results();

// OrderBy Example: From the above query, what if you want to order the results by nested array
$usersWithGmail = $db->query()
                    ->where('email','LIKE','@gmail.com')
                    ->orderBy('profile.name', 'ASC')
                    ->results();

// or just order the results by email address
$usersWithGmail = $db->query()
                    ->where('email','LIKE','@gmail.com')
                    ->orderBy('email', 'ASC')
                    ->results();

// OrderBy can be applied multiple times to perform a multi-sort
$usersWithGmail = $db->query()
                    ->where('email','LIKE','@gmail.com')
                    ->orderBy('last_name', 'ASC')
                    ->orderBy('email', 'ASC')
                    ->results();


// this will return the first user in the list based on ascending order of user name.
$user = $db->query()->orderBy('name', 'ASC')->first();
// print out the user name
echo $user['name'];

// You can also order multiple columns as such (stacking)
$orderMultiples = $db->orderBy('field1','ASC')
                     ->orderBy('field2','DESC')
                     ->results();


// What about regex search? Finds emails within a field
$users = $db->query()->where('email','REGEX','/[a-z\d._%+-]+@[a-z\d.-]+\.[a-z]{2,4}\b/i')->results();


// Find all users that have gmail addresses and only returning their name and age fields (excluding the rest)
$users = $db->query()->select('name,age')->where('email','LIKE','@gmail.com')->results();

// Instead of returning users, how about just count how many users are found.
$totalUsers = $db->query()->where('email','LIKE','@gmail.com')->count();


// You can delete all documents that match the query (BULK DELETE)
$db->where('name','LIKE','john')->delete();

// Delete all items that match query and match custom filter
$db->where('name','LIKE','john')->delete(function($item){
    return ($item->name == 'John' && $item->email == 'some@mail.com');
});


// GLOBAL VARIABLES

// ability to sort the results by created at or updated at times
$documents = $db->orderBy('__created_at', 'DESC')->results();
$documents = $db->orderBy('__updated_at', 'DESC')->results();

// search for items that match the (internal) id
$documents = $db->where('__id', 'IN', ['id1', 'id2'])->results();

要运行查询,请使用 results() 或如果只想返回第一个项目,请使用 first()

查询方法

这些方法是可选的,并且是可堆叠的

以下 方法执行查询 并返回结果 (不要同时使用它们)

比较运算符

(9) 缓存

如果启用了缓存,它将自动将查询结果存储在数据库目录的子目录中。

缓存查询只有在特定保存的缓存小于过期时间时才会使用,否则它将使用实时数据并自动替换下次使用的现有缓存。

(10) 数据库备份

默认情况下,您可以使用 $db->backup()->create() 备份您的数据库,这将根据您的 dir 路径创建整个数据库的 .zip 文件。

方法

当在您的 Database 上调用 backup() 时,可以使用以下方法。

  • create() 创建数据库备份(在您的备份位置 .zip
  • clean() 清除所有现有备份(您的备份位置中的 .zip 文件)
  • find() 返回所有现有备份的 array(数组键为创建备份时的 time()
  • rollback() 恢复现有备份(最新可用),替换现有数据库 dir

示例

// invoke your database
$database = new \Filebase\Database([
    'dir' => '/storage/users',
    'backupLocation' => '/storage/backup',
]);

// create a new backup of your database
// will look something like /storage/backup/1504631092.zip
$database->backup()->create();

// delete all existing backups
$database->backup()->clean();

// get a list of all existing backups (organized from new to old)
$backups = $database->backup()->find();

// restore an existing backup (latest backup available)
$database->backup()->rollback();

为什么是 Filebase?

Filebase 是为了灵活地帮助管理简单数据存储而构建的,无需处理重量级的数据库引擎。Filebase 的概念是提供非常直观的 API 方法,并使开发者能够轻松维护和管理(即使在大型规模上)。

FlywheelFlinetone的启发。

版本是如何工作的

版本格式如下:主版本.次版本.修补版本

  • 主版本:完全使用全新代码库的重写。
  • 次版本:引入新功能/变更,可能导致不兼容。
  • 修补版本:引入新功能/修复,不会导致不兼容。

Filebase将尽力在可能的情况下保持向后兼容。

使用Filebase的网站和用户

如果您正在使用Filebase,请提交一个pull request,我们将在此处添加您的项目。

贡献

任何人都可以为Filebase做出贡献。请在发现意外情况时发布问题,或提交pull request以进行改进。

许可协议

Filebase是开源软件,采用MIT许可协议