ホームページ > バックエンド開発 > PHPチュートリアル > asyncライブラリの書き込み - 'はHTMLをPDFに変換します

asyncライブラリの書き込み - 'はHTMLをPDFに変換します

William Shakespeare
リリース: 2025-02-10 15:51:11
オリジナル
788 人が閲覧しました

Writing Async Libraries - Let's Convert HTML to PDF

キーポイント

    HTMLからPDFなどのPHPの非同期プログラミングにより、非ブロッキング操作は他のコードを同時に実行することでパフォーマンスを改善できます。
  • 非同期フレームワークで約束とコールバックを使用すると、遅延操作と潜在的なエラー処理が簡素化され、コードがより堅牢で維持が容易になります。
  • カスタム非同期ライブラリ(この記事で議論されているHTMLからPDFコンバーターなど)の開発には、ReactPHPやAMPなどのツールを使用して非同期タスクを効果的に管理する抽象化を作成することが含まれます。
  • 非同期コードは、同期実行に適応し、非同期プログラミングの利点を犠牲にすることなく、異なるアプリケーションアーキテクチャ間の互換性と柔軟性を確保できます。
  • 並列実行ロジックを一般的なドライバーシステムに抽象化することにより、複数のフレームワークと環境をサポートでき、さまざまな非同期ライブラリとインターフェイスできます。
  • この記事では、PHPでの非同期HTMLのPDF変換への実際の実装について説明し、効率的なアプリケーション開発のための最新のプログラミングパラダイムの理解と利用の重要性を強調しています。
  • この記事は、トーマス・パントによって査読されました。 SetePointコンテンツを最高に獲得してくれたSetePointのすべてのピアレビューアに感謝します!
PHP非同期プログラミングのトピックについては、ほぼすべての会議について説明します。今はとても頻繁に言及されてうれしいです。しかし、これらのスピーカーは秘密を明らかにしませんでした...

非同期サーバーの作成、ドメイン名の解決、ファイルシステムとの対話:これらはすべて簡単なものです。独自の非同期ライブラリを作成することは困難です。そして、それはまさにあなたがあなたのほとんどの時間を過ごす場所です!


これらの単純なことは、概念の証明であるため、単純です - 非同期PHPをnodejsと競合するようにします。あなたは彼らの初期のインターフェイスがどれほど似ているかを見ることができます:

Writing Async Libraries - Let's Convert HTML to PDF このコードは、ノード7.3.0

を使用してテストされています

var http = require("http");
var server = http.createServer();

server.on("request", function(request, response) {
    response.writeHead(200, {
        "Content-Type": "text/plain"
    });

    response.end("Hello World");
});

server.listen(3000, "127.0.0.1");
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
このコードは、PHP 7.1およびReact/HTTP:0.4.2

を使用してテストされています

今日、私たちはあなたのアプリケーションコードを非同期アーキテクチャでうまく実行するためのいくつかの方法を調べます。心配しないでください - あなたのコードはまだ同期アーキテクチャで機能する可能性があるため、この新しいスキルを学ぶために何もあきらめる必要はありません。時間を費やすことに加えて...
require "vendor/autoload.php";

$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$server = new React\Http\Server($socket);

$server->on("request", function($request, $response) {
    $response->writeHead(200, [
        "Content-Type" => "text/plain"
    ]);

    $response->end("Hello world");
});

$socket->listen(3000, "127.0.0.1");
$loop->run();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

このチュートリアルのコードをGitHubで見つけることができます。 PHP 7.1とReactPHPとAMPの最新バージョンでテストしました。

希望に満ちた理論

非同期コードにはいくつかの共通の抽象化があります。それらの1つを見ました:コールバック。名前が示すように、コールバックは、操作が遅いまたはブロックする方法を説明します。同期コードは待機でいっぱいです。何かを求めて、何かが起こるのを待ちます。
したがって、非同期フレームワークとライブラリはコールバックを使用できます。それが起こったときに何かをリクエストします:フレームワークまたはライブラリはあなたのコードを呼び戻します。

HTTPサーバーの場合、すべてのリクエストを先制的に処理することはありません。リクエストが発生するのを待つこともありません。リクエストが発生した場合、呼び出されるコードを説明するだけです。イベントループは、残りの作業を処理します。

