ホームページ > バックエンド開発 > PHPチュートリアル > PHP はデータセットを共有メモリに直接保存します

PHP はデータセットを共有メモリに直接保存します

WBOY
リリース: 2016-06-20 13:01:27
オリジナル
1034 人が閲覧しました

共有メモリは、同じマシン上のアプリケーション間でデータを交換する効率的な方法です。プロセスは、正しい権限が割り当てられている限り、他のプロセスがアクセスできるメモリ セグメントを作成できます。各メモリ セグメントには、他のプロセスが動作できる物理メモリ領域を指す一意の ID (shmid と呼ばれる) があります。作成され、適切な権限が与えられると、同じマシン上の他のプロセスがこれらのメモリ セグメント上で読み取り、書き込み、削除を実行できるようになります。

これは、C で書かれたアプリケーションが、Java™ や PHP などの他の言語で書かれたアプリケーションと情報を共有できることを意味します。情報にアクセスして理解できる限り、全員が情報を共有できます。共有メモリはほとんどの言語の実装で広く使用されているため、アクセスは問題になりません。情報を理解するには、XML や JSON などの標準形式を使用できます。

共有メモリの使用は、主にメモリ セグメントの作成後にカーネルを介さずにデータが渡されるため、プロセス間でデータを高速に交換する方法です。この方法は、プロセス間通信 (IPC) と呼ばれることがよくあります。他の IPC メソッドには、パイプ、メッセージ キュー、RPC、ソケットなどがあります。アプリケーション間でデータを迅速かつ確実に交換できるこの機能は、相互に通信する必要があるアプリケーションのエコシステムを操作する場合に役立ちます。エコシステムの規模によっては、データベースを使用してアプリケーション間で情報を交換する一般的な方法では、多くの場合、クエリが遅くなったり、I/O ブロックが発生したりする可能性があります。共有メモリを使用すると、開発者の進行を遅らせる I/O が発生しません。

この記事の提案は非常にシンプルです。PHP を使用して共有メモリ セグメントを作成および操作し、それらを使用して他のアプリケーションで使用できるデータ セットを保存する方法を学びます。データ交換に共有メモリを使用する予定がない場合でも、アプリケーションが I/O の問題を回避できるため、それ自体に多くの利点があります。データセットをメモリに直接保存すると、Web サービス データのキャッシュからセッション共有まで、多くの利点があります。これは、すべての PHP 開発者が知っておくべき非常に便利な概念です。

共有メモリと PHP

PHP には、共有メモリと同様に、豊富な拡張機能が用意されています。いくつかの共有機能を使用すると、開発者は拡張機能をインストールせずにメモリ セグメントを簡単に操作できます。

トップに戻る メモリセグメントの作成

共有メモリ関数はファイル操作関数に似ていますが、ストリームを処理する代わりに、共有メモリ アクセス ID を処理します。最初の例は shmop_open 関数です。この関数を使用すると、既存のメモリ セグメントを開いたり、新しいメモリ セグメントを作成したりできます。この関数は、ファイル操作用のストリームを開き、開かれたストリームへの読み取りまたは書き込みを行う他の関数が使用するリソースを返す、古典的な fopen 関数に非常に似ています。リスト 1 の shmop_open を見てみましょう。

リスト 1. shmop_open 関数

<?php

$systemid = 864; // System ID for the shared memory segment

$mode = "c"; // Access mode

$permissions = 0755; // Permissions for the shared memory segment

$size = 1024; // Size, in bytes, of the segment

$shmid = shmop_open($systemid, $mode, $permissions, $size);

?>
ログイン後にコピー

この関数で最初に表示されるのは、システム ID パラメーターです。これは、システム内の共有メモリセグメントを識別する番号です。 2 番目のパラメータはアクセス モードで、fopen 関数のアクセス モードとよく似ています。メモリセグメントには 4 つの異なるモードでアクセスできます:

モード「a」。読み取り専用メモリセグメントにアクセスできます。

モード「w」。メモリセグメントの読み取りおよび書き込みにアクセスできます

モード "c" は、新しいメモリ セグメントを作成するか、メモリ セグメントが既に存在する場合は、読み取りと書き込みのためにそのセグメントを開こうとします

モード "n"。新しいメモリ セグメントを作成しますが、メモリ セグメントが既に存在する場合は失敗します

3 番目のパラメータはメモリセグメントの許可です。ここには 8 進数値を指定する必要があります。

4 番目のパラメータは、メモリ セグメント サイズをバイト単位で指定します。メモリ セグメントに書き込む前に、その上に適切なバイト数を割り当てる必要があります。

この関数は、他の関数がこの共有メモリ セグメントを操作するために使用できる ID 番号を返すことに注意してください。この ID は、パラメータとして渡されるシステム ID とは異なり、共有メモリのアクセス ID です。この 2 つを混同しないように注意してください。失敗すると、shmop_open は FALSE を返します。

トップに戻る メモリセグメントにデータを書き込みます

shmop_write 関数を使用して、共有メモリ ブロックにデータを書き込みます。この関数は使い方が簡単で、リスト 2 に示すように 3 つのパラメーターのみを受け入れます。

リスト 2. shmop_write を使用して共有メモリ ブロックにデータを書き込む

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);

shmop_write($shmid, "Hello World!", 0);

?>
ログイン後にコピー

この関数は fwrite 関数に似ており、オープン ストリーム リソース (fopen によって返される) と書き込むデータという 2 つのパラメーターを取ります。 shmop_write 関数もこのタスクを実行します。

最初のパラメータは shmop_open によって返される ID で、操作している共有メモリ ブロックを識別します。 2 番目のパラメータは保存したいデータで、最後の 3 番目のパラメータは書き込みを開始する位置です。デフォルトでは、書き込みを開始する場所を示すために常に 0 を使用します。この関数は失敗すると FALSE を返し、成功すると書き込まれたバイト数を返すことに注意してください。

トップに戻る メモリセグメントからデータを読み取る

共有メモリセグメントからのデータの読み取りは簡単です。必要なのは、開いているメモリ セグメントと shmop_read 関数だけです。この関数はいくつかのパラメータを受け取り、fread のように動作します。 PHP ファイルの内容を読むには、リスト 3 を参照してください。

清单 3. 使用 shmop_read 读取一个文件的内容

<?php

$stream = fopen('file.txt', 'r+');

fwrite($stream, "Hello World!");

echo fread($stream, 11);

?>
ログイン後にコピー

读取共享内存段的内容的过程与此类似,如清单 4 所示:

清单 4. 读取共享内存段的内容

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);

shmop_write($shmid, "Hello World!", 0);

echo shmop_read($shmid, 0, 11);

?>
ログイン後にコピー

请留意这里的参数。shmop_read 函数将接受 shmop_open 返回的 ID,我们已知道它,不过它还接受另外两个参数。第二个参数是您希望从内存段读取的位置,而第三个是您希望读取的字节数。第二个参数可以始终为 0,表示数据的开头,但第三个参数可能存在问题,因为我们不知道我们希望读取多少字节。

这非常类似于我们在 fread 函数中的行为,该函数接受两个参数:打开的流资源(由 fopen 返回)和您希望从该流读取的字节数。使用 filesize 函数(它返回一个文件中的字节数)来完整地读取它。

幸运的是,当使用共享内存段时,shmop_size 函数返回一个内存段的大小(以字节为单位),类似于 filesize 函数。参见清单 5。

清单 5. shmop_size 函数返回内存段大小,以字节为单位

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);

shmop_write($shmid, "Hello World!", 0);

$size = shmop_size($shmid);

echo shmop_read($shmid, 0, $size);

?>
ログイン後にコピー

回页首删除内存段

我们学习了如何打开、写入和读取共享内存段。要完成我们的 CRUD 类,我们还需要学习如何删除内存段。该任务可使用shmop_delete 函数轻松完成,该函数仅接受一个参数:我们希望删除的共享内存 ID。

清单 6. shmop_delete 标记要删除的内存段

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);

shmop_write($shmid, "Hello World!", 0);

shmop_delete($shmid);

?>
ログイン後にコピー

