azaddevx/database

v2.4.0 2024-03-30 21:20 UTC

This package is auto-updated.

Last update: 2024-09-30 23:35:55 UTC


README

AzadSqlBanner

MySQL PHP

GitHub issues GitHub version

packagist Github all releases MIT license

1. 简介

本项目的主要目标是在确保程序速度的同时,以保持代码结构清洁的方式与数据库建立连接。此外,在项目的不同部分采用面向对象的方法可以提高团队的生产力,并帮助团队成员在各种项目领域中获得全面掌握。

值得注意的是,本项目目前仍处于测试和调试阶段,我们邀请程序员加入我们的开发。

2. 它是如何工作的

这是一个用于与数据库交互的正在开发的库(目前仅支持MySQL)。该库可以自动加密数据,排序数据,并通过作业定义执行查询命令,而不会丢失信息或进行单方面更改。

3. 基本规则

文件夹设置:首先,您需要为您的项目创建一个文件夹结构。此文件夹应包括与表、加密、构建器和其它必要组件相关的文件。请确保正确配置此文件夹。项目命名空间:在配置文件夹的同时,项目名称(在配置类中定义)应作为项目文件的命名空间。这确保了您的项目保持组织,并且不同的组件可以轻松与项目关联。

例如

namespace MyProject\Plugins;

请记住,本项目目前仍处于测试和调试阶段,因此与开发人员协作以增强其功能至关重要。如果您有任何进一步的问题或需要帮助,请随时提出!

4. 初始化设置

首先,使用Composer安装azaddevx/database库。为此,请在您的终端中运行以下命令

composer require azaddevx/database

接下来,使用autoload.php文件加载库

require 'vendor/autoload.php';

// Load the Connect class to start using the library:
$Database = new Azad\Database\Connection(CONFIG CLASS);

现在,为了开始,您需要创建一个配置类。配置类的组件如下所述。

创建此类后,直接将其传递给Connect类。

数据库:在本节中,输入数据库连接信息。未来,根据您拥有的数据库类型,此功能设置的信息可能有所不同。目前,此功能包括以下四个元素

host:您的数据库主机

username:用于连接的用户名

password:您的数据库密码

name:您想要连接的数据库的名称

项目:在本节中,设置您的项目信息,包括项目名称、项目文件夹等。

它包括以下两个元素:directoryname

:此功能包含与数据表相关的通用设置。目前,它包括一个名为prefix的元素。数据表的前缀实际上可以充当所有数据表的签名,放在实际名称之前,并通过下划线(_)与主表名称分隔。

日志:当您在项目中调试时,此功能非常有用。日志将库执行的所有操作保存到不安全的文件中(您必须自行处理安全设置),您可以查看库执行的命令。它包括以下三个元素

  • file_name:保存日志的文件名。

  • save:需要保存到此文件中的数据,包括以下元素

    • query:保存查询命令。
    • affected_rows:保存执行查询后应用的变化数。
    • get_ram:保存从系统RAM接收的数据。
    • save_ram:保存存储在系统RAM中的数据。
    • jobs:保存与工作相关的数据。
    • database:保存所有与数据库相关的存储数据。
  • retain_previous_data:布尔类型,如果为真,则文件中保留以前的日志。

系统:此功能与图书馆的主系统相关,包括两个元素:RAMDatabase

RAM:此功能将数据库接收到的数据存储在系统的RAM中,消除了再次检索查询的需要。这个过程提高了项目的速度,但配置它是可选的。

Database:您打算连接的数据库类型;目前,只有Mysql可用。

以下是一个配置类的示例

<?php
class MySqlConfig {
    public $Database,$Project,$Table,$Log,$System;
    public function __construct() {
        # -------- Database config
        $this->Database['host'] = '127.0.0.1';
        $this->Database['username'] = 'root';
        $this->Database['password'] = '';
        $this->Database['port'] = '';
        $this->Database['name'] = 'AzadSql';


        # -------- Project config
        $this->Project['directory'] = __DIR__."/MyProject";
        $this->Project['name'] = "MyProject";
        if (!file_exists($this->Project['directory'])) { mkdir($this->Project['directory']); }


        # -------- Table config
        $this->Table['prefix'] = "mp";


        # -------- Log
        $this->Log['file_name'] = "Database.log";
        $this->Log['save'] = ['query','affected_rows','get_ram','jobs'];
        // save_ram , database
        $this->Log['retain_previous_data'] = false;


        # -------- System
        $this->System['RAM'] = true;
        # On average 25% speed increase if activated!
        $this->System['Database'] = 'Mysql';
    }
}

配置完配置类后,将其传递给主库类。

例如

$Database = new Azad\Database\Connection(MySqlConfig::class);

5. 主要项目文件夹

成功连接后,这些文件夹将创建在您设置的目录中(在配置类中设置)

    MyProject/
  
      Enums/
    
      Encrypters/
  
      Exceptions/ # Soon
    
      Plugins/
  
      Normalizers/
    
      Tables/

6. 如何创建数据表

为此,进入您的项目文件夹中的Tables文件夹(MyProject\Tables\)。此文件夹包含用于创建数据表的文件。

为此,进入项目文件夹并在Tables文件夹中创建一个php文件

注意

文件名和类名必须匹配。同时,请确保使用包含您的项目名称和术语Tables的命名空间(PROJECT-NAME\Tables)。最后,确保从\Azad\Database\Table\Make类继承。

<?php
namespace MyProject\Tables;
class Users extends \Azad\Database\Table\Make {

}

在上面的示例中,我们正在创建一个名为Users的数据表,在名为Users.php的文件中。

PROJECT-NAME\Tables\Users.php)。

现在是为数据表配置的时间。表设置在类构造函数(__construct)中完成。

首先,注意以下示例

<?php
namespace MyProject\Tables;
class Users extends \Azad\Database\Table\Make {
    public function __construct() {
        $this->Name("user_id")->Type(\Azad\Database\Types\ID::class)->Size(255);
        $this->Name("first_name")->Type(\Azad\Database\Types\Varchar::class)->Size(255);
        $this->Name("last_name")->Type(\Azad\Database\Types\Varchar::class)->Size(255);
        $this->Name("created_at")->Type(\Azad\Database\Types\CreatedAt::class);
        $this->Name("updated_time")->Type(\Azad\Database\Types\UpdateAt::class);
        $this->Save ();
    }
}

很明显,数据表的列是逐行添加的。使用Name方法,我们指定数据表列的名称,使用Type,我们确定要存储在其中的数据类型。最后,使用Size,我们设置数据的大小。这是创建数据表列的最简单方法。然而,数据列设置不仅限于这三种方法。

方法

Name(column_name)

column_name:在此方法中设置列名。此方法的输入是字符串,并且需要在最初始状态下调用。稍后解释的其他方法需要使用此方法定义的名称。

注意

PHP致命错误:未捕获Azad\Database\Table\Exception:您需要首先指定列名。

Type(class_type)

class_type:此方法确定列的数据类型。以下是可以用的数据类型列表。

注意

输入参数必须是\Azad\Database\Types\的类。

类型

  • ArrayData:接受数组输入并输出数组,但它在数据库中以JSON的形式存储。

  • AutoLess:此数据类型为其他团队程序员提供指导(在文档末尾解释)。

  • BigINT:无需解释。!

  • Boolean:无需解释。!

  • Decimal:无需解释。!

  • Floats:无需解释。!

  • CreatedAt:插入时无需手动赋值;此列存储行创建的时间。

  • ID:用于确定用户ID,它使用n+1算法并选择列作为主键。

  • Integer:无需解释。!

  • Random:此数据类型为其他团队程序员提供指导(在文档末尾解释)。

  • UpdateAt:类似于CreatedAt,无需赋值,并存储行的最后编辑时间。

  • Varchar:无需解释。!

  • timestamp:无需解释。!

  • Decimal:无需解释。!

  • Token:创建唯一标识符,对创建API很有用。

  • UserID:被选为主键,数据类型为BigINT。

注意

如果不存在设置的数据类型,您将遇到以下错误。 PHP致命错误:未捕获的Azad\Database\Table\Exception:输入的'type'值无效

Size(size)

size:数据类型大小

Normalizer(normalizer_name) # Set a Normalizer for Column

normalizer_name (字符串):normalizer名称

什么是Normalizers?Normalizers帮助您标准化数据的外观。例如,它们可以使所有字母都变为小写(这有助于数据评估和提取)

在“魔法”部分,这一功能已详细阐述。

Encrypter(encrypter_name) # Set a Encrypter for Column

encrypter_name (字符串):加密器名称

什么是加密器?该功能在存储数据之前对其进行编码,并在检索时进行解码。使用此功能,您可以轻松加密列,并在显示时自动访问解密后的数据。

该功能在“魔法”部分有详细说明。

Foreign(table_name,column_name) # constraint is used to prevent actions that would destroy links between tables.

table_name (字符串):主表名称

column_name (字符串):主列名称

Null () # set default to Null
NotNull () # This means that you cannot insert a new record, or update a record without adding a value to this field
Default ($string) # Set a default value for column
Save() # After setting all columns, call this method

属性

此外,您还可以使用以下属性。

$Unique = [Column names];

这确保了设置的列在其他行中不会重复。

例如

<?php
namespace MyProject\Tables;
class Users extends \Azad\Database\Table\Make {
    public $Unique = ["first_name","last_name"];
    public function __construct() {
        $this->Name("user_id")->Type(\Azad\Database\Types\ID::class)->Size(255);
        $this->Name("first_name")->Type(\Azad\Database\Types\Varchar::class)->Size(255)->Normalizer("Names");
        $this->Name("last_name")->Type(\Azad\Database\Types\Varchar::class)->Size(255)->Normalizer("Names");
        $this->Name("created_at")->Type(\Azad\Database\Types\CreatedAt::class);
        $this->Name("updated_time")->Type(\Azad\Database\Types\UpdateAt::class);
        $this->Save ();
    }
}

表数据的关联

此功能在表中创建链接,使用户能够无需重复搜索就找到自己在另一表中的位置

手动模式

$Transactions = $Sql->Table("Transactions");
$Find = $Transactions->Select("*")->WHERE("user_id",2);
$Transactions_Data = $Find->LastRow()->Result;
$Users = $Sql->Table("Users");
$Find = $Users->Select("*")->WHERE("user_id",$Transactions_Data['user_id']);
$UsersData = $Find->LastRow()->Result;
return $UsersData["first_name"];  #mohammad

使用表格关联

$Transactions = $Sql->Table("Transactions");
$Find = $Transactions->Select("*")->WHERE("user_id",2);
$Transactions_Data = $Find->LastRow()->Result;
return $Transactions->UserData()->first_name; #mohammad

如何设置关联?

首先,您需要使用IndexCorrelation方法指定父表。在接收到数据后,此表的数据将被存储在全局变量中。

    public function __construct() {
        $this->Name("user_id")->Type(\Azad\Database\Types\ID::class)->Size(255);
        $this->Name("first_name")->Type(\Azad\Database\Types\Varchar::class)->Size(255)->Normalizer("Names");
        $this->Name("last_name")->Type(\Azad\Database\Types\Varchar::class)->Size(255)->Normalizer("Names");
        $this->Name("address")->Type(\Azad\Database\Types\ArrayData::class)->Normalizer("Names")->Encrypter("Base64");
        $this->Name("created_at")->Type(\Azad\Database\Types\CreatedAt::class);
        $this->Name("updated_time")->Type(\Azad\Database\Types\UpdateAt::class);
        $this->Save ();
        $this->IndexCorrelation(); # <--------
    }

现在使用内部Correlation方法从第二个表获取数据,并在一个静态函数中定义它。

    public static function Wallet () {
        return self::Correlation("user_id","Wallet","user_id")[0] ?? false;
    }
Correlation($OriginColumn,$table_name,$column)

OriginColumn:要使用的列名进行评估(在此处使用主列)

table_name:目标表名称

column:将OriginColumn数据发送到的列名称

Correlation数据输出是所有找到数据的数组

重要

在使用关联之前,您需要提取数据,此规则是为了防止库处理过重

$Transactions = $Sql->Table("Transactions");
$Find = $Transactions->Select("*")->WHERE("user_id",2);
$Transactions_Data = $Find->LastRow()->Result; # <------
return $Transactions->UserData();

结果

object(stdClass)#38 (6) {
  ["user_id"]=>
  string(1) "2"
  ["first_name"]=>
  string(8) "mohammad"
  ["last_name"]=>
  string(4) "azad"
  ["address"]=>
  NULL
  ["created_at"]=>
  string(19) "2024-03-10 15:48:25"
  ["updated_time"]=>
  string(19) "2024-03-10 15:48:25"
}

第二个示例

$Transactions = $Sql->Table("Transactions");
$Find = $Transactions->Select("*")->WHERE("user_id",2);
// $Transactions_Data = $Find->LastRow()->Result;
return $Transactions->UserData();

结果

bool(false)

警告

在缺乏注意的情况下,存在数据不匹配的风险