2番目の一般的な抽象化は約束です。コールバックは将来のイベントを待っているフックであり、約束は将来の価値への参照です。彼らは次のように見えます:

var http = require("http");
var server = http.createServer();

server.on("request", function(request, response) {
    response.writeHead(200, {
        "Content-Type": "text/plain"
    });

    response.end("Hello World");
});

server.listen(3000, "127.0.0.1");
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これには、コールバックだけを使用するよりも少し多くのコードがありますが、それを行うのに興味深い方法です。私たちは何かが起こるのを待ってから、別のことをします。何かがうまくいかない場合は、エラーをキャッチし、合理的に対応します。これは簡単に思えますが、完全には議論されていません。

私たちはまだコールバックを使用していますが、それらを抽象化に包みました。これは他の方法で役立ちます。利点の1つは、複数の解析コールバックを許可することです...

require "vendor/autoload.php";

$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$server = new React\Http\Server($socket);

$server->on("request", function($request, $response) {
    $response->writeHead(200, [
        "Content-Type" => "text/plain"
    ]);

    $response->end("Hello world");
});

$socket->listen(3000, "127.0.0.1");
$loop->run();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

私たちに別のことに集中してほしい。つまり、Promiseは共通の言語(共通の抽象化)を提供し、同期コードが非同期コードになる方法について考えることです。

いくつかのアプリケーションコードを取得して非同期にしましょう。

pdfファイルを作成

アプリケーションは、請求書または在庫リストであろうと、いくつかの種類の要約文書を生成することが一般的です。 Stripeを介して支払いを処理するeコマースアプリケーションがあるとします。顧客がアイテムを購入したら、トランザクションのためにPDF領収書をダウンロードできるようにします。

これはさまざまな方法で行うことができますが、非常に簡単な方法は、HTMLとCSSを使用してドキュメントを生成することです。 PDFドキュメントに変換して、顧客がダウンロードできるようにすることができます。

最近似たようなことをする必要があります。この操作をサポートする優れたライブラリはあまりないことがわかりました。異なるHTML→PDFエンジンを切り替えることができる単一の抽象化を見つけることができません。それで私は自分で1つを作り始めました。

私は自分の抽象化が何をする必要があるかを考え始めました。私は非常によく似たインターフェイスを選択しました:

readFile()
    ->then(function(string $content) {
        print "content: " . $content;
    })
    ->catch(function(Exception $e) {
        print "error: " . $e->getMessage();
    });
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
簡単にするために、レンダリング方法を除くすべての方法がゲッターおよびセッターとして機能することを願っています。この一連の予想される方法を考えると、次に行うべきことは、可能なエンジンを使用して実装を作成することです。 DOMPDFを自分のプロジェクトに追加し、使用を開始しました。

$promise = readFile();
$promise->then(...)->catch(...);

// ...让我们向现有代码添加日志记录

$promise->then(function(string $content) use ($logger) {
    $logger->info("file was read");
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
DOMPDFの使用方法について詳しく説明しません。この実装の非同期の部分に焦点を合わせることができるように、ドキュメントは十分に十分に行われていると思います。

データと並列メソッドを後で確認します。このドライバーの実装の重要なことは、データ(設定されている場合、デフォルト値)とカスタムオプションを一緒に収集することです。これらを非同期に実行したいコールバックに渡します。

dompdfは非同期ライブラリではなく、HTMLをPDFに変換することは非常に遅いプロセスです。では、どのようにして非同期にするのでしょうか?まあ、完全に非同期コンバーターを書くことも、既存の同期コンバーターを使用することもできます。

これは私が並列方法のためにしたことです:

var http = require("http");
var server = http.createServer();

server.on("request", function(request, response) {
    response.writeHead(200, {
        "Content-Type": "text/plain"
    });

    response.end("Hello World");
});

server.listen(3000, "127.0.0.1");
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで、Getter-Setterメソッドを実装し、次の実装のためにそれらを再利用できると考えました。データメソッドは、さまざまなドキュメント属性を配列に収集するショートカットとして機能し、匿名関数への渡しを容易にします。

並列メソッドが興味深いようになり始めます:

require "vendor/autoload.php";

$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$server = new React\Http\Server($socket);

$server->on("request", function($request, $response) {
    $response->writeHead(200, [
        "Content-Type" => "text/plain"
    ]);

    $response->end("Hello world");
});

$socket->listen(3000, "127.0.0.1");
$loop->run();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

私はAMPプロジェクトが本当に好きです。非同期アーキテクチャをサポートするライブラリのコレクションであり、それらはAsync-Interopプロジェクトの重要な支持者です。

それらのライブラリの1つは、Multi-ThreadedおよびMulti-ProcessコードをサポートするAMPHP/Parallelと呼ばれます(PTHREADとプロセス制御を介して拡張)。これらのスポーンメソッドは、AMPの約束の実装を返します。これは、レンダリング方法を、約束を返す他の方法と同様に使用できることを意味します。

readFile()
    ->then(function(string $content) {
        print "content: " . $content;
    })
    ->catch(function(Exception $e) {
        print "error: " . $e->getMessage();
    });
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
このコードは少し複雑です。 AMPは、通常のPHPジェネレーターをCoroutines and Promisesに変換できるように、イベントループ実装とすべての補助コードも提供します。あなたは別の投稿で読むことができます私はこれがどのように可能であるか、それがPHPのジェネレーターとどのように関連するかを書きました。

返された約束も標準化されています。 AMPは、約束仕様の実装を返します。上記のコードとはわずかに異なりますが、それでも同じ関数を実行します。

ジェネレーターは、コルーチンのある言語のコルーチンのように機能します。 Coroutinesは、中断できる機能です。つまり、短期操作を実行し、何かを待っている間に一時停止するために使用できます。一時停止中、他の機能はシステムリソースを使用できます。

実際、これは次のようになります:

$promise = readFile();
$promise->then(...)->catch(...);

// ...让我们向现有代码添加日志记录

$promise->then(function(string $content) use ($logger) {
    $logger->info("file was read");
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
これは、最初に同期コードを書くよりもはるかに複雑に思えます。しかし、それが許すのは、funcreturnspromiseが完了するのを待つときに何か他のことが起こる可能性があるということです。

約束を生成することは、まさに抽象化と呼ばれるものです。それは、約束を返す関数を作成できるフレームワークを提供します。コードは、これらの約束と予測可能で理解可能な方法で対話できます。

ドライバーを使用してPDFドキュメントをレンダリングするのがどのように見えるかを見てください:

interface Driver
{
    public function html($html = null);
    public function size($size = null);
    public function orientation($orientation = null);
    public function dpi($dpi = null);
    public function render();
}
ログイン後にコピー
これは、非同期HTTPサーバーでPDFSを生成するほど有用ではありません。これらのタイプのサーバーの作成を容易にするAerysと呼ばれるアンプライブラリがあります。 Aerysを使用して、次のHTTPサーバーコードを作成できます。

class DomDriver extends BaseDriver implements Driver
{
    private $options;

    public function __construct(array $options = [])
    {
        $this->options = $options;
    }

    public function render()
    {
        $data = $this->data();
        $custom = $this->options;

        return $this->parallel(
            function() use ($data, $custom) {
                $options = new Options();

                $options->set(
                    "isJavascriptEnabled", true
                );

                $options->set(
                    "isHtml5ParserEnabled", true
                );

                $options->set("dpi", $data["dpi"]);

                foreach ($custom as $key => $value) {
                    $options->set($key, $value);
                }

                $engine = new Dompdf($options);

                $engine->setPaper(
                    $data["size"], $data["orientation"]
                );

                $engine->loadHtml($data["html"]);
                $engine->render();

                return $engine->output();
            }
        );
    }
}
ログイン後にコピー
同様に、私は今は詳細にエリスに入りません。これは、独自の記事を持つ価値がある印象的なソフトウェアです。私たちのコンバーターコードがその隣にどのように見えるかを見るために、Aerysがどのように機能するかを理解する必要はありません。

私の上司は「非同期を使用しないでください!」<

非同期アプリケーションを構築するのにどれくらい時間がかかるかわからない場合、なぜそんなに努力が必要なのですか?このコードを書くことで、新しいプログラミングパラダイムに関する洞察を得ることができます。そして、私たちがこのコードを非同期と書いているからといって、同期環境では機能しないという意味ではありません。 このコードを同期アプリケーションで使用するには、内部で非同期コードを移動するだけです。 このデコレーターを使用すると、同期コードのように見えるコードを書くことができます:

var http = require("http");
var server = http.createServer();

server.on("request", function(request, response) {
    response.writeHead(200, {
        "Content-Type": "text/plain"
    });

    response.end("Hello World");
});

server.listen(3000, "127.0.0.1");
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

それはまだ(少なくともバックグラウンドで)非同期にコードを実行しますが、これはすべて消費者にさらされていません。同期アプリケーションで使用でき、舞台裏で何が起こっているのかわからないでしょう。

他のフレームワークをサポート

AMPには、すべての環境に適していない特定の要件があります。たとえば、基本アンプ(イベントループ)ライブラリにはPHP 7.0が必要です。パラレルライブラリには、Pthreads拡張機能またはプロセス制御拡張機能が必要です。

これらの制限をすべての人に課したくないので、より広いシステムをどのようにサポートできるかを知りたいです。答えは、並列実行コードを別のドライバーシステムに抽象化することです。

require "vendor/autoload.php";

$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$server = new React\Http\Server($socket);

$server->on("request", function($request, $response) {
    $response->writeHead(200, [
        "Content-Type" => "text/plain"
    ]);

    $response->end("Hello world");
});

$socket->listen(3000, "127.0.0.1");
$loop->run();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
アンプ用にも実装できます(制限が少ないが、古いが古い)reactphp:

readFile()
    ->then(function(string $content) {
        print "content: " . $content;
    })
    ->catch(function(Exception $e) {
        print "error: " . $e->getMessage();
    });
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
私は閉鎖をマルチスレッドとマルチプロセスワーカーに渡すことに慣れています。それが、PTHREADとプロセス制御の動作です。 ReactPhpプロセスオブジェクトを使用することは、マルチプロセスの実行にexecに依存しているため、まったく異なります。使用することに慣れているのと同じ閉鎖関数を実装することにしました。これは非同期コードには必要ありません - それは純粋に好みの問題です。

SuperClosureライブラリは、閉鎖とそのバインド変数をシリアル化します。ここのコードのほとんどは、ワーカースクリプトで見つけると予想されるコードです。実際、ReactPHPの子プロセスライブラリを使用する唯一の方法(閉鎖のシリアル化以外)は、ワーカースクリプトにタスクを送信することです。

今、ドライバーは$ this&gt; parallel and amp固有のコードをロードしなくなりましたが、実行プログラムの実装に合格することができます。 Asyncコードとして、これは次のようなものです

$promise = readFile();
$promise->then(...)->catch(...);

// ...让我们向现有代码添加日志记录

$promise->then(function(string $content) use ($logger) {
    $logger->info("file was read");
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ReactPhpコードとAMPコードの違いにショックを受けないでください。 ReactPHPは、AMPと同じコルーチンベースを実装しません。代わりに、ReactPHPは、ほとんどのことを処理するためにコールバックを使用することを好みます。このコードは、PDF変換を並行して実行するだけで、生成されたPDFデータを返します。

プログラムを要約で実行することにより、必要な非同期フレームワークを使用できます。また、そのフレームワークの抽象化を返すために使用するドライバーが期待できます。

これを使用できますか?

最初は単なる実験であり、複数のドライバーと複数の実行プログラムを備えたHTML→PDFライブラリになりました。これは、HTML→PDFに相当するフライシステムのようなものですが、非同期ライブラリを書く方法の素晴らしい例でもあります。

非同期PHPアプリケーションを作成しようとすると、ライブラリエコシステムにギャップがあります。これらに怖がらないでください!代わりに、ReactPHPとAMPが提供する抽象化を使用して独自の非同期ライブラリを作成する機会を考えてください。

最近、興味深い非同期PHPアプリケーションまたはライブラリを作成しましたか?コメントでお知らせください。

非同期変換HTMLをPDF

に変換する

FAQ

HTMLからPDFへの非同期変換の意味は何ですか?

非同期プログラミングは、HTMLをPDFに変換する上で重要な役割を果たします。非ブロッキング操作を実行することができます。つまり、エンジンがバックグラウンドで実行されているため、非同期操作が完了したときにコードの残りの部分が実行を継続できます。これにより、特にHTMLをPDFに変換するなど、多数のI/O操作が関与するアプリケーションでは、リソースのより効率的な使用とパフォーマンスの改善につながります。

ReactPhpは非同期ライブラリの作成にどのように役立ちますか?

ReactPhpは、PHPでのイベント駆動型プログラミングの低レベルライブラリです。 PHPで非同期ライブラリを作成するためのコアインフラストラクチャを提供します。 ReactPHPを使用すると、PHPの馴染みのある構文を使用して非ブロッキングコードを記述することができ、高性能アプリケーションの作成が容易になります。

HTMLからPDFへの非同期変換に伴う手順は何ですか?

HTMLからPDFへの非同期変換のプロセスには、いくつかのステップが含まれます。まず、PDFの構造と内容を定義するHTMLテンプレートを設定する必要があります。次に、ReactPhpのような非同期ライブラリを使用して、変換プロセスを処理します。これには、HTMLファイルの読み取り、PDFに変換してから、生成されたPDFファイルを保存することが含まれます。このプロセスの非同期性は、変換が進行中にアプリケーションが他のタスクを実行し続けることができることを意味します。

PHP以外の言語を使用して非同期にプログラムできますか?

はい、他の言語で非同期にプログラムできます。たとえば、node.jsは、イベント駆動型アーキテクチャにより、非同期アプリケーションを構築するための一般的な選択肢です。ただし、すでにPHPに精通している場合、ReactPhpのようなライブラリを使用すると、新しい言語を学習せずに非同期プログラミングを簡単に利用できます。

HTMLからPDFへの非同期変換中にエラーを処理する方法は?

エラー処理は、非同期プログラミングの重要な側面です。 ReactPhpでは、エラーイベントハンドラーをPromiseオブジェクトに添付することでエラーを処理できます。コンバージョンプロセス中にエラーが発生した場合、このハンドラーが呼び出され、エラーを記録したり、他の適切なアクションを実行したりできます。

HTMLをPDFに変換することの利点は何ですか?

HTMLをPDFに変換することには多くの利点があります。これにより、オフライン、印刷、または簡単に共有できる静的なポータブルバージョンのWebページを作成できます。 PDFは、元のHTMLの形式とレイアウトも保持し、表示されているデバイスやプラットフォームに関係なくコンテンツが同じように見えるようにします。

非同期PHPアプリケーションのパフォーマンスを最適化する方法は?

非同期PHPアプリケーションのパフォーマンスを最適化する方法はいくつかあります。 1つのアプローチは、ReactPhpのようなライブラリを使用することです。これは、イベント駆動型プログラミングに低レベルのインターフェイスを提供します。これにより、非ブロッキングコードを作成できます。これにより、HTMLをPDFに変換するなどのI/O集約型操作のパフォーマンスを大幅に改善できます。

HTMLを同期してPDFに変換できますか?

はい、HTMLは同期してPDFに変換できます。ただし、このアプローチは、コンバージョンプロセスが完了するまでアプリケーションの実行をブロックする場合があり、I/O集約型アプリケーションのパフォーマンスの問題を引き起こす可能性があります。一方、非同期変換により、アプリケーションは変換が進行中に他のタスクを実行し続けることができ、パフォーマンスとリソースの利用が向上します。

PHPにおける非同期プログラミングの課題は何ですか?

PHPの同期特性により、PHPの非同期プログラミングは困難な場合があります。ただし、ReactPhpのようなライブラリは、PHPで非ブロッキングコードを作成するために必要なアーキテクチャを提供します。イベント主導のプログラミングモデルを理解し、約束の使用を習得することも困難な場合がありますが、非同期プログラミングの利点を活用するための鍵です。

非同期PHPアプリケーションのパフォーマンスをテストする方法は?

非同期PHPアプリケーションのパフォーマンスのテストには、応答時間、メモリ使用量、CPU利用などのさまざまな負荷条件下での重要なメトリックの測定が含まれます。 Apache JmeterやSiegeなどのツールを使用して、アプリケーションの負荷をシミュレートし、パフォーマンスデータを収集できます。さらに、Xdebugなどの分析ツールは、コードのボトルネックを特定し、パフォーマンスを最適化するのに役立ちます。

以上がasyncライブラリの書き込み - &#x27;はHTMLをPDFに変換しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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