В целях повышения производительности и безопасности на платформе компании отключены чтение и запись локальных файлов, а также сбор внешних данных. Соответственно, мы предоставляем соответствующие услуги, чтобы сделать то же самое. Интерфейс нового сервиса отличается от оригинального
Программа, специально разработанная для нашей платформы, конечно, не имеет проблем, но существует множество существующих программ и проектов с открытым исходным кодом, которые сталкиваются со сложной миграционной работой
Обертка
Фактически, PHP поддерживает оболочку начиная с PHP 4.3, что означает, что пользователи могут настраивать и перегружать протоколы
Просто используйте stream_wrapper_register
Функция может зарегистрировать протокол. PHP вызовет соответствующие функции для соответствующих операций протокола
В руководстве приведен пример. Он регистрирует протокол под названием VaR, а затем вызывает операцию этого протокола Класс переменного потока
Метод, определенный внутри
varname = $url["host"]; $this->position = 0; return true; } function stream_read($count) { $ret = substr($GLOBALS[$this->varname], $this->position, $count); $this->position += strlen($ret); return $ret; } function stream_write($data) { $left = substr($GLOBALS[$this->varname], 0, $this->position); $right = substr($GLOBALS[$this->varname], $this->position + strlen($data)); $GLOBALS[$this->varname] = $left . $data . $right; $this->position += strlen($data); return strlen($data); } function stream_tell() { return $this->position; } function stream_eof() { return $this->position >= strlen($GLOBALS[$this->varname]); } function stream_seek($offset, $whence) { switch ($whence) { case SEEK_SET: if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) { $this->position = $offset; return true; } else { return false; } break; case SEEK_CUR: if ($offset >= 0) { $this->position += $offset; return true; } else { return false; } break; case SEEK_END: if (strlen($GLOBALS[$this->varname]) + $offset >= 0) { $this->position = strlen($GLOBALS[$this->varname]) + $offset; return true; } else { return false; } break; default: return false; } } } stream_wrapper_register("var", "VariableStream") or die("Failed to register protocol"); $myvar = ""; $fp = fopen("var://myvar", "r+"); fwrite($fp, "line1\n"); fwrite($fp, "line2\n"); fwrite($fp, "line3\n"); rewind($fp); while (!feof($fp)) { echo fgets($fp); } fclose($fp); var_dump($myvar); ?>
Список интерфейсов, которые могут быть реализованы в классе обратного вызова, находится здесь: http://cn2. php .net/manual/en/class.streamwrapper.php
Некоторые проблемы, требующие внимания
Конструкторы
Прежде всего, класс-оболочка
В частности, его конструктор вызывается не каждый раз. Только когда ваша операция запускает операции, связанные с stream_ Open, такие как вы используете file_get_contents
Когда вы запускаете независимые от потока функции, такие как file_ Exists, запускает метод URL_ Stat, конструктор в это время вызываться не будет
Прочитайте реализацию
Существуют такие понятия, как положение и поиск в оболочке, но многие службы фактически считывают все данные одновременно. Это можно найти в stream_open
Прочитайте его за один раз и поместите в атрибут. Позже вы сможете напрямую управлять данными, хранящимися в атрибуте в разделе поиск и передача
url_ Реализация государственной
В реализации класса-оболочки URL_ Реализация состояния представляет собой трудность. URL должен быть реализован правильно. _ Статистика может сделать is_writable
И is_читаемые и другие функции для запроса метаинформации файлов работают нормально
И нам нужно подделать эти значения для нашего виртуального устройства. Возьмите MC в качестве примера, я дам вам некоторые справочные данные
url_ Stat должен возвращать массив из 13 элементов следующим образом:
Номер устройства разработчика – запись 0
Номер индекса Ino – напишите 0
Режим режим файла – это символ управления разрешениями файла, который будет подробно описан позже
Ссылка Nlink – запись 0
Uid uid – POSIX на Linux_ get_ Uid может быть получен, 0 в Windows
GID GID – POSIX в Linux_ get_ GID можно получить, 0 в Windows
Тип устройства Rdev – имеет значение, если это устройство с индексом
Размер размер файла
Последний формат времени чтения времени-метка времени UNIX
Время последней записи
время создания CTime
Размер блока Blksize ввода-вывода файловой системы
Блоки количество выделенных блоков по 512 байт
Значение режима должно быть записано правильно
Если это файл, то значение равно
разрешение на файл 0100000 +; например, 0100000 + 0777;
Если это каталог, то значение равно
разрешение каталога 040000 +, например 0400000 + 0777;
Стандартные протоколы могут быть перегружены
Согласно фактическому тесту, с помощью stream_wrapper_unregister
Вы можете удалить встроенные протоколы, такие как HTTP. Это удобно для нас, чтобы полностью и легко заменить некоторые операции пользователей, такие как file_get_contents('http://sae.sina.com.cn')
К нашим собственным услугам
Дополнение к пункту знаний:
Реализация PHP-оболочки
[предыстория]
Сделайте оболочку бережливого клиента, чтобы реализовать логику поиска для сервера.
[ключевые моменты]
1. Обертка так же удобна, как и клиент.
2. При сбое сервера вы можете случайным образом выбрать другой сервер для повторной попытки.
3. Несколько ключевых функций PHP:__ Call () (волшебная функция, которая будет вызвана, когда функция объекта доступа не существует), класс отражения отражает класс и его функцию-член newinstanceargs, функцию обратного вызова массива call_ user_ func_.
Давайте посмотрим на код напрямую (написанный великим человеком, а не мной).
#!/usr/bin/env php registerNamespace('Thrift', '/usr/local/Cellar/thrift/0.9.1/'); $loader->registerDefinition('xiaoju', $GEN_DIR); $loader->register(); use Thrift\Protocol\TBinaryProtocol; use Thrift\Transport\TSocket; use Thrift\Transport\THttpClient; use Thrift\Transport\TBufferedTransport; use Thrift\Exception\TException; class RetryWrapper { public function __construct($classname, $hosts) { $this->clazz = new \ReflectionClass($classname); $this->hosts = $hosts; } public function __call($method, $args) { shuffle($this->hosts); foreach ($this->hosts as $key => $host) { try { return $this->inner_call($host, $method, $args); } catch (TException $ex) { $msg = $ex->getMessage(); if (!strstr($msg, 'TSocket')) { throw $ex; } } } throw new TException("all server down!"); } public function inner_call($host, $method, $args) { $tmp = explode(":", $host); $socket = new TSocket($tmp[0], (int)$tmp[1]); $transport = new TBufferedTransport($socket, 1024, 1024); $protocol = new TBinaryProtocol($transport); $client = $this->clazz->newInstanceArgs(array($protocol)); $transport->open(); $result = call_user_func_array(array($client, $method), $args); $transport->close(); return $result; } } $hosts = array('localhost:9090', 'localhost:9091'); $wrapper = new RetryWrapper("\xxx\xx\MessageServiceClient", $hosts, 3); $data = array('businessId' => 300100001, 'phones' => array('2','2','3'), 'message' => 'asdfqer') ; $message = new \xxx\xx\Message($data); print $wrapper->sendMessage($message); print "\n"; ?>
резюме
Вот статья о том, как легко перенести исходный проект в новый сервис с помощью PHP-оболочки. Для получения дополнительной информации о переносе новой службы PHP-оболочки, пожалуйста, найдите предыдущие статьи разработчика или продолжайте просматривать следующие статьи. Я надеюсь, что вы сможете больше поддерживать разработчика в будущем!