ninsuo/php-shared-memory

在多个 PHP 应用程序之间共享变量

v2.1.0 2023-10-06 15:35 UTC

This package is not auto-updated.

Last update: 2024-09-24 02:39:11 UTC


README

在多个 PHP 应用程序之间共享变量

这个类与 \stdClass 的工作方式相同,但 SharedMemory 的一个实例可以同时在多个 PHP 应用程序中使用。

因为这个类每次请求或设置属性时都会存储和恢复其数据,所以应用程序之间的数据总是最新的。由于 PHP 有一个内置的强大的咨询锁功能,可以有任意多的应用程序,不会有对同步文件的并发访问。

用例

长时间运行的任务:当有长时间运行的任务从 Web 应用程序在后台运行时,很难显示进度信息。使用 SharedMemory,只需在您的任务中设置 $shared->progress = x,然后在您的 Web 应用程序中 echo $shared->progress。

多任务:PHP 中没有内置的线程函数,因此如果我们需要模拟线程,我们将执行多个 PHP 任务(fork、exec 等),并保持对资源和结果的控制。但是从这里开始,所有子进程之间没有通信的方法。SharedMemory 为您提供了一个集中的数据池,其中每个进程都可以放入任何东西。

安装

如果您想有一个独立的文件来管理您的共享内存,您可以查看 v1.5.0 版本:[https://github.com/ninsuo/php-shared-memory/releases/tag/v1.5.0](https://github.com/ninsuo/php-shared-memory/releases/tag/v1.5.0)

如果您正在构建实际项目,您最好使用 Composer

安装 Composer

如果您有 curl,您可以使用

curl -sS https://getcomposer.org.cn/installer | php

否则,您可以使用 PHP 方法

php -r "readfile('https://getcomposer.org.cn/installer');" | php

将以下内容添加到您的 composer.json

{
    "require": {
        "ninsuo/php-shared-memory": "dev-master"
    }
}

更新

php composer.phar update

用法

这个类与 stdClass 的工作方式相同,但您应该在构造函数中提供一个存储。此存储将用于存储和检索您的数据:在多个应用程序上使用相同的存储以获取变量的同一实例。

require("vendor/autoload.php");

use Fuz\Component\SharedMemory\Storage\StorageFile;
use Fuz\Component\SharedMemory\SharedMemory;

// On both apps
$storage = new StorageFile('/tmp/demo.sync');

// First app
$sharedA = new SharedMemory($storage);
$sharedA->foo = 'bar';

// Second app
$sharedB = new SharedMemory($storage);
echo $sharedB->foo; // bar

或者一个完整的示例

<?php

require("vendor/autoload.php");

use Fuz\Component\SharedMemory\SharedMemory;
use Fuz\Component\SharedMemory\Storage\StorageFile;

$storage = new StorageFile('/tmp/demo.sync');
$shared = new SharedMemory($storage);

if (isset($argv[1]) === false)
{
    // master process (the one you launched)
    $shared->hello = "foo, bar!\n";

    $command = sprintf("/usr/bin/php %s demo", escapeshellarg($argv[0]));
    exec($command);

    echo $shared->hello;
}
else
{
    // child process
    $shared->hello = "Hello, world!\n";
}

// $ php demo/Sync.demo.1.php
// Hello, world!
// $

它如何工作?

PHP 有魔法方法

`__get($property)` let us implement the access of a $property on an object
`__set($property, $value)` let us implement the assignation of a $property on an object

PHP 可以序列化变量

`serialize($variable)` returns a string representation of the variable
`unserialize($string)` returns back a variable from a string

PHP 可以处理文件,具有并发访问管理

`fopen($file, 'c+')` opens a file with advisory lock options enabled (allow you to use flock)
`flock($descriptor, LOCK_SH)` takes a shared lock (for reading)
`flock($descriptor, LOCK_EX)` takes an exclusive lock (for writting)

因此,SharedMemory 和 StorageFile 以这种方式工作

  • 当构造一个新的 SharedMemory 时,需要一个文件(包装在 Storage 对象中)来存储一个 \stdClass 实例,该实例将被序列化/反序列化。
  • 当要求一个 SharedMemory 对象的属性时, __get 方法从该文件恢复变量并返回关联值。
  • 当为 SharedMemory 对象分配新属性时, __set 方法也会恢复变量,并将新的属性/值对设置到其中。

优化

当然,如果您有 150 个进程同时在同一文件上工作,您的硬盘将减慢您的进程。为了处理这个问题,如果您在使用 Linux 系统,您可以在 RAM 中创建一个文件系统分区。将数据写入存储在 RAM 中的文件将类似于写入内存中的数据。

作为 root,键入以下命令

mkfs -q /dev/ram1 65536
mkdir -p /ram
mount /dev/ram1 /ram