php

package
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2026 License: Apache-2.0 Imports: 0 Imported by: 0

README

PHP-биндинги encx

PHP-обёртка над клиентом Encounter из encx. Go-пакет mobile/encxmobile собирается в разделяемую библиотеку (-buildmode=c-shared), а PHP вызывает её через FFI. Клиент живёт на стороне Go, поэтому сессия, куки и HAR-запись сохраняются между вызовами — PHP держит только целочисленный хендл.

Биндинги генерируются из Go-исходника, поэтому не могут от него отстать: см. Синхронизация.

Требования

Что Зачем
PHP 8.1+ с расширением ffi загрузка библиотеки и вызовы
Go (версия из go.mod) сборка библиотеки и генерация
Компилятор C (clang/gcc) и CGO_ENABLED=1 cgo-сборка c-shared

Composer не нужен: рядом лежит autoload.php. composer.json есть для тех, кто подключает биндинги как пакет.

Проверить, что FFI доступен:

php -r 'var_dump(extension_loaded("ffi"));'

Сборка

bash bindings/php/build.sh

Скрипт кладёт libencx.dylib (macOS), libencx.so (Linux) или encx.dll (Windows) в bindings/php/lib/. Каталог не версионируется — библиотеку собирают локально или в CI.

Использование

<?php

require __DIR__ . '/bindings/php/autoload.php';

$client = Encx\Client::newClient('demo.en.cx', false);

$login = json_decode($client->login('user', 'password'), true);
if ($login['Error'] !== 0) {
    throw new RuntimeException(Encx\Helpers::loginErrorText($login['Error']));
}

$model = json_decode($client->getGameModel(82448), true);
echo $model['GameTitle'], "\n";

$client->close();

Для домена без TLS (например локальный encx-mock) используйте расширенную фабрику:

$client = Encx\Client::newClientWithOptions('127.0.0.1:18080', false, true, 10, 'ru');

Аргументы: домен, insecureTLS, useHTTP, таймаут в секундах, язык.

Как читать сигнатуры

Имена методов — это Go-имена в lowerCamelCase: GetGameModelgetGameModel, APIBaseURLapiBaseURL, ExportHARexportHAR. Отображение типов:

Go PHP
string string
int64 int
bool bool
[]byte string (бинарная строка; base64 разбирается за вас)
(T, error) T, а ошибка бросается как Encx\EncxException
error void, ошибка бросается
*HARSnapshot array

Методы, возвращающие JSON (login, getGameModel, getProfile, …), отдают строку — разбирайте её json_decode, как это делают Swift/Kotlin с теми же биндингами.

Время жизни клиента

Каждый Client владеет одним хендлом Go-клиента. Вызывайте close(), когда закончили; деструктор делает то же для клиента, переживившего последнее использование. Повторный close() безвреден, а обращение к закрытому клиенту бросает EncxException.

Что связано, а что нет

Связано 49 символов: 2 фабрики, методы *EncClient (игра, коды, команды, профиль, куки, HAR) и 5 статических функций в Encx\Helpers. Полный машиночитаемый список — в bindings.manifest.json.

Не связано 20 символов, и манифест хранит причину для каждого:

  • IsAntiSpamError, AntiSpamURLFromError, IsUndecodableAcceptedError — принимают error. Go-ошибка это интерфейсное значение, у него нет представления в C ABI. Из PHP та же информация доступна через текст сообщения EncxException.
  • EncClient.NewAgentSession, StartCodexDeviceLogin и методы AgentSession и CodexDeviceLogin — это отдельные объекты с внутренним состоянием (мьютексы, провайдеры, делегаты). Реестр хендлов сейчас держит только *EncClient, поэтому агентская часть API остаётся вне биндингов.

Список не поддерживается вручную: он вычисляется из исходника при каждой генерации.

Синхронизация

Из Go-исходника генерируются пять файлов:

Файл Что это
cshared/exports_gen.go cgo-обёртки с //export
encx.h C-заголовок, который читает FFI::cdef
bindings.manifest.json снимок поверхности: связанное и пропущенное с причинами
src/Encx/Client.php класс клиента
src/Encx/Helpers.php пакетные функции

Правки в них не переживут следующую генерацию — каждый помечен DO NOT EDIT. Рукописны только src/Encx/Ffi.php, src/Encx/EncxException.php, cshared/runtime.go и autoload.php: они реализуют механику вызова, а не поверхность API.

Регенерация:

go generate ./bindings/...

Отставание биндингов от кода ловят четыре независимых механизма:

  1. Кодогенерация. Поверхность не пишется руками, поэтому расходиться нечему: bindings/php/cmd/encxphpgen разбирает AST mobile/encxmobile и печатает все пять файлов.

  2. Go-тест. go test ./bindings/... перегенерирует артефакты в память и падает, называя устаревший файл и первую разошедшуюся строку.

  3. CI. .github/workflows/bindings.yml запускает генерацию и падает при непустом git diff по bindings/, затем собирает библиотеку и гоняет e2e.

  4. Pre-commit hook. Устанавливается один раз:

    bash bindings/php/hooks/install.sh
    

    Хук срабатывает только на коммитах, задевающих mobile/encxmobile/ или bindings/php/, перегенерирует биндинги и блокирует коммит с устаревшими файлами. Индекс он не правит: что попадёт в коммит — решение автора, а не хука.

Быстрая проверка актуальности без записи файлов:

cd bindings/php && go run ./cmd/encxphpgen -out . -check

Тесты

go test ./bindings/... -count=1        # генератор, runtime, drift-детектор
bash bindings/php/tests/run-e2e.sh     # сквозной прогон PHP → FFI → Go → encx-mock

E2E-раннер самодостаточен: он собирает библиотеку, поднимает encx-mock на свободном порту, прогоняет tests/e2e.php и гасит сервер. Тест проверяет в том числе, что сессия переживает вызовы, что ошибка Go приходит исключением, а не null, и что []byte ходит через C ABI в обе стороны.

Добавление другого языка

bindings/ рассчитан на несколько языков. Модель поверхности (bindings/php/internal/surface) не зависит от PHP: она описывает пакет mobile/encxmobile в терминах типов, переносимых через C ABI. Новый язык — это новый эмиттер поверх той же модели плюс свой раздел в манифесте.

Documentation

Overview

Package php holds the PHP bindings for encx: a C-shared library built from mobile/encxmobile and the PHP classes that call it through FFI.

The cgo export file, the C header, the surface manifest and the PHP classes are all generated from the Go source, so they cannot fall behind it. Run `go generate ./bindings/...` after changing mobile/encxmobile.

Directories

Path Synopsis
cmd
encxphpgen command
Command encxphpgen generates the PHP bindings for encx from the Go source of mobile/encxmobile.
Command encxphpgen generates the PHP bindings for encx from the Go source of mobile/encxmobile.
Command cshared is the c-shared library the PHP bindings load through FFI.
Command cshared is the c-shared library the PHP bindings load through FFI.
internal
gen
Package gen emits the C side of the PHP bindings from a surface.Model: the cgo wrapper file compiled into the c-shared library, the FFI-parsable C header, and a JSON manifest describing what was bound and what was not.
Package gen emits the C side of the PHP bindings from a surface.Model: the cgo wrapper file compiled into the c-shared library, the FFI-parsable C header, and a JSON manifest describing what was bound and what was not.
genphp
Package genphp emits the PHP side of the encx bindings: the Client class wrapping the opaque Go handle, and the Helpers class holding the package-level functions that need no client.
Package genphp emits the PHP side of the encx bindings: the Client class wrapping the opaque Go handle, and the Helpers class holding the package-level functions that need no client.
rt
Package rt provides the hand-written runtime shared by the generated PHP cgo bindings: a handle registry for live *encxmobile.EncClient values and a JSON response envelope.
Package rt provides the hand-written runtime shared by the generated PHP cgo bindings: a handle registry for live *encxmobile.EncClient values and a JSON response envelope.
surface
Package surface models the exported surface of the encxmobile Go package as it can be projected onto a C ABI.
Package surface models the exported surface of the encxmobile Go package as it can be projected onto a C ABI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL