PHP verwendet Thrift für die serverseitige Entwicklung.
Thrift verwendet die Schnittstellenbeschreibungssprache zum Definieren und Erstellen von Diensten und verwendet das Binärformat zum Übertragen von Daten. Es ist besser für hohe Parallelität und große Datenmengen Mehrsprachige Umgebung.
Was ist Apache Thrift?
Apache Thrift ist ein erweiterbares, sprachübergreifendes Service-Calling-Framework, das von FaceBook entwickelt wurde. Um es einfach auszudrücken: Sie müssen zunächst eine Konfigurationsdatei definieren, um Server in ihren jeweiligen Sprachen basierend auf dieser Konfigurationsdatei zu generieren Mit anderen Worten: Basierend auf dem Thrift-Protokoll kann Java zum Aufrufen von PHP verwendet werden. Unterstützt derzeit den gegenseitigen Aufruf zwischen C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml und Delphi und anderen Sprachen.
Im Vergleich zu herkömmlichen Datenübertragungsmethoden wie XML und JSON verwendet Thrift die Schnittstellenbeschreibungssprache zum Definieren und Erstellen von Diensten und überträgt Daten im Binärformat. Es ist für hohe Parallelität und große Datenmengen geeignet Mehrsprachige Anwendungen werden besser unterstützt. Anforderungen an die Thrift-Installationsumgebung sind nicht installiert. Zuerst installieren, Andernfalls schlägt „make“ fehl und es kommt zu der Fehlermeldung „Lex- und Yacc-Befehl nicht gefunden“ (allgemeine Maschinen scheinen deinstalliert zu sein, verwenden Sie einfach „apt-get install flex bision“ für Ubuntu).
Thrift installieren
wget http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.3/thrift-0.9.3.tar.gz tar xvf thrift-0.9.3.tar.gz cd thrift-0.9.3
2. Erstellen Sie die Konfigurationsdatei
// 创建./configure文件 ./bootstrap.sh // 配置并安装 ./configure make // 检测是否有问题,如果机子没有安装python和java等可能会报错,不过本文主要讲php,安了php环境就行 make check make install
Verwenden Sie ./configure --help, um die Optionen anzuzeigen
Wenn Sie eine Sprache deaktivieren möchten, können Sie ./configure --without-java verwenden unpack()-Funktionen zum Sequenzieren Um Daten zu konvertieren
müssen Sie die APC-Erweiterung installieren, da die TSocketPool-Klasse die Funktionen apc_fetch() und apc_store() für APC-Cache-Vorgänge verwendet.
Wenn Sie Thrift mit PHP verwenden, müssen Sie zusätzlich zum Kopieren der Basisdateien in Thrift/lib/php/lib in das Projektverzeichnis auch die gemäß der Konfigurationsdatei generierten PHP-Dateien in den Paketordner kopieren und importieren Dies wird später im Projekt ausführlich besprochen.
klassebibliothek Beschreibung
TJSONProtocol, JSON-Format
Datenübertragungsmethode (Transport)
TBufferedTransport, zwischengespeicherte Übertragung, geschriebene Daten beginnen nicht sofort mit der Übertragung, bis der Cache aktualisiert wird.
TSocket verwendet Socket-Übertragung
TFramedTransport verwendet den Blockmodus für die Übertragung. Die spezifische Übertragungsimplementierung hängt von anderen Übertragungsmethoden ab, z. B. TSocketTHttpClient, verwenden Sie den Stream-Modus, um mit dem HTTP-Server zu interagieren.
IDL: 1.tutorial.thrift
include "shared.thrift" namespace php tutorial typedef i32 MyInteger const i32 INT32CONSTANT = 9853 const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} enum Operation { ADD = 1, SUBTRACT = 2, MULTIPLY = 3, DIVIDE = 4 } struct Work { 1: i32 num1 = 0, 2: i32 num2, 3: Operation op, 4: optional string comment, } exception InvalidOperation { 1: i32 whatOp, 2: string why } service Calculator extends shared.SharedService { void ping(), i32 add(1:i32 num1, 2:i32 num2), i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch), oneway void zip() }
2.shared.thrift
namespace php shared struct SharedStruct { 1: i32 key 2: string value } service SharedService { SharedStruct getStruct(1: i32 key) }
<?php namespace tutorial\php; ini_set('display_errors',1); error_reporting(E_ALL); // 引入类自动加载文件 require_once __DIR__.'/../../lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php'; // 载入自动加载类 use Thrift\ClassLoader\ThriftClassLoader; // 定义根据.thrift文件生成的php文件 $GEN_DIR = realpath(dirname(__FILE__).'/..').'/gen-php'; // 注册thrift服务 $loader = new ThriftClassLoader(); $loader->registerNamespace('Thrift', __DIR__ . '/../../lib/php/lib'); $loader->registerDefinition('shared', $GEN_DIR); $loader->registerDefinition('tutorial', $GEN_DIR); $loader->register(); if (php_sapi_name() == 'cli') { ini_set("display_errors", "stderr"); } use Thrift\Protocol\TBinaryProtocol; // 二进制格式打包解包 use Thrift\Transport\TPhpStream; // php流输入输出 use Thrift\Transport\TBufferedTransport; // 使用缓存 // 开始服务端逻辑 class CalculatorHandler implements \tutorial\CalculatorIf { protected $log = array(); public function ping() { error_log("ping()"); } // 相加 public function add($num1, $num2) { error_log("add({$num1}, {$num2})"); return $num1 + $num2; } // 枚举计算类型 public function calculate($logid, \tutorial\Work $w) { error_log("calculate({$logid}, {{$w->op}, {$w->num1}, {$w->num2}})"); switch ($w->op) { case \tutorial\Operation::ADD: $val = $w->num1 + $w->num2; break; case \tutorial\Operation::SUBTRACT: $val = $w->num1 - $w->num2; break; case \tutorial\Operation::MULTIPLY: $val = $w->num1 * $w->num2; break; case \tutorial\Operation::DIVIDE: if ($w->num2 == 0) { $io = new \tutorial\InvalidOperation(); $io->whatOp = $w->op; $io->why = "Cannot divide by 0"; throw $io; } $val = $w->num1 / $w->num2; break; default: $io = new \tutorial\InvalidOperation(); $io->whatOp = $w->op; $io->why = "Invalid Operation"; throw $io; } $log = new \shared\SharedStruct(); $log->key = $logid; $log->value = (string)$val; $this->log[$logid] = $log; return $val; } public function getStruct($key) { error_log("getStruct({$key})"); // This actually doesn't work because the PHP interpreter is // restarted for every request. //return $this->log[$key]; return new \shared\SharedStruct(array("key" => $key, "value" => "PHP is stateless!")); } public function zip() { error_log("zip()"); } }; header('Content-Type', 'application/x-thrift'); if (php_sapi_name() == 'cli') { echo "\r\n"; } $handler = new CalculatorHandler(); $processor = new \tutorial\CalculatorProcessor($handler); // 客户端和服务端在同一个输入输出流上 //1) cli 方式:php Client.php | php Server.php //2) cgi 方式:利用Apache或nginx监听http请求,调用php-fpm处理,将请求转换为PHP标准输入输出流 $transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W)); $protocol = new TBinaryProtocol($transport, true, true); $transport->open(); $processor->process($protocol, $protocol); $transport->close(); //作为cli方式运行,非阻塞方式监听,基于libevent实现,非官方实现 //$transportFactory = new TBufferedTransportFactory(); //$protocolFactory = new TBinaryProtocolFactory(true, true); //$transport = new TNonblockingServerSocket('localhost', 9090); //$server = new TNonblockingServer($processor, $transport, $transportFactory, $transportFactory, $protocolFactory, $protocolFactory); //$server->serve(); //作为cli方式运行,监听端口,官方实现 //$transportFactory = new TBufferedTransportFactory(); //$protocolFactory = new TBinaryProtocolFactory(true, true); //$transport = new TServerSocket('localhost', 9090); //$server = new TSimpleServer($processor, $transport, $transportFactory, $transportFactory, $protocolFactory, $protocolFactory); //$server->serve();
<?php namespace tutorial\php; error_reporting(E_ALL); require_once __DIR__.'/../../lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php'; use Thrift\ClassLoader\ThriftClassLoader; $GEN_DIR = realpath(dirname(__FILE__).'/..').'/gen-php'; $loader = new ThriftClassLoader(); $loader->registerNamespace('Thrift', __DIR__ . '/../../lib/php/lib'); $loader->registerDefinition('shared', $GEN_DIR); $loader->registerDefinition('tutorial', $GEN_DIR); $loader->register(); use Thrift\Protocol\TBinaryProtocol; use Thrift\Transport\TSocket; use Thrift\Transport\THttpClient; use Thrift\Transport\TBufferedTransport; use Thrift\Exception\TException; // 以上配置跟服务端类似 try { if (array_search('--http', $argv)) { // 使用http方式连接 $socket = new THttpClient('localhost', 8080, '/php/PhpServer.php'); } else { // 使用socket连接 $socket = new TSocket('localhost', 9090); } $transport = new TBufferedTransport($socket, 1024, 1024); $protocol = new TBinaryProtocol($transport); $client = new \tutorial\CalculatorClient($protocol); $transport->open(); $client->ping(); print "ping()\n"; $sum = $client->add(1,1); print "1+1=$sum\n"; // 调试异常情况 $work = new \tutorial\Work(); $work->op = \tutorial\Operation::DIVIDE; $work->num1 = 1; $work->num2 = 0; try { $client->calculate(1, $work); print "Whoa! We can divide by zero?\n"; } catch (\tutorial\InvalidOperation $io) { print "InvalidOperation: $io->why\n"; } $work->op = \tutorial\Operation::SUBTRACT; $work->num1 = 15; $work->num2 = 10; $diff = $client->calculate(1, $work); print "15-10=$diff\n"; $log = $client->getStruct(1); print "Log: $log->value\n"; $transport->close(); } catch (TException $tx) { print 'TException: '.$tx->getMessage()."\n"; }
// php client.php --http ping() 1+1=2 InvalidOperation: Cannot divide by 0 15-10=5 Log: PHP is stateless!
Das obige ist der detaillierte Inhalt vonDinge über die Verwendung von Thrift in PHP für die serverseitige Entwicklung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!