$Transactions = $Sql->Table("Transactions");
$Find = $Transactions->Select("*")->WHERE("user_id",2);
$Transactions_Data = $Find->LastRow()->Result;
$Find = $Transactions->Select("*")->WHERE("user_id",3); # <---- user id changed!
# Although the user ID has changed, but no operation has been carried out on it.
return $Transactions->UserData();

结果

object(stdClass)#38 (6) {
  ["user_id"]=>
  string(1) "2"
  ["first_name"]=>
  string(8) "mohammad"
  ["last_name"]=>
  string(4) "azad"
  ["address"]=>
  NULL
  ["created_at"]=>
  string(19) "2024-03-10 15:48:25"
  ["updated_time"]=>
  string(19) "2024-03-10 15:48:25"
}

第二个示例(无问题)

$Transactions = $Sql->Table("Transactions");
$Find = $Transactions->Select("*")->WHERE("user_id",2);
$Transactions_Data = $Find->LastRow()->Result;
$Find = $Transactions->Select("*")->WHERE("user_id",3);
$Transactions_Data = $Find->LastRow()->Result; # Perform operations on the found data, the global variable is updated!!!
return $Transactions->UserData();

结果

object(stdClass)#38 (6) {
  ["user_id"]=>
  string(1) "3"
  ["first_name"]=>
  string(16) "hypothetical_name"
  ["last_name"]=>
  string(20) "hypothetical_lastname"
  ["address"]=>
  NULL
  ["created_at"]=>
  string(19) "2024-03-12 15:56:34"
  ["updated_time"]=>
  string(19) "2024-03-12 15:56:34"
}

6. 如何将数据导入数据表?

数据表配置完成后,要开始注入数据,请使用Table方法选择您希望使用的所需数据表。

此方法的输出是另一个具有类似SelectInsert方法以及您在库类中定义的函数的类。目前,我们使用Insert方法注入数据。

例如

$Database = new Azad\Database\Connect("AzadSql");
$Users = $Database->Table("Users");

选择表后,使用Insert方法将数据插入表中

$Database = new Azad\Database\Connect("AzadSql");
$Users = $Database->Table("Users");

$Users->Insert()
    ->Key("first_name")->Value('Mohammad') // Saved as 'mohammad' because the Normalizer has been used
    ->Key("last_name")->Value('Azad')  // Saved as 'azad' because the Normalizer has been used
->End();

方法

Key(column_name)

column_name:在此字段中设置表列的名称。

Value(data)

data:您想考虑此列的数据。

End(); # After completing the list of columns and their values, call this method

总之,在选择数据表后,有两种方法可以添加数据:用于数据列名称的Key方法,以及指定此列值的Value方法。

最后,在确定数据后,使用End()命令开始数据注入过程。如果您需要数据的ID标识符,End的输出实际上是数据表中添加的最后一个ID。

如何检查是否存在行?

有时,验证您打算添加到数据库中的数据是否可能遇到重复问题是有必要的。为此,我们使用RowExists方法检查我们的数据表中是否存在行。

$Table->RowExists("column_name","value"); // true | false

在下面的例子中,我们检查名称 Mohammad 是否已在 Users 数据表first_name 列中注册。此方法输出的结果为 true(表示存在)和 false(表示不存在)。

在确保这些数据未存储在我们的表中之后,我们将它们添加到表中(这可以防止与唯一性和主键相关的错误)。

$Users = $Sql->Table("Users");
if(!$Users->RowExists("first_name","Mohammad")){
    $Users->Insert()
        ->Key("first_name")->Value("Mohammad")
        ->Key("last_name")->Value("Azad")
        ->Key("wallet")->Value(10000)
    ->End();
}

使用枚举

在开始使用枚举之前,我们需要谈谈它们的应用。什么是枚举?这些常量通常用于通过将数字代码替换为描述性名称来使代码更易读、更易于维护。枚举通过允许您使用有意义的名称而不是魔法数字来使您的代码更易于理解。枚举提供编译时类型检查,防止将无效值分配给变量。枚举将相关常量分组,这在您有一组相关值且应一起考虑时非常有帮助。

要开始使用枚举,您需要遵循以下步骤

1. 创建新枚举

导航到您项目目录中的枚举文件夹,创建一个以您枚举名称命名的文件。在本例中,我们使用 UserStatus(MyProject/Enums/UserStatus.php)。

然后,使用 namespace MyProject\Enums; 指定这是一个枚举类。

注意

这一步不是必须的,但有助于使您的代码更易读。

接下来,使用 enum 关键字创建枚举。 PHP 文档

考虑以下示例,其中我们为用户账户的状态设置了两个状态:Active 和 Inactive

enum UserStatus {
    case Active;
    case Inactive;
}

您也可以为每个表达式分配值,但请注意,您必须指定数据类型。例如,如果您将数字 1 视为 Active,则必须设置这是一个类型为 int 的枚举。

enum UserStatus : int {
    case Active = 1;
    case Inactive = 2;
}

注意

然而,为每个情况设置值不是强制性的,因为库将自动根据您的枚举进行操作。

2. 数据表设置

打开您选择的数据表文件。设置名称后,使用 name 方法中的 Enum 方法。请看以下示例

$this->Name("status")->Enum(\MyProject\Enums\UserStatus::class);

分配 Enum 后,保存和检索数据的过程将发生变化。

要添加一行并更新它,您必须确实使用定义的枚举。以下是一个添加数据的示例。

$Users = $Sql->Table("Users");
if(!$Users->RowExists("first_name","Mohammad")){
    $Users->Insert()
        ->Key("first_name")->Value("Mohammad")
        ->Key("last_name")->Value("Azad")
        ->Key("status")->Value(MyProject\Enums\UserStatus::Active) # <--------
        ->Key("wallet")->Value(10000)
    ->End();
}

现在,当您想要检索 status 的值时,Result 的输出将与定义的枚举相同。

请注意以下示例

$Find = $Users->Select("*")->WHERE("user_id",1);
$Data = $Find->LastRow();
return $Data->Result['status']->name; // "Active"

您也可以向枚举添加函数。例如,我们添加了一个将状态翻译成波斯语的功能。

<?php

namespace MyProject\Enums;

enum UserStatus {
    case Active;
    case Inactive;
    public function toPersian () {
        return match ($this->name) {
            "Active" => "قعال",
            "Inactive" => "غیرفعال"
        };
    }
}

现在,当我们要以波斯语显示用户的状况时,我们这样做

return $Data->Result['status']->toPersian(); // فعال

7. 如何从数据表中提取一行或多行?

在这里,我们将使用另一个名为 Select 的方法。此方法获取您需要数据的列;如果您想获取所有列的数据,请使用星号 (*)。

选择您的列后,您可以使用 WHEREANDOR 搜索特定的行/多行。

请注意以下示例。

$Users = $Database->Table("Users")->Select("*");
$User = $Users->WHERE("first_name","Mohammad")
                    ->AND("last_name","azad");

方法

WHERE(column_name,value)

column_name:您想要获取其值的列的名称。

value:列值。

AND(column_name,value) # Logical Operators (and - &&)

column_name:您想要获取其值的列的名称。

value:列值。

OR(column_name,value) # Logical Operators (or - ||)

column_name:您想要获取其值的列的名称。

value:列值。

在完成 WHERE 子句的数据搜索后,您可以使用以下三种方法访问数据

Data():包括所有检索到的数据。

FirstRow():显示第一个检索到的数据。

LastRow():显示最后一个检索到的数据。

所有三种方法的输出都包含三个属性

结果:检索到的数据。

更新:用于更新或编辑数据。

条件:包含条件表达式方法。

目前,我们打算提取数据,因此我们将使用 结果 属性。

$User->Data ()->Result;

此方法显示所有找到的数据列表。例如

array(1) {
  [0]=>
  array(5) {
    ["user_id"]=>
    string(1) "1"
    ["first_name"]=>
    string(8) "mohammad"
    ["last_name"]=>
    string(4) "azad"
    ["created_at"]=>
    string(19) "2024-03-06 17:49:10"
    ["updated_time"]=>
    string(19) "2024-03-06 17:51:20"
  }
}

$User->FirstRow ()->Result;
# OR
$User->LastRow ()->Result;

此方法获取找到的第一个/最后一个数据。

array(5) {
  ["user_id"]=>
  string(1) "1"
  ["first_name"]=>
  string(8) "mohammad"
  ["last_name"]=>
  string(4) "azad"
  ["created_at"]=>
  string(19) "2024-03-06 17:49:10"
  ["updated_time"]=>
  string(19) "2024-03-06 17:51:20"
}

8. 如何更新一行

要更新一个或多个列,在通过 FirstRow | LastRow | Data 选择行后,使用 更新 属性。

$User->LastRow ()
    ->Update
        ....
    ->Push();

重要

如果 $User 的输出值超过一个,则所有这些值都将更新。

示例

