heydyho/plah

PHP小程序助手

v3.0.0 2020-12-26 08:30 UTC

This package is auto-updated.

Last update: 2024-09-26 16:49:03 UTC


README

PHP小程序助手(Plah)是一个小型库,包含一些可以作为PHP微框架(如著名的Slim Framework)插件的类。例如,它有一个Config类,可以使用文本文件来配置选项,或者有一个Language类,可以用于多语言设置。还包括一个MongoModel基类,这使得使用MongoDB而不是或与MySQL一起使用模型变得容易。

版本 3

版本 3是为PHP7+创建的。PHP5用户应坚持使用版本 2。
有一些破坏性更改,特别是对于MongoDB助手。因为旧的PHP mongo扩展已被弃用,所以Plah现在使用PHP mongodb扩展和库。尽管如此,像save()这样的函数已被保留,并且像版本 2 一样工作。

安装

使用Composer将Plah添加到您的项目中。这将使自动加载变得简单。

{
    "require": {
        "heydyho/plah": "~3.0"
    }
}

您也可以通过下载当前master分支的ZIP文件手动安装Plah。您需要将Plah命名空间注册到项目的自动加载程序中,或者您必须手动require/include必要的文件。这不是推荐的方法,因为某些类相互依赖并依赖于自动加载程序。

使用

由于Plah是一个工具集,因此没有单一的入口点,您可以使用它的部分或全部。Plah的每个部分都有自己的配置选项(如果需要)。它们通过一个获取配置选项数组的::config()函数静态初始化。例如

\Plah\Config::config(array(
    'dir' => __DIR__ . '/../myconfig',
    'file_default' => 'myconfig-default',
    'file_local' => 'myconfig-local'
));

通常您会在项目的index.php文件或某种初始化文件/类中使用此功能。您不需要设置所有可能的选项,只需为计划使用的Plah部分设置选项即可。甚至不需要为单个部分设置所有选项,只需设置与默认值不同的选项即可。例如

\Plah\Config::config(array(
    'dir' => __DIR__ . '/../myconfig'
));

这将仅更改配置目录并保留默认文件名。

组件

配置

Config类可以用于将配置选项放入单个文本文件中。以下格式用于配置文件

; Mailer settings
mail.host = "mail.example.com"
mail.user = "myuser@example.com"
mail.password = "mypassword"

以下是如何获取配置选项的方式

\Plah\Config::getInstance()->get('mail.host');

//You can also use a default value if you are not sure if a config value is set
\Plah\Config::getInstance()->get('mail.host', 'mail.example2.com');

//Another way
$config = new \Plah\Config();
$config->get('mail.host');

//Get all config items as array
$config = \Plah\Config::getInstance()->getAll();
echo $config['mail.host'];

有两个文件,一个默认配置和一个本地配置。本地配置文件中的选项会覆盖默认配置文件中的选项。此功能可以用于在开发设置中具有特殊选项,如其他密码等。请注意:将本地配置文件添加到.gitignore文件中,以将其从您的存储库中排除。默认文件名为config-default.iniconfig-local.ini。名称可以由相应的设置更改,.ini文件扩展名是硬编码的,并且必须存在。

设置

\Plah\Config::config(array(
    'dir' => '../config',
    'file_default' => 'config-default',
    'file_local' => 'config-local'
));

平台

平台类可以用作配置类的补充或替代。基本上工作流程是相同的。有两个文件,默认情况下是 platform-default.iniplatform-local.ini,但你也可以添加具有特定平台设置的额外文件。例如,如果你的项目有两个URL,一个用于英文版本,一个用于德文版本,那么新(未配置)的URL默认应该是英文。你可以有如下这样的文件

//platform-default.ini
language = "en"

//myplatform.com.ini
language = "en"

//myplatform.de.ini
language = "de"

代码看起来可能像这样

//Set the platform
$hostname = my_function_for_getting_the_hostname();
\Plah\Platform::getInstance()->set($hostname);

//Get an option
\Plah\Platform::getInstance()->get('language');

//Like with the Config class you can also use a default value
\Plah\Platform::getInstance()->get('language', 'en');

//Another way
$platform = new \Plah\Platform();
$platform->set($hostname);
$platform->get('language');

//Get all platform items as array
$platform = \Plah\Platform::getInstance()->getAll();
echo $platform['language'];

这会加载 platform-default.ini 文件,如果有,还会额外加载 platform-local.ini 文件以及与主机名匹配的 .ini 文件(主机名中不得包含 .ini 扩展名,它会被自动添加)。另一种用例可能是并行使用两个不同的配置文件。可以这样操作

//myconfig1.ini
language = "en"

//myconfig2.ini
language = "de"

$config1 = new \Plah\Platform();
$config2 = new \Plah\Platform();
$config1->set('myconfig1');
$config2->set('myconfig2');
$config1->get('language');  //gives you en
$config2->get('language');  //gives you de

如果你愿意,可以将配置和平台类结合起来,以便通过全局配置文件一次性覆盖特定平台的设置。例如,要在所有平台上关闭一个功能,而无需更改每个平台配置文件中的设置。

//myplatform1.ini
userupload = 1

//myplatform2.ini
userupload = 0

//myplatform3.ini
userupload = 1

//The code to get the userupload setting would look like this
\Plah\Config::getInstance()->get('userupload', \Plah\Platform::getInstance()->get('userupload'));

//To switch of the userupload for all platforms just add it to your config-default.ini (not the platform-default.ini)
userupload = 0

在这个例子中,通过主配置文件请求用户上传设置,作为后备,使用平台配置。这意味着只要主配置文件中没有用户上传选项,就会使用平台设置,一旦将选项添加到 config-default.ini 中,就会覆盖所有平台设置。请注意:platform-default.ini 文件不能覆盖特定平台的文件,它只用作选项的基础,如果特定平台文件中缺少选项。

设置

\Plah\Platform::config(array(
    'dir' => '../platform',
    'file_default' => 'platform-default',
    'file_local' => 'platform-local'
));

语言

语言类可用于处理多语言设置。它与配置和平台类一样使用文本文件,这是对众所周知的但有时有点复杂的 Gettext 实现的替代方案,这些实现使用预编译的文件。

//en.ini
main.hello = "hello"

//de.ini
main.hello = "hallo"

\Plah\Language::getInstance()->set('en');
echo \Plah\Language::getInstance()->get('main.hello');  //hello

\Plah\Language::getInstance()->set('de');
echo \Plah\Language::getInstance()->get('main.hello');  //hallo

//Like with the Config class you can also use a default value
echo \Plah\Language::getInstance()->get('main.hello', 'hello');

//Another way
$language_en = new \Plah\Language();
$language_en->set('en');
$language_en->get('main.hello');  //hello

$language_de = new \Plah\Language();
$language_de->set('de');
$language_de->get('main.hello');  //hallo

//Get all language items as array
$language = \Plah\Language::getInstance()->getAll();
echo $language['main.hello'];

其中并没有多少魔法。选项 file_default 允许你设置默认语言文件。此文件始终被加载。所以如果 en 是你的主要语言,而 de 文件缺少一些文本,则会使用 en 文件中的文本。你应在项目的 index.php 或某种初始化文件/类中选择语言,可能取决于浏览器语言或 URL,就像平台示例中那样。请注意:file_default 选项不应用作你的平台默认语言设置,它只是一个用于后续翻译的基本语言文件。

设置

\Plah\Language::config(array(
    'dir' => '../language',
    'file_default' => 'en'
));

MongoModel

MongoModel 类可以用作使用 MongoDB 作为存储后端的模型的基础。一个基本模型可能看起来像这样

class User extends \Plah\MongoModel
{
    //Basic database settings
    protected static $_db = 'mydatabase';
    protected static $_collection = 'user';
    protected static $_key = '_id';

    //Model properties
    public $_id = null;
    public $email = '';
    public $password = '';
    public $first_name = '';
    public $last_name = '';

    public static function createIndexes()
    {
        self::getCollection()->createIndex(array('email' => 1), array('background' => true));
    }
}

$_db 设置数据库,$_collection 设置用于存储数据的 MongoDB 集合(表)。必须设置这些属性才能使模型工作。$_key 可用于设置类似主键的东西,用法可以在下面的示例中找到。模型的所有公共属性是写入集合的字段。createIndexes() 函数定义了你的模型所需的索引。你必须运行它当索引发生变化时。最佳实践是有一个文件运行所有模型的 createIndexes() 函数。

以下是如何使用你的模型的示例

//Create a new user, set some values and save it
$user = new User();
$user->email = 'myaddress@example.com';
$user->password = 'myunencryptedtopsecretpassword';
$user->first_name = 'John';
$user->last_name = 'Doe';
$user-save();

//Another way to set values
$user = new User();
$user->set('email', 'myaddress@example.com');

//Find a user with the email myaddress@example.com, change it and save it
$user = User::getInstance()->findOne(array('email' => 'myaddress@example.com'));
$user->email = 'mynewaddress@example.com';
$user-save();

//Find a user by the primary key (which is a MongoId in this case), change it and save it
try {
    $user = new User(new MongoDB\BSON\ObjectId('555ef27165689edd457b23c7'));
    $user->first_name = 'Jane';
    $user-save();
} catch (\Exception $e) {
}

//Find all users with the first name John, walk over the results in a loop and show the email addresses
$users = User::getInstance()->find(array('first_name' => 'John'));
foreach ($users as $user) {
    echo $user->email;
}

//Another way to get values
echo $user->get('email');
echo $user->get('email', 'unknown');  //Gets 'unknown' as default value if the email property doesn't exist

//Find a user with the email myaddress@example.com and remove it from the collection
$user = User::getInstance()->findOne(array('email' => 'myaddress@example.com'));
$user-remove();

//Get a PHP MongoCollection object to use all possible functions
$user_collection = User::getCollection();

函数 findOne()find()save()remove() 是围绕由 MongoDB\Collection 对象提供的函数的包装器。findOne() 如果没有找到任何内容则返回 null,就像原始函数一样,如果找到了,则返回你的模型类的实例。原始函数返回 null 或一个数组。find() 返回一个空数组或一个包含你的模型实例的数组,而原始函数返回一个空数组或一个返回数组的 MongoDB\Driver\Cursor 对象。

find() 函数有一些额外的参数用于排序和限制结果。以下是一个示例

//Find users with the first name John, order the results descending by last name and limit the results to the first 10 matching entries
$users = User::getInstance()->find(array('first_name' => 'John'), array(), array('last_name' => -1), 0, 10);

除了对find()的结果进行排序和限制外,您还可以获取有无限制时找到的元素数量。这在对数据进行分页时很有用。请看以下示例

//Find users with the first name John, order the results descending by last name and limit the results to the first 10 matching entries
$users = User::getInstance()->find(array('first_name' => 'John'), array(), array('last_name' => -1), 0, 10, $count, $found);
echo $count;  //This will be the number of all elements with the first name John, maybe 0, 5, 10 or even 100
echo $found;  //This will be 10 or less because the result set is limited to max 10

count()函数是MongoDB\Collectioncount()函数的包装,但同时也接受查询参数以及跳过和限制参数,就像find()函数一样。它返回由查询找到的、通过跳过和限制限制的数据集数量。请注意:只有在只关心数据集数量的情况下,这才有用,在所有其他情况下,find()函数的$count$found参数将做得更好,因为不需要第二次查询来获取数据集。以下是一个仅进行计数查询的示例

//Count the users with first name John
echo User::getInstance()->count(array('first_name' => 'John'));

您可以通过静态config()函数为MongoDB连接设置一些选项。大多数选项应该是清晰的,auth_db是用于身份验证的数据库,如果设置了用户名和密码。

设置

\Plah\MongoModel::config(array(
    'host' => 'localhost',
    'port' => '',
    'user' => '',
    'password' => '',
    'auth_db' => ''
));

MongoAutoIncrement

MongoAutoIncrement类可以用来获取类似于SQL数据库使用的自动递增ID。MongoAutoIncrement需要一个数据库和一个集合,两者默认为autoincrement,可以更改。内部会创建一个具有特定键的文档,每次尝试为该键获取下一个自动递增值时,序列号都会递增1。以下是一个简短的用法示例

echo \Plah\MongoAutoIncrement::getInstance()->getNext('user');  //1
echo \Plah\MongoAutoIncrement::getInstance()->getNext('user');  //2
echo \Plah\MongoAutoIncrement::getInstance()->getNext('user');  //3

echo \Plah\MongoAutoIncrement::getInstance()->getNext('event');  //1
echo \Plah\MongoAutoIncrement::getInstance()->getNext('event');  //2
echo \Plah\MongoAutoIncrement::getInstance()->getNext('user');  //4
echo \Plah\MongoAutoIncrement::getInstance()->getNext('event');  //3

//Another way
$auto_increment = new \Plah\MongoAutoIncrement();
echo $auto_increment->getNext('user');  //5
echo $auto_increment->getNext('event');  //4

您可以设置一个初始化值,以便在这是对键的第一个请求时,从该值开始计数

echo \Plah\MongoAutoIncrement::getInstance()->getNext('user', 1000);  //1000

echo \Plah\MongoAutoIncrement::getInstance()->getNext('event');  //1
echo \Plah\MongoAutoIncrement::getInstance()->getNext('event', 1000);  //2 <- Not the first request for 'event', the init value is ignored

您应该运行以下行一次来为集合创建必要的索引。

\Plah\MongoAutoIncrement::createIndexes();

MongoAutoIncrement类扩展了MongoModel类,因此在使用MongoAutoIncrement之前,请确保正确配置MongoModel。

设置

\Plah\MongoAutoIncrement::config(array(
    'db' => 'autoincrement',
    'collection' => 'autoincrement'
));

MongoSession

MongoSession类可以用于基于MongoDB的会话管理。该类不使用或依赖于PHP会话,但使用相同的流程。首先必须开始会话。如果页面的访问者已经有一个有效的会话ID,则从MongoDB集合中加载相应的数据,否则生成一个新的会话ID。为了“记住”访问者的会话ID,使用cookie。为了防止数据库中充满空会话(例如在DDoS攻击的情况下),不会自动将新会话写入数据库。当通过set()函数设置第一个值时,以及在每次通过set()函数设置新值时,会保存会话。会话的数据库和集合可以通过配置选项设置,以及cookie名称和过期时间。过期时间可以是0(这意味着cookie在浏览器关闭时结束),Unix时间戳或字符串如“1天”。以下是一个用法示例

//Configure the sessions to be valid for 1 day
\Plah\MongoSession::config(array(
    'expires' => '1 day'
));

//Start the session
\Plah\MongoSession::getInstance()->start();

//Set a session value
\Plah\MongoSession::getInstance()->set('test', 'testvalue');

//Get a session value
echo \Plah\MongoSession::getInstance()->get('test');  //shows testvalue

//Get a session value with a default fallback value
echo \Plah\MongoSession::getInstance()->get('test2', 'testvalue2');  //shows testvalue2 because no other value was set for test2

//Another way
//This is not recommended because you have to make the $session variable globally available or call start() every time you create a new instance of the MongoSession class
$session = new \Plah\MongoSession();
$session->start();
$session->set('test', 'testvalue');
echo $session->get('test');

MongoSession类扩展了MongoModel类,因此在使用MongoSession之前,请确保正确配置MongoModel。MongoModel类的set()函数被重写和修改,以便在每次更改属性时将对象保存到数据库中。这是为了保持会话数据的一致性,即使请求不能完全处理。

设置

\Plah\MongoSession::config(array(
    'db' => 'session',
    'collection' => 'session',
    'name' => 'session',
    'expires' => 0
));

Session

Session类是$_SESSION超级全局变量的包装。您可以使用它来获取、设置或删除$_SESSION的值。会话本身不是由Session类存储的。用法如下

//Get the session language
$language = \Plah\Session::getInstance()->get('language');

//Like with the Config class you can also use a default value
$language = \Plah\Session::getInstance()->get('language', 'en');

//Set the session language to en
\Plah\Session::getInstance()->set('language', 'en');

//Delete the language value
\Plah\Session::getInstance()->delete('language');

//Another way
$session = new \Plah\Session();
$language = $session->get('language');
$session->set('language', 'en');
$session->delete('language');

分页

分页类执行必要的计算以显示分页,并返回一个包含相关数字的数组。它需要四个参数:数据总数、每页条目数、当前活动页和所需分页数。返回的数组将包含第一页和最后一页、上一页和下一页、显示的页码、活动页、活动页的条目数、总条目数以及活动页的起始和结束数据。所有数字都不会小于1,以避免除以零的问题。同时,不接受小于1或非整数的数字进行计算。以下是一个示例

//Calculate a pagination
$total = 5;
$entries = 2;
$page = 1;
$pages = 4;
$pagination = \Plah\Pagination::getInstance()->get($total, $entries, $page, $pages);
print_r($pagination);

Array
(
    [first] => 1
    [last] => 3
    [previous] => 1
    [next] => 2
    [pages] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [active] => 1
    [entries] => 2
    [total] => 5
    [start] => 1
    [end] => 2
)

示例显示,即使需要4页,分页类也会计算出只需要1到3页,第4页将没有数据。

单例

单例类主要在其他Plah类内部使用。如您在上述示例中所见,您可以使用 ::getInstance() 获取类的静态版本。这是通过扩展单例类来实现的。例如

MyClass
{
    public function my_function()
    {
        echo "my_function";
    }
}

$myclass = new MyClass();
$myclass->my_function();

//By changing
MyClass
//to
MyClass extends \Plah\Singleton
//you can use your function like this
MyClass::getInstance()->my_function();

请注意:这仅适用于没有特殊设置且不需要不同实例的类。

IniParser

IniParser类由Config、Platform和Language类使用。它解析格式为key = "value"的文本文件,并返回一个关联数组。它主要基于PHP函数parse_ini_file(),但总是返回一个数组,即使文件无法解析。如果您的项目需要,可以使用IniParser如下

$myoptions = \Plah\IniParser::getInstance()->get('myfile.ini');

//Another way
$parser = new \Plah\IniParser();
$myoptions = $parser->get('myfile.ini');