这不会实际删除该内存段。它将该内存段标记为删除,因为共享内存段在有其他进程正在使用它时无法被删除。shmop_delete 函数将该内存段标记为删除,阻止任何其他进程打开它。要删除它,我们需要关闭该内存段。

回页首关闭内存段

打开一个共享内存段会 “附加” 到它。附加该内存段之后,我们可在其中进行读取和写入,但完成操作后,我们必须从它解除。这使用清单 7 中的 shmop_close 函数来完成。

这非常类似于处理文件时的 fclose 函数。打开包含一个文件的流并在其中读取或写入数据后,我们必须关闭它,否则将发生锁定。

清单 7. 使用 shmop_close 与一个内存段分开

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);

shmop_write($shmid, "Hello World!", 0);

shmop_delete($shmid);

shmop_close($shmid);

?>
ログイン後にコピー

回页首使用共享内存作为一个存储选项

有了共享内存和共享内存段上基本 CRUD 操作的基本知识,是时候应用此知识了。我们可以使用共享内存作为一种独特的存储选项,提供快速读/写操作和进程互操作性等优势。对于 Web 应用程序,这意味着:

缓存存储(数据库查询、Web 服务数据、外部数据)

会话存储

应用程序之间的数据交换

在继续之前,我想介绍一个名为 SimpleSHM 小型库。SimpleSHM 是一个较小的抽象层,用于使用 PHP 操作共享内存,支持以一种面向对象的方式轻松操作内存段。在编写使用共享内存进行存储的小型应用程序时,这个库可帮助创建非常简洁的代码。要了解 SimpleSHM,请访问 GitHub 页面。

您可以使用 3 个方法进行处理:读、写和删除。从该类中简单地实例化一个对象,可以控制打开的共享内存段。清单 8 展示了基本用途。

清单 8. SimpleSHM 基本用途

<?php

$memory = new SimpleSHM;

$memory->write('Sample');

echo $memory->read();

?>
ログイン後にコピー

请注意,这里没有为该类传递一个 ID。如果没有传递 ID,它将随机选择一个编号并打开该编号的新内存段。我们可以以参数的形式传递一个编号,供构造函数打开现有的内存段,或者创建一个具有特定 ID 的内存段,如清单 9 所示。

清单 9. 打开一个特定的内存段

<?php

$new = new SimpleSHM(897);

$new->write('Sample');

echo $new->read();

?>
ログイン後にコピー

神奇的方法 __destructor 负责在该内存段上调用 shmop_close 来取消设置对象,以与该内存段分离。我们将这称为 “SimpleSHM 101”。现在让我们将此方法用于更高级的用途:使用共享内存作为存储。存储数据集需要序列化,因为数组或对象无法存储在内存中。尽管这里使用了 JSON 来序列化,但任何其他方法(比如 XML 或内置的 PHP 序列化功能)也已足够。清单 10 给出了一个示例。

清单 10. 使用共享内存作为存储

<?php

require('SimpleSHM.class.php');

$results = array(

'user' => 'John',

'password' => '123456',

'posts' => array('My name is John', 'My name is not John')

);

$data = json_encode($results);

$memory = new SimpleSHM;

$memory->write($data);

$storedarray = json_decode($memory->read());

print_r($storedarray);

?>
ログイン後にコピー

我们成功地将一个数组序列化为一个 JSON 字符串,将它存储在共享内存块中,从中读取数据,去序列化 JSON 字符串,并显示存储的数组。这看起来很简单,但请想象一下这个代码片段带来的可能性。您可以使用它存储 Web 服务请求、数据库查询或者甚至模板引擎缓存的结果。在内存中读取和写入将带来比在磁盘中读取和写入更高的性能。

このストレージ テクノロジの使用は、データが両端で読み取り可能な形式で保存されている限り、キャッシュだけでなく、アプリケーション間のデータ交換にも役立ちます。 Web アプリケーションの共有メモリの力を過小評価しないでください。このストレージを賢く実装するにはさまざまな方法がありますが、唯一の制限は開発者の創造性とスキルです。


関連ラベル:
php
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート