palepupet / dbjsonbased
一个轻量级的PHP库,可以将JSON文件用作数据库。当您不想使用重型武器或需要快速设置数据持久性时,非常实用。
Requires (Dev)
- phpunit/phpunit: ^10.2
This package is not auto-updated.
Last update: 2024-09-23 15:16:23 UTC
README
一个轻量级的PHP库,可以将JSON文件用作数据库。当您不想使用重型武器或需要快速设置数据持久性时,非常实用。
安装
composer require palepupet/dbjsonbased
使用
初始化
$jsonDb = new DbJsonBased("path_of_the_db_without_json_extension");
然后您需要创建数据库的文件,使用 DbJsonBasedStructureInterface 来完成。您必须提供一个结构,并使用 DbJsonBasedStructureInterface 作为参数。 DbJsonBasedStructure 类实现了它,并提供了所有必要的检查方法。
$jsonDb->createDb(new DbJsonBasedStructure(string $tableName, array $columns));
简而言之,您可以这样做
$jsonDb = new DbJsonBased("customersDb"); $datasStructure = new DbJsonBasedStructure("Customers", [ "first_name" => DbJsonBasedStructure::TYPE_STRING, "last_name" => DbJsonBasedStructure::TYPE_STRING, "size" => DbJsonBasedStructure::TYPE_FLOAT, "age" => DbJsonBasedStructure::TYPE_INT, ... ]); $jsonDb->createDb($datasStructure);
所有接受的类型都是 布尔型、浮点型、整型 和 字符串型。如果您愿意,可以使用提供的类常量。
DbJsonBasedStructure::TYPE_BOOLEAN DbJsonBasedStructure::TYPE_FLOAT DbJsonBasedStructure::TYPE_INT DbJsonBasedStructure::TYPE_STRING
创建的文件将如下所示。每个数据库文件都将被编码为json格式。
{ "CUSTOMERS":{ "COLUMNS":{ "FIRST_NAME":"string", "LAST_NAME":"string", "SIZE":"float", "AGE":"int" }, "VALUES":[], "ID":null } }
您可以使用 Utils::getContentAndDecode(string $pathOfDbFile) 方法获取整个文件并将其解码。
array(1) { ["CUSTOMERS"] => array(3) { ["COLUMNS"] => array(4) { ["FIRST_NAME"] => string(6) "string" ["LAST_NAME"] => string(6) "string" ["SIZE"] => string(4) "float" ["AGE"] => string(3) "int" } ["VALUES"] => array(0) {} ["ID"] => NULL } }
注意:但是,如果您只想检索或操作某个元素,例如 TABLENAME、COLUMNS、VALUES、ID 等一些方法,这些方法更合适。
您可以在一个文件中创建任意多的结构。要向现有文件添加新结构,只需使用上述函数并使用不同的结构名称即可。
// Adding the 2nd structure $datasStructure2 = new DbJsonBasedStructure("Address", [ "name" => DbJsonBasedStructure::TYPE_STRING, "street" => DbJsonBasedStructure::TYPE_STRING, "zip_code" => DbJsonBasedStructure::TYPE_STRING, "city" => DbJsonBasedStructure::TYPE_STRING, ... ]); $jsonDb->createDb($datasStructure2); // Now we have 2 structures into the same file array(2) { ["CUSTOMERS"] => array(3) { ["COLUMNS"] => array(4) { ["FIRST_NAME"] => string(6) "string" ["LAST_NAME"] => string(6) "string" ["SIZE"] => string(4) "float" ["AGE"] => string(3) "int" } ["VALUES"] => array(0) {} ["ID"] => NULL }, ["ADDRESS"] => array(3) { ["COLUMNS"] => array(4) { ["NAME"] => string(6) "string" ["STREET"] => string(6) "string" ["ZIP_CODE"] => string(6) "string" ["CITY"] => string(6) "string" } ["VALUES"] => array(0) {} ["ID"] => NULL } }
插入数据
注意:在插入数据之前,您必须创建数据库的结构。
insert(DbJsonBasedDataInterface $datas) 插入作为参数传递的数据,使用 DbJsonBasedDataInterface 来完成。您可以使用实现了所有必要检查方法的 DbJsonBasedData 类。
$datas = new DbJsonBasedData($jsonDb, "Customers", [ [ "first_name" => "John", "last_name" => "Doe", "size" => 175.50, "age" => 21, ], [ "first_name" => "Neo", "last_name" => "Trinitron", "size" => 184.20, "age" => 33, ] ]); $jsonDb->insert($datas);
更新数据
update(DbJsonBasedDataInterface $datas) 仅更新在参数中指定的数据。其他数据将保持不变。更新使用 DbJsonBasedDataInterface 作为创建数据库结构,这允许在表、字段上进行相同的检查。因此,更新数据时也必须使用 DbJsonBasedData 类。
注意:您绝对必须提供实体ID(与数据一起)以进行修改。没有它,将无法找到要修改的实体。
// 'Entity' datas ["id" => 0, "first_name" => "John", "last_name" => "Doe", "size" => 175.50, "age" => 21], ["id" => 1, "first_name" => "Neo", "last_name" => "Trinitron", "size" => 184.20, "age" => 33], ["id" => 2, "first_name" => "Alan", "last_name" => "Turingstone", "size" => 170.30, "age" => 45], ["id" => 3, "first_name" => "Luke", "last_name" => "Skylogger", "size" => 173.80, "age" => 18] // Update the entity with the ID 1 $datasToUpdate = new DbJsonBasedData($jsonDb, "customers", [ [ "last_name" => "Turingstone", "age" => 55, "id" => 1 ] ]); $jsonDb->update($datasToUpdate); // result ["id" => 0, "first_name" => "John", "last_name" => "Doe", "size" => 175.50, "age" => 21], ["id" => 1, "first_name" => "Neo", "last_name" => "Turingstone", "size" => 184.20, "age" => 55], // modified datas ["id" => 2, "first_name" => "Alan", "last_name" => "Turingstone", "size" => 170.30, "age" => 45], ["id" => 3, "first_name" => "Luke", "last_name" => "Skylogger", "size" => 173.80, "age" => 18]
如果您要修改多个实体,可以添加必要的数组。每个数组包含要进行的修改。
// Update multiple entities $datasToUpdate = new DbJsonBasedData($jsonDb, "customers", [ [ "first_name" => "Neo", "age" => 45, "id" => 0 ], [ "last_name" => "Doe", "size" => 32, "id" => 1 ], [ "age" => 25, "id" => 2 ] ]); $jsonDb->update($datasToUpdate);
删除数据
remove(string $tableName, ?int $idToRemove, bool $removeAllTableNameValues = false) DbJsonBased提供了几种数据删除选项,具体取决于您的需求。一个函数将这些选项集中在一起。仅使用参数配置您需要的删除。
- 您可以从表中删除单个实体 remove('Customers', 1)。在这种情况下,您将删除ID为1的'Customer'表中的实体。如果以上述插入函数中插入的数据为基础,删除后将如下所示的数据:
// 'Entity' datas ["id" => 0, "first_name" => "John", "last_name" => "Doe", "size" => 175.50, "age" => 21], ["id" => 1, "first_name" => "Neo", "last_name" => "Trinitron", "size" => 184.20, "age" => 33], // result array(1) { [0] => array(5) { ["FIRST_NAME"] => string(4) "John" ["LAST_NAME"] => string(3) "Doe" ["SIZE"] => float(175.5) ["AGE"] => int(21) ["ID"] => int(0) } }
- 您可以删除表中的所有值。如果您这样做,将重置所有已存在的值,remove('Customers', null, true)。如果您想使用此删除,不要提供任何ID。
注意:这样做将删除表中的所有值。一旦操作完成,您将无法恢复已删除的数据。
添加列
addColumn(DbJsonBasedStructureInterface $structure) 向您的结构和数据添加列。添加列使用 DbJsonBasedStructureInterface 利用结构检查。您可以使用实现了此接口的 DbJsonBasedStructure 类。
注意:在您的数据中添加列、插入缺失的列。但是,您的数据将添加NULL值。您需要更新它们以使用所需的值。
// 'Entity' columns ["ID" => "int", "FIRST_NAME" => "string", "LAST_NAME" => "string"] // Adding new columns $addColumns = new DbJsonBasedStructure( "customers", [ "actif" => DbJsonBasedStructure::TYPE_BOOLEAN, "address" => DbJsonBasedStructure::TYPE_STRING, ] ); $jsonDb->addColumn($addColumns); // result columns ["ID" => "int", "FIRST_NAME" => "string", "LAST_NAME" => "string", "ACTIF" => "bool", "ADDRESS" => "string"] // result datas with NULL value ["id" => 0, "first_name" => "John", "last_name" => "Doe", "actif" => NULL, "address" => NULL], ["id" => 1, "first_name" => "Neo", "last_name" => "Turingstone", "actif" => NULL, "address" => NULL]
删除列
removeColumn(string $tableName, array $removedColumns) 如果您发现某一列变得不再必要或您想删除错误添加的列,可以使用此方法。此方法允许您删除每个数据中的列,同时也删除表结构部分的列。
注意:如果您删除了列,请注意,任何已删除的数据都无法恢复。它将被永久删除。
// 'Entity' columns ["ID" => "int", "FIRST_NAME" => "string", "LAST_NAME" => "string", "SIZE" => "float", "AGE" => "int"] // 'Entity' datas ["id" => 0, "first_name" => "John", "last_name" => "Doe", "size" => 175.50, "age" => 21], ["id" => 1, "first_name" => "Neo", "last_name" => "Trinitron", "size" => 184.20, "age" => 33], ["id" => 2, "first_name" => "Alan", "last_name" => "Turingstone", "size" => 170.30, "age" => 45], ["id" => 3, "first_name" => "Luke", "last_name" => "Skylogger", "size" => 173.80, "age" => 18] // Deletion of the columns SIZE and AGE $jsonDb->removeColumn("customers", [ "size", "age" ]); // result 'Entity' columns ["ID" => "int", "FIRST_NAME" => "string", "LAST_NAME" => "string"] // result 'Entity' datas ["id" => 0, "first_name" => "John", "last_name" => "Doe"], ["id" => 1, "first_name" => "Neo", "last_name" => "Trinitron"], ["id" => 2, "first_name" => "Alan", "last_name" => "Turingstone"], ["id" => 3, "first_name" => "Luke", "last_name" => "Skylogger"]
更新列
updateColumn(DbJsonBasedStructureInterface $structure) 允许您修改列的类型。更新列使用 DbJsonBasedStructureInterface 以利用结构检查。您可以使用实现此接口的 DbJsonBasedStructure 类。
注意:修改类型允许您在数据库结构中修改类型。然而,您的数据可能不再与新类型一致。因此,您必须根据新类型修改数据。
// 'Entity' columns ["ID" => "int", "FIRST_NAME" => "string", "LAST_NAME" => "string", "SIZE" => "float", "AGE" => "int"] // Update columns $newColumnType = new DbJsonBasedStructure("customers", [ "size" => DbJsonBasedStructure::TYPE_INT, "age" => DbJsonBasedStructure::TYPE_STRING, ] ); $jsonDb->updateColumn($newColumnType); // result 'Entity' columns ["ID" => "int", "FIRST_NAME" => "string", "LAST_NAME" => "string", "SIZE" => "int", "AGE" => "string"]
重命名列
renameColumn(string $tableName, array $renamedColumns) 如果您需要修改数据库结构和数据中列的名称,可以使用此方法。
// 'Entity' columns ["ID" => "int", "FIRST_NAME" => "string", "LAST_NAME" => "string", "SIZE" => "float", "AGE" => "int"] // 'Entity' datas ["id" => 0, "first_name" => "John", "last_name" => "Doe", "size" => 175.50, "age" => 21], ["id" => 1, "first_name" => "Neo", "last_name" => "Trinitron", "size" => 184.20, "age" => 33], ["id" => 2, "first_name" => "Alan", "last_name" => "Turingstone", "size" => 170.30, "age" => 45], ["id" => 3, "first_name" => "Luke", "last_name" => "Skylogger", "size" => 173.80, "age" => 18] // Rename columns $jsonDb->renameColumn("customers", [ "first_name" => "name", "age" => "is_adult" ]); // result 'Entity' columns ["ID" => "int", "NAME" => "string", "LAST_NAME" => "string", "SIZE" => "int", "IS_ADULT" => "string"] // result 'Entity' datas ["id" => 0, "name" => "John", "last_name" => "Doe", "size" => 175.50, "is_adult" => 21], ["id" => 1, "name" => "Neo", "last_name" => "Trinitron", "size" => 184.20, "is_adult" => 33], ["id" => 2, "name" => "Alan", "last_name" => "Turingstone", "size" => 170.30, "is_adult" => 45], ["id" => 3, "name" => "Luke", "last_name" => "Skylogger", "size" => 173.80, "is_adult" => 18]
处理
有几种方法可用于操作数据库。为了查找和获取数据
findOne
findOne(string $tableName, int $id) 返回数据库表中与提供的id相等的第一个数据
// datas ["id" => 0, "first_name" => "John", "last_name" => "Doe", "size" => 175.50, "age" => 21], ["id" => 1, "first_name" => "Neo", "last_name" => "Trinitron", "size" => 184.20, "age" => 33], ["id" => 2, "first_name" => "Alan", "last_name" => "Turingstone", "size" => 170.30, "age" => 45], ["id" => 3, "first_name" => "Luke", "last_name" => "Skylogger", "size" => 173.80, "age" => 18] $jsonDb->findOne("Customers", 1); // result array(1) { [0]=> array(5) { ["ID"] => int(1) ["FIRST_NAME"] => string(3) "Neo" ["LAST_NAME"] => string(9) "Trinitron" ["SIZE"] => float(184.2) ["AGE"] => int(33) } }
findOneBy
findOneBy(string $tableName, array $criteria, bool $caseSensitive = true) 返回数据库表中满足筛选条件的数据。默认情况下,如果没有提供筛选条件,则执行“精确”搜索。所有有效的筛选器为 START_BY、END_BY、CONTAINS 和 EXACT。您可以使用提供的类常量 DbJsonBased::START_BY|END_BY|CONTAINS|EXACT
// datas ["id" => 0, "first_name" => "Andrea", "last_name" => "Baker"], ["id" => 1, "first_name" => "Angela", "last_name" => "Carr"], ["id" => 2, "first_name" => "Stephanie", "last_name" => "Dowd"], ["id" => 3, "first_name" => "stephanie", "last_name" => "Hardacre"] $jsonDb->findOneBy("Customers", [ "first_name" => "Stephanie" ]); // result array(1) { [0] => array(3) { ["FIRST_NAME"] => string(9) "Stephanie" ["LAST_NAME"] => string(4) "Dowd" ["ID"] => int(2) } }
也可以对多个筛选器进行搜索。但是,一个筛选器对应一个字段。一个字段上不能有多个筛选器。
// datas ["id" => 0, "first_name" => "Andrea", "last_name" => "Baker"], ["id" => 1, "first_name" => "Angela", "last_name" => "Carr"], ["id" => 2, "first_name" => "Stephanie", "last_name" => "Dowd"] $jsonDb->findOneBy("Customers", [ "first_name" => "an|" . DbJsonBased::CONTAINS // "first_name" must contains "an" ], false); // result 1 filter array(3) { [0] => array(3) { ["FIRST_NAME"] => string(6) "Andrea" ["LAST_NAME"] => string(5) "Baker" ["ID"] => int(0) } [1] => array(3) { ["FIRST_NAME"] => string(6) "Angela" ["LAST_NAME"] => string(4) "Carr" ["ID"] => int(1) } [2] => array(3) { ["FIRST_NAME"] => string(9) "Stephanie" ["LAST_NAME"] => string(4) "Dowd" ["ID"] => int(2) } } // ============================ $jsonDb->findOneBy("Customers", [ "first_name" => "an|" . DbJsonBased::CONTAINS, // "first_name" must contain "an" "last_name" => "er|" . DbJsonBased::END_BY // AND "last_name" must end by "er" ], false); // result 2 filters array(1) { [0] => array(3) { ["FIRST_NAME"] => string(6) "Andrea" ["LAST_NAME"] => string(5) "Baker" ["ID"] => int(0) } }
您还可以选择是否希望进行大小写敏感搜索。默认情况下,搜索是大小写敏感的。
// datas ["id" => 0, "first_name" => "Andrea", "last_name" => "Baker"], ["id" => 1, "first_name" => "Angela", "last_name" => "Carr"], ["id" => 2, "first_name" => "Stephanie", "last_name" => "Dowd"], ["id" => 3, "first_name" => "stephanie", "last_name" => "Hardacre"] $jsonDb->findOneBy("Customers", [ "first_name" => "Stephanie" ], false); // case sensitive = false // result array(2) { [0] => array(3) { ["FIRST_NAME"] => string(9) "Stephanie" ["LAST_NAME"] => string(4) "Dowd" ["ID"] => int(2) } [1] => array(3) { ["FIRST_NAME"] => string(9) "stephanie" ["LAST_NAME"] => string(8) "Hardacre" ["ID"] => int(3) } }
findAll
findAll(string $tableName) 返回数据库表中包含的所有数据
// datas ["id" => 0, "first_name" => "John", "last_name" => "Doe", "size" => 175.50, "age" => 21], ["id" => 1, "first_name" => "Neo", "last_name" => "Trinitron", "size" => 184.20, "age" => 33], ["id" => 2, "first_name" => "Alan", "last_name" => "Turingstone", "size" => 170.30, "age" => 45], ["id" => 3, "first_name" => "Luke", "last_name" => "Skylogger", "size" => 173.80, "age" => 18] $jsonDb->findAll("Customers"); // result array(4) { [0] => array(5) { ["ID"] => int(0) ["FIRST_NAME"] => string(4) "John" ["LAST_NAME"] => string(3) "Doe" ["SIZE"] => float(175.5) ["AGE"] => int(21) } [1] => array(5) { ["ID"] => int(1) ["FIRST_NAME"] => string(3) "Neo" ["LAST_NAME"] => string(9) "Trinitron" ["SIZE"] => float(184.2) ["AGE"] => int(33) } [2] => array(5) { ["ID"] => int(2) ["FIRST_NAME"] => string(4) "Alan" ["LAST_NAME"] => string(11) "Turingstone" ["SIZE"] => float(170.3) ["AGE"] => int(45) } [3] => array(5) { ["ID"] => int(3) ["FIRST_NAME"] => string(4) "Luke" ["LAST_NAME"] => string(9) "Skylogger" ["SIZE"] => float(173.8) ["AGE"] => int(18) } }
GET方法
getFullName
getFullName() 返回数据库文件的名称,包括其扩展名。
getName
getName() 返回数据库文件的名称,不包括其扩展名。
getPath
getPath() 返回数据库文件的名称,包括其完整路径和扩展名。
注意:即使返回了路径,也无法确认数据库是否存在。至少,不是直到您使用了 createDb() 方法。如果您的目标是确定文件是否物理存在,请使用静态方法 isFileExist(string $path)
getLastId
getLastId(string $tableName) 返回数据库表中最后一次使用的ID
// datas array(1) { ["CUSTOMERS"] => array(3) { ["COLUMNS"] => array(4) { ["FIRST_NAME"] => string(6) "string" ["LAST_NAME"] => string(6) "string" ["SIZE"] => string(4) "float" ["AGE"] => string(3) "int" } ["VALUES"] => array(3) { {datas}, {datas}, {datas} } ["ID"] => 3 // This id is not necessarily equal to the record numbers into "VALUES" because we can delete data. This is why this value keeps the last id used even if it has been deleted } } $jsonDb->getLastId("Customers") // result int(3)
getColumns
getColumns(string $tableName) 返回数据库表中所有列及其类型
array(4) { ["FIRST_NAME"] => string(6) "string" ["LAST_NAME"] => string(6) "string" ["ACTIF"] => string(3) "int" ["ID"] => string(3) "int" }
静态方法
updateKeysArray
Utils::updateKeysArray(array &$arrayToModified, array $renamedKey) 重命名作为参数传递的数组中的键
harmonizeKeyCase
Utils::harmonizeKeyCase(array $datas, string $caseFunction, bool $simpleArray = false) 返回作为参数传递的数据数组。您可以更改大小写为小写或大写。如果 $simpleArray 为 true,则根据给定的案例修改数组(标准)的每个元素。否则,如果它是 false,则只修改此数组(关联)的键,根据指定的案例进行修改。您可以使用类常量来完成此操作:STRTOUPPER | STRTOLOWER
isFileExist
Utils::isFileExist(string $path) 如果数据库存在并且创建了 .json 文件,则返回一个布尔值。
getContentAndDecode
Utils::getContentAndDecode(string $path, bool $associative = true) 返回文件内容并对其进行解码。如果 $associative 参数为 true,则返回关联数组,如果为 false,则返回对象。
encodeAndWriteFile
Utils::encodeAndWriteFile(string $path, array $toEncode) 编码数据并将这些数据写入指定的文件。
注意:写入的数据将替换整个文件。因此,如果文件已存在并包含数据,则之前的数据将被删除并替换为新的数据。
这些最后两个静态方法(Utils::getContentAndDecode() 和 Utils::encodeAndWriteFile())不打算在相关方法之外使用。它们用于恢复和保存数据库。