$Users = $Sql->Table("Users");
$Find = $Users->Select("*")->WHERE("user_id",2);
$Data = $Find->LastRow();
$Data->
    Update
        ->Key("first_name")->Value("Mohammad")
    ->Push();

现在,要更新列的值,我们有三种方法

方法

Value(new_value)

new_value:在此参数中设置新值

Increase(number)

number:您想要添加到先前值中的数字。 (value + number = new_value)

Decrease(number)

number:您想要从先前值中减去的数字。 (number - value = new_value)

条件

您还可以使用条件命令来更新数据。例如:(在这个例子中,所有在 300 到 600 范围内的 USD 列都增加了 50 个值。)

try {
    $Users = $Sql->Table("Users");
    $Find = $Users->Select("*");
    $Data = $Find->Data();
    $Data->
        Condition->
            IF("USD")->Between(300,600)
        ->End()
            ->Update
                ->Key("USD")->Increase(50)
            ->Push();
} catch (Azad\Database\Conditions\Exception $E) {
    var_dump($E->getMessage());
}

方法

IF (column_name)

column_name:列名

And (column_name) # Logical Operators (and - &&)

column_name:列名

Or (column_name) # Logical Operators (or - ||)

column_name:列名

条件方法

EqualTo(x) # The defined column is equal to the value of x
ISNot(x) # The defined column does not equal the value of x
LessThan(x) # The column is defined as less than x.
MoreThan(x) # The column is defined as more than x.
LessOrEqualThan(x) # If the value of the column is less than or equal to the value of x.
MoreOrEqualThan(x) # If the value of the column is greater than or equal to the value of x.
Between(x , y) # The value of the column is between x and y - ( x <= value && y >= value)
Have(x) # If there is x in the column value - (Used for arrays and strings)
NotHave(x) # If there is no x in the column value - (Used for arrays and strings)
IN(array x) # If x exists in the data of a column.
NotIN(array x) # If there is no x in the data of a column،

功能性

功能性函数(位于主项目中)以加快工作进度。这部分仍在开发中。(src\Functional

魔法

标准化器

简单来说,这意味着排序数据。当您计划定期在数据库中存储数据时使用标准化器。

tEhRAn -> Tehran

在保存之前,数据被发送到标准化器,然后在更改完成后,标准化器将其存储在数据库中。

normalizer

如何创建新的标准化器

为此,进入项目文件夹,在标准化器文件夹中创建一个 php 文件(AzadSql\Normalizers\x.php)。在这个例子中,我们使用名称 "strtolower",使用 "strtolower" 标准化器将用户名存储为小写(AzadSql\Normalizers\strtolower.php

规则

  1. 类似于表结构,文件名需要与类名相同。
  2. 使用命名空间。 ProjectName\Normalizers
  3. \Azad\Database\Magic\Normalizer 继承
  4. 创建一个名为 Normalization 的方法,作为 静态 并为其输入设置一个参数。 Rebuild ($Data)
  5. 结束。 Normalization 的输出存储在表中,$Data 是打算存储在表中的数据

$Data -> strtolower::Normalization($Data) -> Save

<?php
# strtolower.php
namespace MyProject\Normalizers;
class Names extends \Azad\Database\Magic\Normalizer {
    public static function Normalization ($Data) {
        return strtolower($Data);
    }
}

并且您想要对表中的列进行操作

    ...
        $this->Name("first_name")
            ->Type(\Azad\Database\Types\Varchar::class)
            ->Size(255)
            ->Normalizer("Names"); # <------
        $this->Name("last_name")
            ->Type(\Azad\Database\Types\Varchar::class)
            ->Size(255)
            ->Normalizer("Names"); # <------
    ...

加密器

如果您打算存储重要数据,请使用此方法!

数据加密是自动完成的,您不需要持续解密和加密。

数据在存储之前被加密,在接收后解密。

Encrypter

如何创建新的加密器

为此,进入项目文件夹,在加密器文件夹中创建一个 php 文件(AzadSql\Encrypters\x.php)。在这个例子中,我们使用名称 "Base64",使用 Base64 加密器在存储之前将数据加密为 base64,在接收时解密。

(x.php -> Base64.php)

规则

  1. 类似于表结构,文件名需要与类名相同。
  2. 使用命名空间。 ProjectName\Encrypters
  3. \Azad\Database\Magic\Encrypter 继承
  4. 创建一个名为 Encrypt 的方法,作为 静态 并为其输入设置一个参数。 Encrypt($Data)
  5. 创建一个名为 Decrypt 的方法,作为 静态 并为其输入设置一个参数。 Decrypt($Data)
  6. 结束。

示例

<?php

namespace MyProject\Encrypters;
class Base64 extends \Azad\Database\Magic\Encrypter {
    public static function Encrypt($Data) {
        return base64_encode($Data);
    }
    public static function Decrypt($Data) {
        return base64_decode($Data);
    }
}

并且您想要对表中的列进行操作

    ...
        $this->Name("password")
            ->Type(\Azad\Database\Types\Varchar::class)
            ->Size(255)
            ->Encrypter("Base64"); # <------
    ...

插件

插件可以访问所有数据库数据。它可以接收数据并更改它们。这些过程在插件类内部完成。插件有助于提高团队合作,还可以在网络上发布插件。插件可以帮助您在另一个文件夹中处理数据并访问其定义的方法在主文件中。

如何制作插件

要完成此操作,请进入项目文件夹,并在插件文件夹中创建一个php文件(MyProject\Plugins\x.php

规则

  1. 类似于表结构,文件名需要与类名相同。
  2. 使用命名空间。 ProjectName\Plugins
  3. 继承自 \Azad\Database\Magic\Plugin

self::Table(X):选择要操作数据的表。

$this->Data:此值在编码期间设置,将用于插件的数据放置在此部分。

制作插件的示例

<?php

namespace MyProject\Plugins;

class UserManagment extends \Azad\Database\Magic\Plugin {
    public function ChangeFirstName ($new_first_name) {
        $Users = self::Table("Users");
        $Users = $Users->Select("*");
        $User = $Users->WHERE("user_id",$this->Data->Result['user_id']);
        $User->LastRow()->
            Update
                ->Key("first_name")->Value($new_first_name)
            ->Push();
    }
}

?>

您还可以通过IncludePlugin方法导入另一个插件。

<?php

namespace MyProject\Plugins;
class ChangeName extends \Azad\Database\Magic\Plugin {
    public function ChangeName ($new_first_name) {
        $UserManagment = $this->IncludePlugin("UserManagment",$this->Data);
        $UserManagment->ChangeFirstName ($new_first_name);
    }
}

?>

加载插件的示例

<?php
#  index.php

require 'vendor/autoload.php'; // load librarys

$Sql = new Azad\Database\Connect("AzadSql"); // load AzadSql

$Users = $Sql->Table("Users"); // Select table
$Users = $Users->Select("*"); //Select Columns

$User = $Users->WHERE("first_name","Mohammad")
            ->And("last_name","azad"); // Find User

$UserManagment = $Sql->LoadPlugin ("UserManagment",$User->LastRow()); // Load Plugin

$UserManagment->ChangeFirstName("Mohammad2"); // Use plugin methods

var_dump($User->LastRow()->Result); // Get new data
array(5) {
  ["user_id"]=>
  string(1) "5"
  ["first_name"]=>
  string(9) "mohammad2"
  ["last_name"]=>
  string(4) "azad"
  ["created_at"]=>
  string(19) "2024-03-07 02:30:18"
  ["updated_time"]=>
  string(19) "2024-03-07 13:05:13"
}

任务

一个有趣且非常高效的特性。您是否曾经遇到过在两个用户之间转账后,一个用户的余额减少但第二个用户的余额没有增加的情况?这是真的,您可能陷入了连续且复杂的条件中,但在这里我们有一个更好的解决方案。

使用此功能,所有数据在执行前都会进行评估,按顺序列出,如果其中一个数据的执行遇到问题,将恢复之前的数据,并且不会更改任何数据。

Jobs

请注意以下示例

try {

    $Job1 = $Sql->NewJob();

    # Job1 -> Find (VALUE_PRIMARY_KEY) -> From (TABLE_NAME)
    $User1 = $Job1->Find(1)->From("Users");
    $User1_Wallet = $User1->Result['wallet'];
    $User2 = $Job1->Find(2)->From("Users");
    $User2_Wallet = $User2->Result['wallet'];

    $Amount = 10000;

    # Job1 -> Table (TABLE_NAME) -> SELECT (COLUMN_NAME) -> To (NEW_VALUE) -> Who? (UserObject)
    $Job1->Table("Users")->Select("wallet")->To($User1_Wallet + $Amount)->Who($User1);
    $Job1->Table("Users")->Select("wallet")->To($User2_Wallet - $Amount)->Who($User2);

    if ($User2_Wallet < $Amount) {
        $Job1->Exception(new ExceptionJob("User 2 does not have enough inventory",-1));
    }

    $Job1->Start();

} catch (ExceptionJob $E) {
    $message = match ($E->getCode()) {
        -1 => "User 2 you do not have enough balance, please recharge your account.",
        default => "There is a problem, please try it later."
    };
    print($message);
}

在上面的示例中,我们打算在两个用户之间转移10,000货币单位。

此功能的整洁架构如下

首先,定义您需要的数据的用户。

然后,定义您所需的变量。

现在,开始对数据进行操作。

最后,在开始任务之前检查数据。

在第一步中,需要定义一个新的任务,这是通过NewJob方法完成的。

$Job1 = $Sql->NewJob();

在定义了一个用于从表中接收数据的工作(例如,上面的Users)之后,使用以下结构

$Job1->Find(VALUE_PRIMARY_KEY)->From(TABLE_NAME);

Find方法的输入实际上是主键列的值。工作会自动检测哪个列是主键,并使用此方法值的值与主键列进行比较。

然后,使用From方法,指定数据属于哪个表。

注意

在任务中,不要手动更改数据;我们需要之前的数据和新的数据,这需要正确编写任务。

在下一步中,为了保存更新命令,我们使用以下结构

$Job1->Table(TABLE_NAME)->SELECT(COLUMN_NAME)->To(NEW_VALUE)->Who?(UserObject);

Table方法中,输入您打算操作的表的名称。对于Select输入,输入您打算编辑数据的列的名称(在上面的示例中,amount)。

现在,使用To方法定义新的输入应该是什么。最后,使用Who方法指定您正在编辑的用户(使用前一步中通过Find方法定义的变量)。

现在,最后,我们可以在开始命令之前评估数据,并在出现问题的情况下使用异常方法。

注意

此方法的输入必须是ExceptionJob类。

在完全配置任务后,使用Start命令按定义的顺序执行命令。

库开发者指南 🤜 🤛

如何创建新的数据类型

数据类型是以面向对象的方式创建的,这有助于我们为每种数据类型设置特定的功能。数据类型的文件夹在/src/types

规则

  1. 文件名与类名相同。
  2. 使用命名空间Azad\Database\Types
  3. 继承自Init

类组件分为两组属性和方法。

属性

$SqlType:需要定义为公开的必需属性。这些属性的值作为数据类型发送到sql。BIGInt示例

<?php
namespace Azad\Database\Types;
class BigINT extends Init {
    public $SqlType = "BIGINT";
}
# CREATE TABLE table_name ( column [$SqlType] );

$Primary:布尔值,如果定义为true,此列将自动被视为主键ID示例

<?php
namespace Azad\Database\Types;
class ID extends Init {
    public $SqlType = "BIGINT";
    public $Primary = true;
    public function AddToQueryTable () {
        return "AUTO_INCREMENT";
    }
}

方法

AddToQueryTable ()

在数据类型创建后在SQL中添加新值,例如CreatedAt

<?php
namespace Azad\Database\Types;
class CreatedAt extends Init {
    public $SqlType = "timestamp";
    public function AddToQueryTable () {
        return "DEFAULT CURRENT_TIMESTAMP";
    }
}
# CREATE TABLE table_name ( column [$SqlType] [AddToQueryTable ()] );
InsertMe()

用户首次使用“插入”功能后,此值被视为列值。

UpdateMe()

用户更新他们的某一列后,由这种方法定义的列将变为这种方法输出的结果。

随机示例

<?php
namespace Azad\Database\Types;
class Random extends Init {
    public $SqlType = "INT";
    public function InsertMe() {
        return 12345;
    }
    public function UpdateMe() {
        return rand(1,100);
    }
}
Set($value)

用户打算存储数据后,数据会被发送到这个方法,并且其输出被替换为新的数据。

$value:正在数据库中存储的值

AutoLess 示例

<?php
namespace Azad\Database\Types;
class AutoLess extends Init {
    public $SqlType = "INT";
    public function InsertMe() {
        return 9999;
    }
    public function Set($value) {
        return $value - 1;
    }
}
Get($value)

程序员打算从表列获取数据后,首先将表列数据发送到这个方法,并将其输出设置为输出数据。

$value:正在数据库中存储的值

ArrayData 示例

<?php
namespace Azad\Database\Types;
class ArrayData extends Init {
    public $SqlType = "JSON";
    public function Set($value) {
        return json_encode($value);
    }
    public function Get($value) {
        return json_decode($value,1);
    }
}