Undr

На память

Реализация google protocol buffers на php

1 Star2 Stars3 Stars4 Stars5 Stars (2 голосов, средний: 5.00 из 5)
Loading ... Loading ...

without comments

phpbuf – реализация google protocol buffers на php.

Эта библиотека не имеет пока генераторов кода. Классы сообщений нужно писать самому. Благо что пишутся они очень просто.

Установка

Просто копируете содержимое папки lib в удобное для Вас место. Потом подключаете файл PhpBuf.php

require_once("PhpBuf.php");

Классы сообщений

Классы сообщений наследуются от класса PhpBuf_Message_Abstract, в конструкторе описывается структура. Например, класс:

class Message_Example extends PhpBuf_Message_Abstract {
    public function __construct() {
        $this->setField("id", PhpBuf_Type::INT, PhpBuf_Rule::REQUIRED, 1);
        $this->setField("balance", PhpBuf_Type::SINT, PhpBuf_Rule::REQUIRED, 2);
        $this->setField("isAdmin", PhpBuf_Type::BOOL, PhpBuf_Rule::REQUIRED, 3);
        $this->setField("status", PhpBuf_Type::ENUM, PhpBuf_Rule::REQUIRED, 4, array("active", "inactive", "deleted"));
        $this->setField("name", PhpBuf_Type::STRING, PhpBuf_Rule::REQUIRED, 5);
        $this->setField("bytes", PhpBuf_Type::BYTES, PhpBuf_Rule::REQUIRED, 6);
    }
}

соответствует .proto файлу:

message Message_Example {
    required int32 id = 1;
    required sint32 balance = 2;
    required bool isAdmin = 3;
    enum Status {
      active = 0;
      inactive = 1;
      deleted = 2;
    }
    required enum Status status = 4;
    required string name = 5;
    required bytes bytes = 6;
}

Вызов метода setField() создает атрибут объекта с определенным типом. Метод принимает пять параметров: protected function setField($name, $type, $rule, $index, $extra = "")

  • $name – определяет имя атрибута
  • $type – определяет тип атрибута. Тип атрибута задается обычно константой определенной в классе PhpBuf_Type. На сегодняшний момент поддерживаются 7 типов: bool (PhpBuf_Type::BOOL), bytes (PhpBuf_Type::BYTES), int32 (PhpBuf_Type::INT), sint32 (PhpBuf_Type::SINT), string (PhpBuf_Type::STRING), enum (PhpBuf_Type::ENUM) и message (PhpBuf_Type::MESSAGE)
  • $rule – определяет правила для сериализации и десериализации атрибута. Их три: PhpBuf_Rule::REQUIRED, PhpBuf_Rule::REPEARED и PhpBuf_Rule::OPTIONAL. Обычно задается одной из этих констант.
  • $index – определяет индекс атрибута (необходим для сериализации и десериализации).
  • $extra – определяет дополнительные параметры. Используется в двух случаях: когда тип атрибута PhpBuf_Type::ENUM, нужно передать массив возможных значений для перечисляемого типа; и когда тип атрибута PhpBuf_Type::MESSAGE, тогда надо передать имя класса сообщения.

Подробнее о типах и правилах можете прочитать на странице проекта google protocol buffers

message SearchResponse {
  message Result {
    required string url = 1;
    optional string title = 2;
    repeated string snippets = 3;
  }
  repeated Result result = 1;
}
class Result extends PhpBuf_Message_Abstract {
    public function __construct() {
        $this->setField("url", PhpBuf_Type::STRING, PhpBuf_Rule::REQUIRED, 1);
        $this->setField("title", PhpBuf_Type::STRING, PhpBuf_Rule::OPTIONAL, 2);
        $this->setField("snippets", PhpBuf_Type::STRING, PhpBuf_Rule::REPEATED, 3);
    }
}
class SearchResponse extends PhpBuf_Message_Abstract {
    public function __construct() {
        $this->setField("result", PhpBuf_Type::MESSAGE, PhpBuf_Rule::REPEATED, 1, "Result");
    }
}

Пример использования

class Request extends PhpBuf_Message_Abstract {
    public function __construct() {
        $this->setField("query", PhpBuf_Type::STRING, PhpBuf_Rule::REQUIRED, 1);
    }
}
class Result extends PhpBuf_Message_Abstract {
    public function __construct() {
        $this->setField("url", PhpBuf_Type::STRING, PhpBuf_Rule::REQUIRED, 1);
        $this->setField("title", PhpBuf_Type::STRING, PhpBuf_Rule::OPTIONAL, 2);
        $this->setField("snippets", PhpBuf_Type::STRING, PhpBuf_Rule::REPEATED, 3);
    }
}
class SearchResponse extends PhpBuf_Message_Abstract {
    public function __construct() {
        $this->setField("result", PhpBuf_Type::MESSAGE, PhpBuf_Rule::REPEATED, 1, "Result");
    }
}
$rawData = isset($GLOBALS['HTTP_RAW_POST_DATA'])? $GLOBALS['HTTP_RAW_POST_DATA'] : @file_get_contents("php://input");

$request = new Request();
$request->read(new PhpBuf_IO_Reader($rawData));

$result = doSomethingQuery($request->query);

$response = new SearchResponse();
$arrayResult = array();
foreach($result as $item) {
    $result = new Result;
    $result->url = $item['url'];
    if(isset($item['title']) && !empty($item['title'])) {
        $result->title = $item['title'];
    }
    if(isset($item['snippets']) && !empty($item['snippets'])) {
        $result->snippets = $item['snippets'];
    }
    $arrayResult[] = $result;
}
$response->result = $arrayResult;

$writer = new PhpBuf_IO_Writer();
$response->write($writer);

header("Content-type: application/octet-stream");
echo $writer->getData();
exit;
?>

Написал undr ()

15 октября 2009 в 19:55

Оставьте комментарий